From 32352fcc4c087a27daf5e2e96a24a6829ebddda3 Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Mon, 20 Feb 2017 18:41:46 -0500 Subject: [PATCH] added printer support --- .gitignore | 2 + Makefile | 13 +- README.md | 9 +- apple/applevm.cpp | 5 + apple/applevm.h | 2 + apple/fx80-font.h | 2570 +++++++++++++++++++++++++++++++++ apple/fx80.cpp | 259 ++++ apple/fx80.h | 75 + apple/parallelcard.cpp | 50 + apple/parallelcard.h | 32 + apple/slot.cpp | 9 - apple/slot.h | 3 +- globals.cpp | 1 + globals.h | 2 + opencv/aiie.cpp | 12 +- opencv/opencv-filemanager.cpp | 2 +- opencv/opencv-printer.cpp | 75 + opencv/opencv-printer.h | 31 + physicalprinter.h | 13 + teensy/fx80-font.h | 1 + teensy/fx80.cpp | 1 + teensy/fx80.h | 1 + teensy/parallel-rom.h | 1 + teensy/parallelcard.cpp | 1 + teensy/parallelcard.h | 1 + teensy/physicalprinter.h | 1 + teensy/teensy-printer.cpp | 78 + teensy/teensy-printer.h | 25 + util/genrom.pl | 5 +- 29 files changed, 3254 insertions(+), 26 deletions(-) create mode 100644 apple/fx80-font.h create mode 100644 apple/fx80.cpp create mode 100644 apple/fx80.h create mode 100644 apple/parallelcard.cpp create mode 100644 apple/parallelcard.h delete mode 100644 apple/slot.cpp create mode 100644 opencv/opencv-printer.cpp create mode 100644 opencv/opencv-printer.h create mode 100644 physicalprinter.h create mode 120000 teensy/fx80-font.h create mode 120000 teensy/fx80.cpp create mode 120000 teensy/fx80.h create mode 120000 teensy/parallel-rom.h create mode 120000 teensy/parallelcard.cpp create mode 120000 teensy/parallelcard.h create mode 120000 teensy/physicalprinter.h create mode 100644 teensy/teensy-printer.cpp create mode 100644 teensy/teensy-printer.h diff --git a/.gitignore b/.gitignore index a6c3c82..1bb9a6c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ apple2e.rom disk.rom +parallel.rom *~ *.o apple/applemmu-rom.h apple/diskii-rom.h +apple/parallel-rom.h \ No newline at end of file diff --git a/Makefile b/Makefile index e46c245..135bc71 100755 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ LDFLAGS=-L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_features2d -lopencv_calib3d -CXXFLAGS=-Wall -I .. -I . -I apple -O3 +CXXFLAGS=-Wall -I .. -I . -I apple -I opencv -O3 TSRC=cpu.cpp util/testharness.cpp -OPENCVOBJS=cpu.o opencv/dummy-speaker.o opencv/opencv-display.o opencv/opencv-keyboard.o opencv/opencv-paddles.o opencv/opencv-filemanager.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o apple/slot.o RingBuffer.o globals.o opencv/aiie.o +OPENCVOBJS=cpu.o opencv/dummy-speaker.o opencv/opencv-display.o opencv/opencv-keyboard.o opencv/opencv-paddles.o opencv/opencv-filemanager.o apple/appledisplay.o apple/applekeyboard.o apple/applemmu.o apple/applevm.o apple/diskii.o apple/nibutil.o RingBuffer.o globals.o opencv/aiie.o apple/parallelcard.o apple/fx80.o opencv/opencv-printer.o -ROMS=apple/applemmu-rom.h apple/diskii-rom.h +ROMS=apple/applemmu-rom.h apple/diskii-rom.h apple/parallel-rom.h all: opencv @@ -14,17 +14,18 @@ opencv: roms $(OPENCVOBJS) g++ $(LDFLAGS) -o aiie-opencv $(OPENCVOBJS) clean: - rm -f *.o *~ */*.o */*~ testharness.basic testharness.verbose testharness.extended aiie-opencv apple/diskii-rom.h apple/applemmu-rom.h + rm -f *.o *~ */*.o */*~ testharness.basic testharness.verbose testharness.extended aiie-opencv apple/diskii-rom.h apple/applemmu-rom.h apple/parallel-rom.h test: $(TSRC) g++ $(CXXFLAGS) -DBASICTEST $(TSRC) -o testharness.basic g++ $(CXXFLAGS) -DVERBOSETEST $(TSRC) -o testharness.verbose g++ $(CXXFLAGS) -DEXTENDEDTEST $(TSRC) -o testharness.extended -roms: apple2e.rom disk.rom - ./util/genrom.pl apple2e.rom disk.rom +roms: apple2e.rom disk.rom parallel.rom + ./util/genrom.pl apple2e.rom disk.rom parallel.rom apple/applemmu-rom.h: roms apple/diskii-rom.h: roms +apple/parallel-rom.h: roms diff --git a/README.md b/README.md index 38974c6..07bfee5 100644 --- a/README.md +++ b/README.md @@ -26,16 +26,21 @@ As with many emulators, you have to go get the ROMs yourself. I've got the ROMs that I dumped out of my Apple //e. You can probably get yours a lot easier. -There are two files that you'll need: +There are three files that you'll need: * apple2e.rom -- a 32k dump of the entire Apple //e ROM * disk.rom -- a 256 byte dump of the DiskII controller ROM (16-sector P5) +* parallel.rom -- a 256 byte dump of either of the two Apple Parallel cards -The MD5 sums of those two files are: +The MD5 sums of those files are: * 003a780b461c96ae3e72861ed0f4d3d9 apple2e.rom * 2020aa1413ff77fe29353f3ee72dc295 disk.rom +* 5902996f16dc78fc013f6e1db14805b3 parallel.rom +-or- + d666ea749f79a35faa31b4e9a7878eb7 parallel.rom + From those, the appropriate headers will be automatically generated by "make roms" (or any other target that relies on the ROMs). diff --git a/apple/applevm.cpp b/apple/applevm.cpp index 8b3dadd..c752186 100644 --- a/apple/applevm.cpp +++ b/apple/applevm.cpp @@ -19,6 +19,10 @@ AppleVM::AppleVM() ((AppleMMU *)mmu)->setSlot(6, disk6); keyboard = new AppleKeyboard((AppleMMU *)mmu); + + parallel = new ParallelCard(); + ((AppleMMU *)mmu)->setSlot(1, parallel); + #ifdef TEENSYDUINO teensyClock = new TeensyClock((AppleMMU *)mmu); ((AppleMMU *)mmu)->setSlot(7, teensyClock); @@ -51,6 +55,7 @@ void AppleVM::cpuMaintenance(uint32_t cycles) } keyboard->maintainKeyboard(cycles); + parallel->update(); } void AppleVM::Reset() diff --git a/apple/applevm.h b/apple/applevm.h index 514e7ad..4e1fce4 100644 --- a/apple/applevm.h +++ b/apple/applevm.h @@ -5,6 +5,7 @@ #include "appledisplay.h" #include "diskii.h" #include "vmkeyboard.h" +#include "parallelcard.h" #ifdef TEENSYDUINO #include "teensy-clock.h" #endif @@ -32,6 +33,7 @@ class AppleVM : public VM { protected: DiskII *disk6; VMKeyboard *keyboard; + ParallelCard *parallel; #ifdef TEENSYDUINO TeensyClock *teensyClock; #endif diff --git a/apple/fx80-font.h b/apple/fx80-font.h new file mode 100644 index 0000000..08ed889 --- /dev/null +++ b/apple/fx80-font.h @@ -0,0 +1,2570 @@ +#ifndef TEENSYDUINO + #define PROGMEM +#endif + +const uint8_t Fx80Font[4864] ={ + // each character is + // 1 byte of proportional_size; + // 9x2 bytes of horizontal data (b/c each char is 12 bits wide, max) + + // chr(0) + 12, 0x10, 0x00, + 0x08, 0x00, + 0x3F, 0x00, + 0x01, 0x00, + 0x55, 0x00, + 0x81, 0x00, + 0x54, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(1) + 12, 0x10, 0x00, + 0x08, 0x00, + 0x55, 0x00, + 0x80, 0x80, + 0xFF, 0x80, + 0x80, 0x00, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(2) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(3) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(4) [fixme] + 6, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(5) [fixme] + 8, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(6) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(7) [fixme] + 5, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(8) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(9) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(10) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(11) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(12) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(13) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(14) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(15) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(16) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(17) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(18) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(19) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(20) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(21) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(22) [fixme] + 8, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(23) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(24) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(25) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(26) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(27) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(28) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(29) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(30) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(31) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(32) [ ] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(33) [!] + 5, 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(34) ["] + 8, 0x22, 0x00, + 0x22, 0x00, + 0x22, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(35) [#] + 12, 0x22, 0x00, + 0x22, 0x00, + 0xFF, 0x80, + 0x22, 0x00, + 0xFF, 0x80, + 0x22, 0x00, + 0x22, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(36) [$] + 12, 0x08, 0x00, + 0x3F, 0x80, + 0x80, 0x00, + 0x3E, 0x00, + 0x08, 0x80, + 0xFE, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(37) [%] + 12, 0xE1, 0x00, + 0xE2, 0x00, + 0x04, 0x00, + 0x08, 0x00, + 0x10, 0x00, + 0x20, 0x00, + 0x33, 0x80, + 0x43, 0x80, + 0x00, 0x00, + // chr(38) [&] + 12, 0x50, 0x00, + 0x82, 0x00, + 0x55, 0x00, + 0x40, 0x80, + 0x89, 0x00, + 0x82, 0x00, + 0x38, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(39) ['] + 05, 0x04, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(40) [(] + 06, 0x00, 0x80, + 0x01, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x01, 0x00, + 0x00, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(41) [)] + 06, 0x20, 0x00, + 0x10, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x10, 0x00, + 0x20, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(42) [*] + 12, 0x00, 0x00, + 0x22, 0x00, + 0x14, 0x00, + 0xFF, 0x80, + 0x14, 0x00, + 0x22, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(43) [+] + 12, 0x00, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0xFF, 0x80, + 0x08, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(44) [,] + 07, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x14, 0x00, + 0x14, 0x00, + 0x04, 0x00, + 0x08, 0x00, + // chr(45) [-] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0xFF, 0x80, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(46) [.] + 06, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x38, 0x00, + 0x38, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(47) [/] + 10, 0x01, 0x00, + 0x02, 0x00, + 0x04, 0x00, + 0x08, 0x00, + 0x10, 0x00, + 0x20, 0x00, + 0x40, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(48) [0] + 12, 0x14, 0x00, + 0x41, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x41, 0x00, + 0x14, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(49) [1] + 8, 0x08, 0x00, + 0x38, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x3E, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(50) [2] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x00, 0x80, + 0x02, 0x00, + 0x08, 0x00, + 0x20, 0x00, + 0xFF, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(51) [3] + 12, 0xFF, 0x80, + 0x02, 0x00, + 0x08, 0x00, + 0x02, 0x00, + 0x00, 0x80, + 0x80, 0x80, + 0x3E, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(52) [4] + 12, 0x0E, 0x00, + 0x12, 0x00, + 0x22, 0x00, + 0x42, 0x00, + 0xFF, 0x80, + 0x02, 0x00, + 0x02, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(53) [5] + 12, 0xAA, 0x80, + 0x80, 0x00, + 0xAA, 0x00, + 0x00, 0x80, + 0x00, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(54) [6] + 12, 0x08, 0x00, + 0x10, 0x00, + 0x20, 0x00, + 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(55) [7] + 12, 0xFF, 0x80, + 0x01, 0x00, + 0x02, 0x00, + 0x04, 0x00, + 0x08, 0x00, + 0x10, 0x00, + 0x20, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(56) [8] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(57) [9] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x02, 0x00, + 0x04, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(58) [:] + 06, 0x00, 0x00, + 0x00, 0x00, + 0x28, 0x00, + 0x28, 0x00, + 0x00, 0x00, + 0x28, 0x00, + 0x28, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(59) [;] + 06, 0x00, 0x00, + 0x00, 0x00, + 0x28, 0x00, + 0x28, 0x00, + 0x00, 0x00, + 0x28, 0x00, + 0x28, 0x00, + 0x08, 0x00, + 0x20, 0x00, + // chr(60) [<] + 10, 0x02, 0x00, + 0x08, 0x00, + 0x20, 0x00, + 0x80, 0x00, + 0x20, 0x00, + 0x08, 0x00, + 0x02, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(61) [=] + 12, 0x00, 0x00, + 0x00, 0x00, + 0xFF, 0x80, + 0x00, 0x00, + 0xFF, 0x80, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(62) [>] + 10, 0x20, 0x00, + 0x08, 0x00, + 0x02, 0x00, + 0x00, 0x80, + 0x02, 0x00, + 0x08, 0x00, + 0x20, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(63) [?] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x00, 0x80, + 0x02, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(64) [@] + 12, 0x2A, 0x00, + 0x40, 0x80, + 0x8A, 0x80, + 0x94, 0x80, + 0x8A, 0x80, + 0x40, 0x00, + 0x2A, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(65) [A] + 12, 0x14, 0x00, + 0x22, 0x00, + 0x41, 0x00, + 0x80, 0x80, + 0xFF, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(66) [B] + 12, 0xFE, 0x00, + 0x40, 0x80, + 0x40, 0x80, + 0x55, 0x00, + 0x40, 0x80, + 0x40, 0x80, + 0xFE, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(67) [C] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(68) [D] + 12, 0xFE, 0x00, + 0x41, 0x00, + 0x40, 0x80, + 0x40, 0x80, + 0x40, 0x80, + 0x41, 0x00, + 0xFE, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(69) [E] + 12, 0xFF, 0x80, + 0x80, 0x00, + 0x80, 0x00, + 0xFE, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0xFF, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(70) [F] + 12, 0xFF, 0x80, + 0x80, 0x00, + 0x80, 0x00, + 0xFE, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(71) [G] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x00, + 0x8A, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(72) [H] + 12, 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0xFF, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(73) [I] + 8, 0x3F, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x3F, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(74) [J] + 11, 0x15, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x82, 0x00, + 0x82, 0x00, + 0x54, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(75) [K] + 12, 0x80, 0x80, + 0x82, 0x00, + 0x88, 0x00, + 0xA0, 0x00, + 0x88, 0x00, + 0x82, 0x00, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(76) [L] + 12, 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0xFF, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(77) [M] + 12, 0x80, 0x80, + 0xA2, 0x80, + 0x94, 0x80, + 0x88, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(78) [N] + 12, 0x80, 0x80, + 0xE0, 0x80, + 0x90, 0x80, + 0x88, 0x80, + 0x84, 0x80, + 0x83, 0x80, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(79) [O] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(80) [P] + 12, 0xFE, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0xFE, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(81) [Q] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x88, 0x80, + 0x82, 0x00, + 0x54, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(82) [R] + 12, 0xFE, 0x00, + 0x80, 0x80, + 0x80, 0x80, + 0xFE, 0x00, + 0x82, 0x00, + 0x81, 0x00, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(83) [S] + 12, 0x55, 0x00, + 0x80, 0x80, + 0x80, 0x00, + 0x55, 0x00, + 0x00, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(84) [T] + 12, 0xFF, 0x80, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(85) [U] + 12, 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(86) [V] + 12, 0x80, 0x80, + 0x80, 0x80, + 0x80, 0x80, + 0x41, 0x00, + 0x22, 0x00, + 0x14, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(87) [W] + 12, 0x80, 0x80, + 0x80, 0x80, + 0x88, 0x80, + 0x88, 0x80, + 0x94, 0x80, + 0xE3, 0x80, + 0x41, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(88) [X] + 10, 0x41, 0x00, + 0x22, 0x00, + 0x14, 0x00, + 0x08, 0x00, + 0x14, 0x00, + 0x22, 0x00, + 0x41, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(89) [Y] + 12, 0x80, 0x80, + 0x41, 0x00, + 0x22, 0x00, + 0x14, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(90) [Z] + 10, 0x55, 0x00, + 0x02, 0x00, + 0x04, 0x00, + 0x08, 0x00, + 0x10, 0x00, + 0x20, 0x00, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(91) '[' + 8 /* 'a' typo? */, 0x3E, 0x00, + 0x20, 0x00, + 0x20, 0x00, + 0x20, 0x00, + 0x20, 0x00, + 0x20, 0x00, + 0x3E, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(92) [\] + 10, 0x40, 0x00, + 0x20, 0x00, + 0x10, 0x00, + 0x08, 0x00, + 0x04, 0x00, + 0x02, 0x00, + 0x01, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(93) ']' + 8 /* 'a' typo? */, 0x3E, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x02, 0x00, + 0x3E, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(94) [^] + 12, 0x80, 0x00, + 0x22, 0x00, + 0x80, 0x80, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(95) [_] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0xFF, 0x80, + // chr(96) [`] + 05, 0x10, 0x00, + 0x08, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(97) [a] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x2A, 0x00, + 0x01, 0x00, + 0x55, 0x00, + 0x81, 0x00, + 0x54, 0x80, + 0x00, 0x00, + 0x00, 0x00, + // chr(98) [b] + 11, 0x80, 0x00, + 0x80, 0x00, + 0xFE, 0x00, + 0x81, 0x00, + 0x81, 0x00, + 0x81, 0x00, + 0xFE, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(99) [c] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x55, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x80, 0x00, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(100) [d] + 11, 0x01, 0x00, + 0x01, 0x00, + 0x55, 0x00, + 0x81, 0x00, + 0x81, 0x00, + 0x81, 0x00, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(101) [e] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x55, 0x00, + 0x80, 0x80, + 0xFE, 0x00, + 0x80, 0x00, + 0x55, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(102) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(103) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(104) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(105) [fixme] + 8 /* 'a' typo? */, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(106) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(107) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(108) [fixme] + 8 /* 'a' typo? */, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(109) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(110) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(111) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(112) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(113) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(114) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(115) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(116) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(117) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(118) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(119) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(120) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(121) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(122) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(123) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(124) [fixme] + 05, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(125) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(126) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(127) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(128) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(129) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(130) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(131) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(132) [fixme] + 8, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(133) [fixme] + 8, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(134) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(135) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(136) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(137) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(138) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(139) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(140) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(141) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(142) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(143) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(144) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(145) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(146) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(147) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(148) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(149) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(150) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(151) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(152) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(153) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(154) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(155) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(156) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(157) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(158) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(159) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(160) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(161) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(162) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(163) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(164) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(165) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(166) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(167) [fixme] + 05, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(168) [fixme] + 8 /* 'a' typo? */, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(169) [fixme] + 8 /* 'a' typo? */, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(170) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(171) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(172) [fixme] + 8 /* 'a' typo? */, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(173) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(174) [fixme] + 07, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(175) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(176) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(177) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(178) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(179) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(180) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(181) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(182) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(183) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(184) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(185) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(186) [fixme] + 8, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(187) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(188) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(189) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(190) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(191) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(192) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(193) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(194) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(195) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(196) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(197) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(198) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(199) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(200) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(201) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(202) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(203) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(204) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(205) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(206) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(207) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(208) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(209) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(210) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(211) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(212) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(213) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(214) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(215) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(216) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(217) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(218) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(219) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(220) [fixme] + 07, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(221) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(222) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(223) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(224) [fixme] + 05, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(225) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(226) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(227) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(228) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(229) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(230) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(231) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(232) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(233) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(234) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(235) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(236) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(237) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(238) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(239) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(240) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(241) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(242) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(243) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(244) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(245) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(246) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(247) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(248) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(249) [fixme] + 11, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(250) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(251) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(252) [fixme] + 9, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(253) [fixme] + 10, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(254) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + // chr(255) [fixme] + 12, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00 +}; diff --git a/apple/fx80.cpp b/apple/fx80.cpp new file mode 100644 index 0000000..c33bc11 --- /dev/null +++ b/apple/fx80.cpp @@ -0,0 +1,259 @@ +#include // memset +#include +#include // while debugging + +#include "fx80.h" +#include "fx80-font.h" + +#include "globals.h" + +Fx80::Fx80() +{ + clearLine(); + escapeMode = false; + proportionalMode = false; + carriageDot = 0; + twoSixteenthsLineSpacing = 36; // 1/6" line spacing is the default (12 pixels) + graphicsWidth = 960; + ninePinGraphics = false; + escapeModeActive = 0; + escapeModeExpectingBytes = -1; + escapeModeLengthByteCount = 0; + escapeModeLength = 0; +} + +Fx80::~Fx80() +{ +} + +void Fx80::handleEscape(uint8_t c) +{ + switch (c & 0x7F) { + case 75: // FIXME: single-density 480 dpi graphics line + graphicsWidth = 480; + break; + case 76: // FIXME: low-speed double-density graphics line + case 89: // FIXME: high-speed double-density graphics + graphicsWidth = 960; + escapeModeActive = c; + escapeModeExpectingBytes = -1; + escapeModeLengthByteCount = 0; + break; + case 90: // FIXME: quadruple-density graphics + graphicsWidth = 960 * 2; + break; + case 94: // FIXME: enable 9-pin graphics + escapeModeActive = c; + escapeModeExpectingBytes = -1; + escapeModeLengthByteCount = 0; + break; + case 65: // set line spacing + escapeModeActive = c; + escapeModeExpectingBytes = 1; + break; + case 33: // FIXME: mode select + case 35: // FIXME: enable 8-bit reception from computer + case 37: // FIXME: pick charset from ROM + case 38: // FIXME: define chars in RAM + case 42: // FIXME: set vertical tabs + case 43: // FIXME: set form length (default: 66 lines, 11 inches) + case 68: // FIXME: reset current tabs, pitch + case 69: // FIXME: emphasized mode on + case 70: // FIXME: emphasized mode off + case 71: // FIXME: double-strike on + case 72: // FIXME: double-strike off + case 73: // FIXME: enable printing chr[0..31] except control codes + case 74: // FIXME: line feed immediately, n/216th of an inch + case 77: // FIXME: elite mode (12cpi) + case 78: // FIXME: turn on skip-over perforation + case 79: // FIXME: turn off skip-over perforation + case 80: // FIXME: disable elite; enable pica mode (unless compressed is enabled) + case 81: // FIXME: cancel print buffer, set right margin + case 82: // FIXME: select international charset + case 83: // FIXME: script mode on + case 84: // FIXME: script mode off + case 85: // FIXME: unidirecitonal mode on/off + case 87: // FIXME: expanded mode + case 98: // FIXME: set vertical tab + case 105: // FIXME: immediate mode on + case 106: // FIXME: immediate reverse linefeed 1/216" + case 108: // FIXME: set left margin + case 112: // FIXME: turn on proportional mode + case 115: // FIXME: print speed + printf("unhandled escape code %d\n", c); + break; + + } +} + +void Fx80::handleActiveEscapeMode(uint8_t c) +{ + switch (escapeModeActive) { + case 76: + case 89: + // one column of double-density graphics + { + // FIXME: abstract this - second time it's being used + uint16_t byteIdx = (carriageDot+0) / 8 + (FX80_MAXWIDTH/8) * 0; + uint8_t bitIdx = (carriageDot+0) % 8; + for (int i=0; i<8; i++) { + if (c & (1 << (7-i))) { + rowOfBits[byteIdx] |= (1 << (7-bitIdx)); + } + byteIdx += (FX80_MAXWIDTH/8); + } + } + carriageDot++; + break; + case 65: // set line spacing to n/72ths of an inch (n=0-85) + twoSixteenthsLineSpacing = 3 * c; + + break; + default: + printf("unhandled active escape mode %d\n", c); + break; + } +} + +void Fx80::input(uint8_t c) +{ + if (escapeMode) { + handleEscape(c); + escapeMode = false; + return; + } + + // Is this an escape mode that gets a fixed amount of input? + if (escapeModeActive) { + if (escapeModeExpectingBytes < 0) { + // We're reading 2 bytes of length + escapeModeLengthByteCount++; + if (escapeModeLengthByteCount == 1) { + escapeModeLength = c; + } else { + escapeModeLength |= (c << 8); + escapeModeExpectingBytes = escapeModeLength; + } + return; + } else { + escapeModeExpectingBytes--; + } + + handleActiveEscapeMode(c); + if (escapeModeExpectingBytes == 0) { + escapeModeActive = 0; + } + return; + } + + if (c == 27) { + escapeMode = true; + return; + } + + // FIXME: all these also work as 128 + c + switch (c & 0x7F) { + case 0: // FIXME: terminate horiz/vert tab setting + return; + case 7: // beep + return; + case 8: // FIXME: "at current width" instead of this fixed-12 + if (carriageDot >= 12) + carriageDot -= 12; + return; + case 9: // FIXME: HTAB + return; + case 10: + lineFeed(); + return; + case 11: // FIXME: VTAB + return; + case 12: // FIXME: Form Feed + lineFeed(); + return; + case 13: + carriageDot = 0; + // lineFeed(); // FIXME: this was controlled by a switch + return; + case 14: // FIXME: Shift Out - turns on "Expanded Mode" + case 15: // FIXME: Shift In - turns on "Compressed Mode" + case 17: // FIXME: DC1 + case 18: // FIXME: DC2 + case 19: // FIXME: DC3 + case 20: // FIXME: DC4 + case 24: // FIXME: cancel text in print buffer; not the same as "clear line" + case 127: // FIXME: delete last char in the print buffer + return; + + } + + // normal print - send the character verbatim... + addCharacter(c & 0x7F); // FIXME: masking high bit +} + +// add the given character on the line at the current carriage dot position +void Fx80::addCharacter(uint8_t c) +{ + uint8_t width = Fx80Font[c * 19]; + // FIXME: is 12 right for non-proportional mode? + if (!proportionalMode) + width = 12; + + // Each row for this char has two bytes of bits, left-to-right, high + // bit leftmost. + + const uint8_t *charPtr = &Fx80Font[c * 19]; + charPtr++; + + for (uint8_t row=0; row<9; row++) { + // Don't print beyond end of line! + + for (uint8_t xoff = 0; xoff < 8; xoff++) { + + if (carriageDot+xoff >= FX80_MAXWIDTH) + continue; + + uint16_t byteIdx = (carriageDot+xoff) / 8 + (FX80_MAXWIDTH/8) * row; + uint8_t bitIdx = (carriageDot+xoff) % 8; + + // We never clear bits - it's possible to overstrike, so just add more... + if (charPtr[2*row] & (1 << (7-xoff))) { + rowOfBits[byteIdx] |= (1 << (7-bitIdx)); + } + if (charPtr[2*row+1] & (1 << (7-xoff))) { + rowOfBits[byteIdx+1] |= (1 << (7-bitIdx)); + } + } + } + + carriageDot += 12; // FIXME +} + +void Fx80::lineFeed() +{ + emitLine(); + g_printer->moveDownPixels(twoSixteenthsLineSpacing / 3); // pixel estimation + clearLine(); +} + +void Fx80::clearLine() +{ + memset(rowOfBits, 0, sizeof(rowOfBits)); +} + +void Fx80::emitLine() +{ + // FIXME: this is very wrong. Doesn't deal with line advance + // properly. But it's good enough for debugging basic operation. + g_printer->addLine(rowOfBits); +} + +void Fx80::update() +{ + // The onscreen window needs to update regularly, and we probably + // want to periodically flush the Teensy buffer. + if (g_printer) { + g_printer->update(); + } +} + diff --git a/apple/fx80.h b/apple/fx80.h new file mode 100644 index 0000000..5a984cf --- /dev/null +++ b/apple/fx80.h @@ -0,0 +1,75 @@ +#ifndef __FX80_H +#define __FX80_H + +#include + +/* maximum width, in dots, that we're supporting. The FX80 supported + * up to 1920 ("quadruple density") -- which I'm not, b/c that's + * overkill for what I'm doing at the moment. I'm supporting "double density" + * (960 dots per 8-inch line). + * + * My general strategy here is to fill up a line with bits until the + * printer thinks it needs to move to the next line; and then do + * something with the bits (send them to a printer, a screen, a file, + * whatever). This gets both graphics and text modes in one swell foop. + * + * There is the troublesome "9-pin graphics mode" where each column of + * bits is > 1 byte of data; for that, we keep an extra "rowOfPin9" + * bits, which is just a bit stream across the width. It would be + * easier to make rowOfBits be uint16_t but it would consume more RAM, + * and I'm trying to minimize that as I'm down to about 13k of free + * space in the Teensy! + */ + +#define FX80_MAXWIDTH 960 + +#ifdef TEENSYDUINO +class TeensyPrinter; +#else +class OpenCVPrinter; +#endif + +class Fx80 { + public: + Fx80(); + ~Fx80(); + + void input(uint8_t c); + + void update(); + + private: + void lineFeed(); + void clearLine(); + + void addCharacter(uint8_t c); + + void handleEscape(uint8_t c); + void handleActiveEscapeMode(uint8_t c); + void emitLine(); + + protected: + bool escapeMode; + bool proportionalMode; + + uint16_t carriageDot; // what dot-column we are at + + // Line spacing. 1/216th of an inch is 1/3 of a dot, which is the minimum + // supported by the FX-80. This is usually set in terms of 72nds, and + // it's unlikely that I'll render anything at 1/216, but might as + // well interpret it the way the printer understands it. + // (That means 8/72, which is a setting of 24 here, is 8 dots tall.) + uint16_t twoSixteenthsLineSpacing; + + uint16_t graphicsWidth; + bool ninePinGraphics; + uint8_t escapeModeActive; + int32_t escapeModeExpectingBytes; + uint8_t escapeModeLengthByteCount; + uint16_t escapeModeLength; + + // 9 pixel-rows of (FX80_MAXWIDTH) bits (stuffed in 8-bit bytes) + uint8_t rowOfBits[(FX80_MAXWIDTH/8)*9]; +}; + +#endif diff --git a/apple/parallelcard.cpp b/apple/parallelcard.cpp new file mode 100644 index 0000000..670d100 --- /dev/null +++ b/apple/parallelcard.cpp @@ -0,0 +1,50 @@ +#include "parallelcard.h" +#include + +#include "parallel-rom.h" +#include "fx80.h" + +ParallelCard::ParallelCard() +{ + fx80 = new Fx80(); +} + +ParallelCard::~ParallelCard() +{ +} + +void ParallelCard::Reset() +{ +} + +uint8_t ParallelCard::readSwitches(uint8_t s) +{ + return 0xFF; +} + +void ParallelCard::writeSwitches(uint8_t s, uint8_t v) +{ + if (s == 0x00) { + fx80->input(v); + } else { + // printf("unknown switch 0x%X\n", s); + } +} + +void ParallelCard::loadROM(uint8_t *toWhere) +{ +#ifdef TEENSYDUINO + Serial.println("loading parallel slot rom"); + for (uint16_t i=0; i<=0xFF; i++) { + toWhere[i] = pgm_read_byte(&romData[i]); + } +#else + printf("loading parallel slot rom\n"); + memcpy(toWhere, romData, 256); +#endif +} + +void ParallelCard::update() +{ + fx80->update(); +} diff --git a/apple/parallelcard.h b/apple/parallelcard.h new file mode 100644 index 0000000..938baf7 --- /dev/null +++ b/apple/parallelcard.h @@ -0,0 +1,32 @@ +#ifndef __PARALLELCARD_H +#define __PARALLELCARD_H + +#ifdef TEENSYDUINO +#include +#else +#include +#include +#endif + +#include "applemmu.h" +#include "slot.h" + +class Fx80; + +class ParallelCard : public Slot { + public: + ParallelCard(); + virtual ~ParallelCard(); + + virtual void Reset(); // used by BIOS cold-boot + virtual uint8_t readSwitches(uint8_t s); + virtual void writeSwitches(uint8_t s, uint8_t v); + virtual void loadROM(uint8_t *toWhere); + + void update(); + + private: + Fx80 *fx80; +}; + +#endif diff --git a/apple/slot.cpp b/apple/slot.cpp deleted file mode 100644 index 3a80a18..0000000 --- a/apple/slot.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "slot.h" - -Slot::Slot() -{ -} - -Slot::~Slot() -{ -} diff --git a/apple/slot.h b/apple/slot.h index 7dbeb87..792570f 100644 --- a/apple/slot.h +++ b/apple/slot.h @@ -11,8 +11,7 @@ class Slot { public: - Slot(); - ~Slot(); + virtual ~Slot() {}; virtual void Reset() = 0; // for use at cold-boot diff --git a/globals.cpp b/globals.cpp index 4f301fe..56a38ae 100644 --- a/globals.cpp +++ b/globals.cpp @@ -7,5 +7,6 @@ PhysicalDisplay *g_display = NULL; PhysicalKeyboard *g_keyboard = NULL; PhysicalSpeaker *g_speaker = NULL; PhysicalPaddles *g_paddles = NULL; +PhysicalPrinter *g_printer = NULL; int16_t g_volume; uint8_t g_displayType = 3; // FIXME m_perfectcolor diff --git a/globals.h b/globals.h index bd5092b..c3b873e 100644 --- a/globals.h +++ b/globals.h @@ -7,6 +7,7 @@ #include "physicalkeyboard.h" #include "physicalspeaker.h" #include "physicalpaddles.h" +#include "physicalprinter.h" extern FileManager *g_filemanager; extern Cpu *g_cpu; @@ -15,5 +16,6 @@ extern PhysicalDisplay *g_display; extern PhysicalKeyboard *g_keyboard; extern PhysicalSpeaker *g_speaker; extern PhysicalPaddles *g_paddles; +extern PhysicalPrinter *g_printer; extern int16_t g_volume; extern uint8_t g_displayType; diff --git a/opencv/aiie.cpp b/opencv/aiie.cpp index d1ac29c..6acb607 100644 --- a/opencv/aiie.cpp +++ b/opencv/aiie.cpp @@ -12,6 +12,7 @@ #include "dummy-speaker.h" #include "opencv-paddles.h" #include "opencv-filemanager.h" +#include "opencv-printer.h" #include "globals.h" @@ -247,14 +248,14 @@ static void *cpu_thread(void *dummyptr) { #endif if (send_rst) { -#if 0 +#if 1 printf("Sending reset\n"); - // g_cpu->Reset(); + g_cpu->Reset(); // testing startup keyboard presses - perform Apple //e self-test - g_vm->getKeyboard()->keyDepressed(RA); - g_vm->Reset(); - g_cpu->Reset(); + //g_vm->getKeyboard()->keyDepressed(RA); + //g_vm->Reset(); + //g_cpu->Reset(); //((AppleVM *)g_vm)->insertDisk(0, "disks/DIAGS.DSK"); #else @@ -293,6 +294,7 @@ static void *cpu_thread(void *dummyptr) { int main(int argc, char *argv[]) { g_speaker = new DummySpeaker(); + g_printer = new OpenCVPrinter(); // create the filemanager - the interface to the host file system. g_filemanager = new OpenCVFileManager(); diff --git a/opencv/opencv-filemanager.cpp b/opencv/opencv-filemanager.cpp index c10e539..c966551 100644 --- a/opencv/opencv-filemanager.cpp +++ b/opencv/opencv-filemanager.cpp @@ -61,7 +61,7 @@ const char *OpenCVFileManager::fileName(int8_t fd) return cachedNames[fd]; } -int8_t OpenCVFileManager::readDir(const char *where, const char *suffix, char *outputFN, int8_t startIdx, uint8_t maxlen) +int8_t OpenCVFileManager::readDir(const char *where, const char *suffix, char *outputFN, int8_t startIdx, uint16_t maxlen) { // not used in this version return -1; diff --git a/opencv/opencv-printer.cpp b/opencv/opencv-printer.cpp new file mode 100644 index 0000000..c064992 --- /dev/null +++ b/opencv/opencv-printer.cpp @@ -0,0 +1,75 @@ +#include "opencv-printer.h" + +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/calib3d/calib3d.hpp" +#include "opencv2/features2d/features2d.hpp" + +using namespace cv; +using namespace std; + +#define WINDOWNAME "printer" + +#define HEIGHT 800 +#define NATIVEWIDTH 960 // FIXME: printer can change density... + + +//#define WIDTH 384 // emulating the teeny printer I've got +#define WIDTH 960 + +OpenCVPrinter::OpenCVPrinter() +{ + pixels = new Mat(HEIGHT, WIDTH, CV_8U); + *pixels = cv::Scalar(0xFF); + ypos = 0; + isDirty = false; + namedWindow(WINDOWNAME, CV_WINDOW_AUTOSIZE); +} + +OpenCVPrinter::~OpenCVPrinter() +{ + delete pixels; pixels = NULL; +} + +void OpenCVPrinter::update() +{ + if (isDirty) { + imshow(WINDOWNAME, *pixels); + isDirty = false; + } +} + +void OpenCVPrinter::addLine(uint8_t *rowOfBits) +{ + isDirty = true; + for (int yoff=0; yoff<8; yoff++) { + // 960 pixels == 120 bytes -- FIXME + for (int i=0; i<(NATIVEWIDTH/8); i++) { + uint8_t bv = rowOfBits[yoff*120+i]; + for (int xoff=0; xoff<8; xoff++) { + // scale X from "actual FX80" coordinates to "real printer" coordinates + uint16_t actualX = (uint16_t)(((float)(i*8+xoff) * (float)WIDTH) / (float)NATIVEWIDTH); + + uint8_t oldPixel = pixels->at((ypos + yoff)%HEIGHT, actualX); + uint8_t pixelColor = (bv & (1 << (7-xoff))) ? 0x00 : 0xFF; + // Make sure to preserve any pixels we've already drawn + pixels->at((ypos + yoff)%HEIGHT, actualX) = ~(~oldPixel | ~pixelColor); + } + } + } + + if (ypos >= HEIGHT) { + ypos = 0; + } +} + +void OpenCVPrinter::moveDownPixels(uint8_t p) +{ + ypos+= p; + if (ypos >= HEIGHT) { + // clear page & restart + *pixels = cv::Scalar(0xFF); + ypos = 0; + } +} diff --git a/opencv/opencv-printer.h b/opencv/opencv-printer.h new file mode 100644 index 0000000..cbf1d70 --- /dev/null +++ b/opencv/opencv-printer.h @@ -0,0 +1,31 @@ +#ifndef __OPENCV_PRINTER_H +#define __OPENCV_PRINTER_H + +#include + +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/calib3d/calib3d.hpp" +#include "opencv2/features2d/features2d.hpp" + +#include "physicalprinter.h" + +class OpenCVPrinter : public PhysicalPrinter { + public: + OpenCVPrinter(); + virtual ~OpenCVPrinter(); + + virtual void addLine(uint8_t *rowOfBits); // must be 960 pixels wide (120 bytes) + + virtual void update(); + + virtual void moveDownPixels(uint8_t p); + + private: + bool isDirty; + uint16_t ypos; + cv::Mat *pixels; +}; + +#endif diff --git a/physicalprinter.h b/physicalprinter.h new file mode 100644 index 0000000..c907c91 --- /dev/null +++ b/physicalprinter.h @@ -0,0 +1,13 @@ +#ifndef __PHYSICALPRINTER_H +#define __PHYSICALPRINTER_H + +class PhysicalPrinter { + public: + virtual ~PhysicalPrinter() {} + // must be 960 pixels wide (120 bytes) + virtual void addLine(uint8_t *rowOfBits) = 0; + virtual void update() = 0; + virtual void moveDownPixels(uint8_t p) = 0; +}; + +#endif diff --git a/teensy/fx80-font.h b/teensy/fx80-font.h new file mode 120000 index 0000000..ae4b358 --- /dev/null +++ b/teensy/fx80-font.h @@ -0,0 +1 @@ +../apple/fx80-font.h \ No newline at end of file diff --git a/teensy/fx80.cpp b/teensy/fx80.cpp new file mode 120000 index 0000000..21158aa --- /dev/null +++ b/teensy/fx80.cpp @@ -0,0 +1 @@ +../apple/fx80.cpp \ No newline at end of file diff --git a/teensy/fx80.h b/teensy/fx80.h new file mode 120000 index 0000000..8ea3bfd --- /dev/null +++ b/teensy/fx80.h @@ -0,0 +1 @@ +../apple/fx80.h \ No newline at end of file diff --git a/teensy/parallel-rom.h b/teensy/parallel-rom.h new file mode 120000 index 0000000..12a187c --- /dev/null +++ b/teensy/parallel-rom.h @@ -0,0 +1 @@ +../apple/parallel-rom.h \ No newline at end of file diff --git a/teensy/parallelcard.cpp b/teensy/parallelcard.cpp new file mode 120000 index 0000000..202b81e --- /dev/null +++ b/teensy/parallelcard.cpp @@ -0,0 +1 @@ +../apple/parallelcard.cpp \ No newline at end of file diff --git a/teensy/parallelcard.h b/teensy/parallelcard.h new file mode 120000 index 0000000..b5de523 --- /dev/null +++ b/teensy/parallelcard.h @@ -0,0 +1 @@ +../apple/parallelcard.h \ No newline at end of file diff --git a/teensy/physicalprinter.h b/teensy/physicalprinter.h new file mode 120000 index 0000000..205d087 --- /dev/null +++ b/teensy/physicalprinter.h @@ -0,0 +1 @@ +../physicalprinter.h \ No newline at end of file diff --git a/teensy/teensy-printer.cpp b/teensy/teensy-printer.cpp new file mode 100644 index 0000000..a2ce4e5 --- /dev/null +++ b/teensy/teensy-printer.cpp @@ -0,0 +1,78 @@ +#include +#include "teensy-printer.h" + +#define WIDTH (384) // width of printer, in dots +#define NATIVEWIDTH 960 // + +#define RXPIN 57 +#define TXPIN 56 + +TeensyPrinter::TeensyPrinter() +{ + ser = new SoftwareSerial(RXPIN, TXPIN, false); + ser->begin(19200); + char buf[6] = { 27, '@', // init command '@' + 27, '3', 8, // ESC-3 is "set line spacing"; default 30 + 0 // terminator + }; + ser->print(buf); +} + +TeensyPrinter::~TeensyPrinter() +{ + delete ser; +} + +void TeensyPrinter::update() +{ +} + +void TeensyPrinter::addLine(uint8_t *rowOfBits) +{ + static uint8_t linebuf[WIDTH/8]; // output data for one line of pixels + + // The rowOfBits is a set of *rows* of bits. The printer needs *columns*. + // Convert and send as necessary. + + // Send bitmap command, followed by bitmap data, followed by linefeed? + // ser->write(27); // set line spacing + // ser->write('3'); + // ser->write((uint8_t)30); + +#define DC2 18 + + // FIXME: is this 0-6, or 1-7? One of them is empty.. + // FIXME: also read this off of the print head size/line feed size? + for (int yoff=1; yoff<8; yoff++) { + memset(linebuf, 0, sizeof(linebuf)); // start clear... + for (int i=0; i<(NATIVEWIDTH/8); i++) { + uint8_t bv = rowOfBits[yoff*120+i]; + // Process the 8 bits in this byte + for (int xoff=0; xoff<8; xoff++) { + // scale X from "actual FX80" coordinates to "real printer" coordinates + uint16_t actualX = (uint16_t)(((float)(i*8+xoff) * (float)WIDTH) / (float)NATIVEWIDTH); + + if (bv & (1 << (7-xoff))) { // if it's on in the original + // then turn it on in our copy + uint8_t bitNum = actualX & 0x07; + linebuf[actualX>>3] |= (1<<(7-bitNum)); + } + } + } + + // Send this line to the printer + ser->write(DC2); // send this line as a bitmap + ser->write('*'); + ser->write(1); // FIXME: height + ser->write(48); // FIXME: width, in bytes + for (int i=0; iwrite(linebuf[i]); + } + } + + // ser->write(10); // linefeed @ the end +} + +void TeensyPrinter::moveDownPixels(uint8_t p) +{ +} diff --git a/teensy/teensy-printer.h b/teensy/teensy-printer.h new file mode 100644 index 0000000..f4ba173 --- /dev/null +++ b/teensy/teensy-printer.h @@ -0,0 +1,25 @@ +#ifndef __TEENSY_PRINTER_H +#define __TEENSY_PRINTER_H + +#include +#include + +#include "physicalprinter.h" + +class TeensyPrinter : public PhysicalPrinter { + public: + TeensyPrinter(); + virtual ~TeensyPrinter(); + + virtual void addLine(uint8_t *rowOfBits); // must be 960 pixels wide (120 bytes) + + virtual void update(); + + virtual void moveDownPixels(uint8_t p); + + private: + uint16_t ypos; + SoftwareSerial *ser; +}; + +#endif diff --git a/util/genrom.pl b/util/genrom.pl index 0bda7cb..c6cc27b 100755 --- a/util/genrom.pl +++ b/util/genrom.pl @@ -5,12 +5,15 @@ use warnings; my $romfile = shift || die "Must provide the path to an Apple //e ROM image"; my $diskrom = shift || die "Must also provide the path to an Apple //e Disk II ROM image"; +my $parallelrom = shift || die "Must also provide the path to an Apple // parallel card ROM image"; validate($romfile, 32768, "an Apple //e ROM image"); validate($diskrom, 256, "a DiskII ROM image"); +validate($parallelrom, 256, "a parallel card ROM image"); dumpRom($romfile, "apple/applemmu-rom.h", "romData", 32768); dumpRom($diskrom, "apple/diskii-rom.h", "romData", 256); +dumpRom($parallelrom, "apple/parallel-rom.h", "romData", 256); exit 0; sub validate { @@ -38,7 +41,7 @@ sub dumpRom { #endif static - uint8_t romData[32768] PROGMEM = { + uint8_t romData[$datasize] PROGMEM = { EOF ;