]> Shamusworld >> Repos - apple2/commitdiff
Misc. improvements, added WOZ file support to floppy emulation
authorShamus Hammons <jlhamm@acm.org>
Thu, 24 Jan 2019 02:33:05 +0000 (20:33 -0600)
committerShamus Hammons <jlhamm@acm.org>
Thu, 24 Jan 2019 02:33:05 +0000 (20:33 -0600)
- Refactored old MMU slot code to be more flexible
- Moved all Mockingboard related code to its own compilation unit
- Refactored old 6522 & AY-3-8910 code into v6522VIA & vAY8910  :-)
- Fixed BCD mode for ADC and SBC in v65C02
- Finally fixed text mode characters in both ALTCHARSET and regular
  modes
- Added new floppy disk controller Logic State Sequencer emulation
- Fixed v65C02 to be cycle exact (as far as I can tell)
- Fixed a bunch of bugs in v65C02
- Dropped NIB support
- Added WOZ 1.0 file support

That last item is a bit of a big deal, as I had been thinking about
writing a new file format that would be bit-based--since the NIB nybble
format, while better than pretty much all the other formats out there,
fails hard in things like extra sync bits and half tracks.  So, somewhat
serendipitously, I stumbled upon the Applesauce project and found out
that not only had other people been thinking in more or less the same
direction, they had created it and had made disk images to try!

So now, because of this, WOZ is the internal format used by the floppy
emulation (as opposed to NIB) which, along with the new disk Logic State
Sequencer emulator, makes it possible to format floppy disks correctly
for the first time.  :-)

One ironic consequence of this is that NIB format can no longer be
properly supported.  The irony comes from the fact that before there was
LSS emulation, NIB was the most accurate format you could get to
represent the low level format of a disk, but now, with proper LSS
emulation, it's the worst format for representing a floppy disk.  And
the main reason for this is that NIB doesn't contain sync bits, and has
no mechanism to represent them--so when feeding them to the new LSS
emulation, they will fail horribly because without sync bits, the
bitstream represented by a NIB formatted disk can and will be
misinterpreted by the LSS.  And since there is now a format that
properly represents the bitstream on a floppy disk (WOZ), there's
absolutely no reason to keep NIB around or support it anymore.  While it
was a nice interim format to have around (when the emulation of the disk
was "imperfectly perfect"), it now no longer has a place in disk
preservation and/or emulation.

Another consequence of this new format is that Apple2 only supports
writing of WOZ images--it will no longer support writing of DSK and its
bretheren.  However, since those formats are extremely limited in their
scope (they literally only represented the contents of the sectors on a
disk) we still support reading them; Apple2 will automagically upconvert
them and save them as WOZs (it will use the same filename but substitute
"woz" for the old extension).  So if you're wondering why your DSKs are
unchanged when saving to them, you now know why.  :-)

Big, big thanks to the Applesauce guys and everyone who contributed and
continues to contribute to that project; your efforts are very much
appreciated--you guys are awesome!

45 files changed:
.gitignore
Makefile
apple2.cfg
cross-compile
src/apple2.cpp
src/apple2.h
src/ay8910.cpp [deleted file]
src/ay8910.h [deleted file]
src/charset.cpp
src/crc32.cpp
src/crc32.h
src/floppy.cpp [deleted file]
src/floppy.h [deleted file]
src/floppydrive.cpp [new file with mode: 0644]
src/floppydrive.h [new file with mode: 0644]
src/gui/diskselector.cpp
src/gui/diskselector.h
src/gui/font10pt.cpp
src/gui/gui.cpp
src/log.cpp
src/mmu.cpp
src/mmu.h
src/mockingboard.cpp [new file with mode: 0644]
src/mockingboard.h [new file with mode: 0644]
src/mos6522via.cpp [deleted file]
src/sound.cpp
src/v6522via.cpp [new file with mode: 0644]
src/v6522via.h [moved from src/mos6522via.h with 61% similarity]
src/v65c02.cpp
src/vay8910.cpp [new file with mode: 0644]
src/vay8910.h [new file with mode: 0644]
src/video.cpp
web/apple2.css
web/img/a2-icon-64x64.png [new file with mode: 0644]
web/img/a2-logo.png [new file with mode: 0644]
web/img/ss-01.png [new file with mode: 0644]
web/img/ss-01s.png [new file with mode: 0644]
web/img/ss-02.png [new file with mode: 0644]
web/img/ss-02s.png [new file with mode: 0644]
web/img/ss-03.png [new file with mode: 0644]
web/img/ss-03s.png [new file with mode: 0644]
web/img/ss-04.png [new file with mode: 0644]
web/img/ss-04s.png [new file with mode: 0644]
web/index.html
web/nib.html [new file with mode: 0644]

index 539de2008c39eba29851cb93377c998e651f5bc7..efe1d56a18eeb4c510f73e46b4c5073bf2d6719b 100644 (file)
@@ -13,3 +13,4 @@ ROMs/bin2c
 ROMs/from-applewin/
 res/
 docs/
+wozmaker/
index 449664c38be5398091bf08c33130d8f791826bd6..f0a599be1bcc0d3717c6052ec7ef30af29be58c1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,8 +20,9 @@ ifeq "$(findstring Msys,$(OSTYPE))" "Msys"
 SYSTYPE    = __GCCWIN32__
 EXESUFFIX  = .exe
 ICON       = obj/icon.o
-SDLLIBTYPE = --libs
+SDLLIBTYPE = --static-libs
 MSG        = Win32 on MinGW
+EXTRA      = -static
 
 # Should catch both 'darwin' and 'darwin7.0'
 else ifeq "$(findstring Darwin,$(OSTYPE))" "Darwin"
@@ -86,7 +87,7 @@ CFLAGS   = $(GCC_DEPS) -Wall -Wno-switch $(DEFINES) -ffast-math $(SDL_CFLAGS) -p
 CPPFLAGS = $(GCC_DEPS) -Wall -Wno-switch -Wno-non-virtual-dtor $(DEFINES) \
                -ffast-math $(SDL_CFLAGS) -pg -g
 
-LDFLAGS =
+LDFLAGS = $(EXTRA)
 
 #LIBS = -L/usr/local/lib -L/usr/lib `sdl2-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB)
 # Link in the gcov library (for profiling purposes)
@@ -107,20 +108,21 @@ OBJS = \
        obj/gui.o             \
                               \
        obj/apple2-icon-64x64.o \
-       obj/ay8910.o          \
        obj/charset.o         \
        obj/crc32.o           \
        obj/dis65c02.o        \
        obj/firmware.o        \
-       obj/floppy.o          \
+       obj/floppydrive.o     \
        obj/log.o             \
-       obj/mos6522via.o      \
        obj/mmu.o             \
+       obj/mockingboard.o    \
        obj/sdlemu_config.o   \
        obj/settings.o        \
        obj/sound.o           \
        obj/timing.o          \
+       obj/v6522via.o        \
        obj/v65c02.o          \
+       obj/vay8910.o         \
        obj/video.o           \
        obj/apple2.o          \
        $(ICON)
index 61e176b0a1c47374b1a7576515c012d05a6231b0..b4cac17fdeac00eccfd2a090f7e12f161bf2464c 100644 (file)
@@ -6,14 +6,17 @@
 
 #default
 #BIOSROM = ./ROMs/apple2e-enhanced.rom
+#BIOSROM = ./ROMs/apple2e.rom
 #Not used anymore
 #diskROM = ./ROMs/disk.rom
 #ROMs = ./ROMs
+#default
+#disks = ./disks
 
 # Auto state loading/saving upon starting/quitting Apple2 (1 - use, 0 - don't use)
 
 #These are the defaults--we don't advertise it just yet... ;-)
-#autoSaveState = 1
+autoSaveState = 0
 #autoStateFilename = ./apple2auto.state
 
 # OpenGL filtering type: 1 - blurry, 0 - sharp
index f0b73fabc88b0df5b9875ac409dd52c6e809753e..2598b84420a344c0632d3a4d6c3d990bf1e6b2dd 100755 (executable)
@@ -7,8 +7,9 @@
 #
 export PATH=/opt/mxe/usr/bin:$PATH
 #make CROSS=i686-pc-mingw32- clean  && make CROSS=i686-pc-mingw32-
-make CROSS=x86_64-w64-mingw32- clean  && make CROSS=x86_64-w64-mingw32.static-
-upx -9v apple2.exe
+make CROSS=x86_64-w64-mingw32.static- clean \
+ && make CROSS=x86_64-w64-mingw32.static- \
+ && upx -9v apple2.exe
 
 #TARGET = apple2
 #echo "Cross compiling $(TARGET) for Win32..."
index b9bd4ff3f668f082ee74d4fe19c8e24c50186d55..33b9e22da4b3d6d90b93aeacc08a8e8d38112dd3 100644 (file)
@@ -6,7 +6,7 @@
 //
 // Parts loosely inspired by AppleWin by Tom Charlesworth which was based on
 // AppleWin by Oliver Schmidt which was based on AppleWin by Michael O'Brien.
-// :-) Some parts (mainly TV rendering) are derived from ApplePC. Too bad it
+// :-)  Some parts (mainly TV rendering) are derived from ApplePC.  Too bad it
 // was closed source--it could have been *the* premier Apple II emulator out
 // there.
 //
 #include <stdlib.h>
 #include <string>
 #include <time.h>
-#include "ay8910.h"
 #include "firmware.h"
-#include "floppy.h"
+//#include "floppydisk.h"
 #include "log.h"
-#include "mos6522via.h"
 #include "mmu.h"
+#include "mockingboard.h"
 #include "settings.h"
 #include "sound.h"
 #include "timing.h"
@@ -73,17 +72,11 @@ uint8_t ram[0x10000], rom[0x10000];                 // RAM & ROM spaces
 uint8_t ram2[0x10000];                                         // Auxillary RAM
 V65C02REGS mainCPU;                                                    // v65C02 execution context
 uint8_t appleType = APPLE_TYPE_IIE;
-FloppyDrive floppyDrive;
 bool powerStateChangeRequested = false;
 uint64_t frameCycleStart;
 
-#if 0
-uint32_t frameTicks = 0;
-uint32_t frameTime[60];
-#else
 uint64_t frameTicks = 0;
 uint64_t frameTime[60];
-#endif
 uint32_t frameTimePtr = 0;
 
 // Exported variables
@@ -94,8 +87,9 @@ bool openAppleDown = false;
 bool closedAppleDown = false;
 bool store80Mode = false;
 bool vbl = false;
-bool slotCXROM = false;
+bool intCXROM = false;
 bool slotC3ROM = false;
+bool intC8ROM = false;
 bool ramrd = false;
 bool ramwrt = false;
 bool altzp = false;
@@ -103,17 +97,12 @@ bool ioudis = true;
 bool dhires = false;
 // Language card state (ROM read, no write)
 uint8_t lcState = 0x02;
+uint8_t blinkTimer = 0;
 
 static bool running = true;                                    // Machine running state flag...
-#if 0
-static uint32_t startTicks;
-#else
 static uint64_t startTicks;
-#endif
 static bool pauseMode = false;
 static bool fullscreenDebounce = false;
-//static bool capsLock = false;
-//static bool capsLockDebounce = false;
 static bool resetKeyDown = false;
 static int8_t hideMouseTimeout = 60;
 
@@ -186,37 +175,24 @@ WriteLog("CPU: SDL_SemWait(mainSem);\n");
 #ifdef THREAD_DEBUGGING
 WriteLog("CPU: Execute65C02(&mainCPU, cycles);\n");
 #endif
-//             for(int i=0; i<786; i++)
                for(int i=0; i<262; i++)
                {
-//                     uint32_t cycles = 21;
-//                     overflow += 0.666666667;
-
-//                     if (overflow > 1.0)
-//                     {
-//                             cycles++;
-//                             overflow -= 1.0;
-//                     }
-
                        // If the CTRL+Reset key combo is being held, make sure the RESET
                        // line stays asserted:
                        if (resetKeyDown)
                                mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET;
 
-//                     Execute65C02(&mainCPU, cycles);
                        Execute65C02(&mainCPU, 65);
-//                     WriteSampleToBuffer();
 
                        // According to "Understanding The Apple IIe", VBL asserted after
                        // the last byte of the screen is read and let go on the first read
                        // of the first byte of the screen. We now know that the screen
                        // starts on line #6 and ends on line #197 (of the vertical
-                       // counter--actual VBLANK happens on lines 230 thru 233).
-//                     vbl = ((i > 17) && (i < 592) ? true : false);
+                       // counter--actual VBLANK proper happens on lines 230 thru 233).
                        vbl = ((i >= 6) && (i <= 197) ? true : false);
                }
 
-WriteLog("*** Frame ran for %d cycles (%.3lf Âµs, %d samples).\n", mainCPU.clock - oldClock, ((double)(SDL_GetPerformanceCounter() - cpuFrameTickStart) * 1000000.0) / (double)SDL_GetPerformanceFrequency(), sampleCount);
+//WriteLog("*** Frame ran for %d cycles (%.3lf Âµs, %d samples).\n", mainCPU.clock - oldClock, ((double)(SDL_GetPerformanceCounter() - cpuFrameTickStart) * 1000000.0) / (double)SDL_GetPerformanceFrequency(), sampleCount);
 //     frameTicks = ((SDL_GetPerformanceCounter() - startTicks) * 1000) / SDL_GetPerformanceFrequency();
 /*
 Other timings from UTA2E:
@@ -325,7 +301,7 @@ bool LoadImg(char * filename, uint8_t * ram, int size)
 }
 
 
-const uint8_t stateHeader[19] = "APPLE2SAVESTATE1.1";
+const uint8_t stateHeader[19] = "APPLE2SAVESTATE1.2";
 static void SaveApple2State(const char * filename)
 {
        WriteLog("Main: Saving Apple2 state...\n");
@@ -353,8 +329,9 @@ static void SaveApple2State(const char * filename)
        fputc((uint8_t)closedAppleDown, file);
        fputc((uint8_t)store80Mode, file);
        fputc((uint8_t)vbl, file);
-       fputc((uint8_t)slotCXROM, file);
+       fputc((uint8_t)intCXROM, file);
        fputc((uint8_t)slotC3ROM, file);
+       fputc((uint8_t)intC8ROM, file);
        fputc((uint8_t)ramrd, file);
        fputc((uint8_t)ramwrt, file);
        fputc((uint8_t)altzp, file);
@@ -370,7 +347,10 @@ static void SaveApple2State(const char * filename)
        fputc(lcState, file);
 
        // Write out floppy state
-       floppyDrive.SaveState(file);
+       floppyDrive[0].SaveState(file);
+
+       // Write out Mockingboard state
+       MBSaveState(file);
        fclose(file);
 }
 
@@ -410,8 +390,9 @@ static bool LoadApple2State(const char * filename)
        closedAppleDown = (bool)fgetc(file);
        store80Mode = (bool)fgetc(file);
        vbl = (bool)fgetc(file);
-       slotCXROM = (bool)fgetc(file);
+       intCXROM = (bool)fgetc(file);
        slotC3ROM = (bool)fgetc(file);
+       intC8ROM = (bool)fgetc(file);
        ramrd = (bool)fgetc(file);
        ramwrt = (bool)fgetc(file);
        altzp = (bool)fgetc(file);
@@ -427,8 +408,10 @@ static bool LoadApple2State(const char * filename)
        lcState = fgetc(file);
 
        // Read in floppy state
-       floppyDrive.LoadState(file);
+       floppyDrive[0].LoadState(file);
 
+       // Read in Mockingboard state
+       MBLoadState(file);
        fclose(file);
 
        // Make sure things are in a sane state before execution :-P
@@ -448,8 +431,9 @@ static void ResetApple2State(void)
        closedAppleDown = false;
        store80Mode = false;
        vbl = false;
-       slotCXROM = false;
+       intCXROM = false;
        slotC3ROM = false;
+       intC8ROM = false;
        ramrd = false;
        ramwrt = false;
        altzp = false;
@@ -457,14 +441,7 @@ static void ResetApple2State(void)
        dhires = false;
        lcState = 0x02;
        ResetMMUPointers();
-       ResetMBVIAs();
-#ifdef USE_NEW_AY8910
-       AYReset(0);
-       AYReset(1);
-#else
-       AY8910_reset(0);
-       AY8910_reset(1);
-#endif
+       MBReset();
 
        // Without this, you can wedge the system :-/
        memset(ram, 0, 0x10000);
@@ -477,54 +454,12 @@ static double cyclesForSample = 0;
 static void AppleTimer(uint16_t cycles)
 {
        // Handle PHI2 clocked stuff here...
-       bool via1T1HitZero = (mbvia[0].timer1counter <= cycles ? true : false);
-       bool via2T1HitZero = (mbvia[1].timer1counter <= cycles ? true : false);
-
-       mbvia[0].timer1counter -= cycles;
-       mbvia[0].timer2counter -= cycles;
-       mbvia[1].timer1counter -= cycles;
-       mbvia[1].timer2counter -= cycles;
-
-       if (via1T1HitZero)
-       {
-               if (mbvia[0].acr & 0x40)
-               {
-                       mbvia[0].timer1counter += mbvia[0].timer1latch;
-
-                       if (mbvia[0].ier & 0x40)
-                       {
-                               mbvia[0].ifr |= (0x80 | 0x40);
-                               mainCPU.cpuFlags |= V65C02_ASSERT_LINE_IRQ;
-                       }
-               }
-               else
-               {
-                       mbvia[0].ier &= 0x3F; // Disable T1 interrupt (VIA #1)
-               }
-       }
-
-       if (via2T1HitZero)
-       {
-               if (mbvia[1].acr & 0x40)
-               {
-                       mbvia[1].timer1counter += mbvia[1].timer1latch;
-
-                       if (mbvia[1].ier & 0x40)
-                       {
-                               mbvia[1].ifr |= (0x80 | 0x40);
-                               mainCPU.cpuFlags |= V65C02_ASSERT_LINE_NMI;
-                       }
-               }
-               else
-               {
-                       mbvia[1].ier &= 0x3F; // Disable T1 interrupt (VIA #2)
-               }
-       }
+       MBRun(cycles);
+       floppyDrive[0].RunSequencer(cycles);
 
 #if 1
        // Handle sound
        // 21.26009 cycles per sample @ 48000 (running @ 1,020,484.32 Hz)
-       // Noooooope.  We need ~801 cycles per frame.  Averaging about 786, so missing 15 or so.
        // 16.688154500083 ms = 1 frame
        cyclesForSample += (double)cycles;
 
@@ -608,15 +543,9 @@ int main(int /*argc*/, char * /*argv*/[])
        SetupAddressMap();
        ResetMMUPointers();
 
-       // Set up Mockingboard
-       memset(&mbvia[0], 0, sizeof(MOS6522VIA));
-       memset(&mbvia[1], 0, sizeof(MOS6522VIA));
-//(at some point this shite will have to go into the state file...)
-#ifdef USE_NEW_AY8910
-       AYInit();
-#else
-       AY8910_InitAll(1020484, 48000);
-#endif
+       // Install devices in slots
+       InstallFloppy(6);
+       InstallMockingboard(4);
 
        // Set up V65C02 execution context
        memset(&mainCPU, 0, sizeof(V65C02REGS));
@@ -670,7 +599,7 @@ So we need to decouple the CPU thread from the host video thread, and have the C
        // Set frame to fire at 1/60 s interval
        SetCallbackTime(FrameCallback, 16666.66666667);
        // Set up blinking at 1/4 s intervals
-       SetCallbackTime(BlinkTimer, 250000);
+//     SetCallbackTime(BlinkTimer, 250000);
        startTicks = SDL_GetTicks();
 
 #ifdef THREADED_65C02
@@ -722,8 +651,19 @@ WriteLog("Main: SDL_DestroyCond(cpuCond);\n");
        if (settings.autoStateSaving)
                SaveApple2State(settings.autoStatePath);
 
-       floppyDrive.SaveImage(0);
-       floppyDrive.SaveImage(1);
+       floppyDrive[0].SaveImage(0);
+       floppyDrive[0].SaveImage(1);
+
+#if 0
+#include "dis65c02.h"
+static char disbuf[80];
+uint16_t pc=0x801;
+while (pc < 0x9FF)
+{
+       pc += Decode65C02(&mainCPU, disbuf, pc);
+       WriteLog("%s\n", disbuf);
+}
+#endif
 
        SoundDone();
        VideoDone();
@@ -822,6 +762,10 @@ static void FrameCallback(void)
                        {
 //seems to leave the machine in an inconsistent state vis-a-vis the language card... [does it anymore?]
                                resetKeyDown = true;
+                               // Need to reset the MMU switches as well on RESET
+                               intCXROM = false;
+                               slotC3ROM = false;
+                               intC8ROM = false;
                                break;
                        }
 
@@ -910,9 +854,7 @@ static void FrameCallback(void)
                                        lastKeyPressed -= 0x20;
 
                                // Handle key repeat if the key hasn't been held
-//                             if (keyDelay == 0)
-                                       keyDelay = 15;
-
+                               keyDelay = 15;
                                keyDownCount++;
 
                                // Buffer the key held. Note that the last key is always
@@ -951,29 +893,6 @@ static void FrameCallback(void)
                                openAppleDown = true;
                        else if (event.key.keysym.sym == SDLK_RALT)
                                closedAppleDown = true;
-                       // Toggle the disassembly process
-                       else if (event.key.keysym.sym == SDLK_F11)
-                       {
-                               dumpDis = !dumpDis;
-                               SpawnMessage("Trace: %s", (dumpDis ? "ON" : "off"));
-                       }
-                       else if (event.key.keysym.sym == SDLK_F12)
-                       {
-                               logAYInternal = !logAYInternal;
-                               SpawnMessage("AY Trace: %s", (logAYInternal ? "ON" : "off"));
-                       }
-
-/*else if (event.key.keysym.sym == SDLK_F9)
-{
-       floppyDrive.CreateBlankImage(0);
-//     SpawnMessage("Image cleared...");
-}//*/
-/*else if (event.key.keysym.sym == SDLK_F10)
-{
-       floppyDrive.SwapImages();
-//     SpawnMessage("Image swapped...");
-}//*/
-
                        else if (event.key.keysym.sym == SDLK_F2)
                                TogglePalette();
                        else if (event.key.keysym.sym == SDLK_F3)
@@ -1003,13 +922,30 @@ static void FrameCallback(void)
                        else if (event.key.keysym.sym == SDLK_F7)
                        {
                                // 4th root of 2 is ~1.18920711500272 (~1.5 dB)
-                               maxVolume /= 1.4142135f;        // This attenuates by ~3 dB
-                               SpawnMessage("MB Volume: %d", (int)maxVolume);
+                               // This attenuates by ~3 dB
+                               VAY_3_8910::maxVolume /= 1.4142135f;
+                               SpawnMessage("MB Volume: %d", (int)VAY_3_8910::maxVolume);
                        }
                        else if (event.key.keysym.sym == SDLK_F8)
                        {
-                               maxVolume *= 1.4142135f;
-                               SpawnMessage("MB Volume: %d", (int)maxVolume);
+                               VAY_3_8910::maxVolume *= 1.4142135f;
+                               SpawnMessage("MB Volume: %d", (int)VAY_3_8910::maxVolume);
+                       }
+else if (event.key.keysym.sym == SDLK_F9)
+{
+       floppyDrive[0].CreateBlankImage(1);
+//     SpawnMessage("Image cleared...");
+}//*/
+/*else if (event.key.keysym.sym == SDLK_F10)
+{
+       floppyDrive[0].SwapImages();
+//     SpawnMessage("Image swapped...");
+}//*/
+                       // Toggle the disassembly process
+                       else if (event.key.keysym.sym == SDLK_F11)
+                       {
+                               dumpDis = !dumpDis;
+                               SpawnMessage("Trace: %s", (dumpDis ? "ON" : "off"));
                        }
                        else if (event.key.keysym.sym == SDLK_F12)
                        {
@@ -1133,6 +1069,11 @@ static void FrameCallback(void)
                powerStateChangeRequested = false;
        }
 
+       blinkTimer = (blinkTimer + 1) & 0x1F;
+
+       if (blinkTimer == 0)
+               flash = !flash;
+
        // Render the Apple screen + GUI overlay
        RenderAppleScreen(sdlRenderer);
        GUI::Render(sdlRenderer);
index 3e8559e49f61aa15925d5639ba76f29d2953bb71..0bbf6d04a205dc5670a99d5305a41b78be063c3c 100644 (file)
@@ -3,7 +3,7 @@
 //
 
 #include <stdint.h>
-#include "floppy.h"
+#include "floppydrive.h"
 #include "v65c02.h"
 
 enum { APPLE_TYPE_II, APPLE_TYPE_IIE, APPLE_TYPE_IIC };
@@ -19,15 +19,15 @@ extern uint8_t ram[0x10000], rom[0x10000];          // RAM & ROM pointers
 extern uint8_t ram2[0x10000];                                  // Auxillary RAM
 extern V65C02REGS mainCPU;                                             // v65C02 execution context
 extern uint8_t appleType;
-extern FloppyDrive floppyDrive;
 extern uint8_t lastKeyPressed;
 extern bool keyDown;
 extern bool openAppleDown;
 extern bool closedAppleDown;
 extern bool store80Mode;
 extern bool vbl;
-extern bool slotCXROM;
+extern bool intCXROM;
 extern bool slotC3ROM;
+extern bool intC8ROM;
 extern bool ramrd;
 extern bool ramwrt;
 extern bool altzp;
diff --git a/src/ay8910.cpp b/src/ay8910.cpp
deleted file mode 100644 (file)
index 50862ed..0000000
+++ /dev/null
@@ -1,1176 +0,0 @@
-//
-// AY-3-8910 Emulator
-//
-// This was written mainly from the General Instruments datasheet for the 8910
-// part.  I would have used the one from MAME, but it was so poorly written and
-// so utterly incomprehensible that I decided to start from scratch to see if I
-// could do any better; and so here we are.  I did use a bit of code from
-// MAME's AY-3-8910 RNG, as it was just too neat not to use.  :-)
-//
-// by James Hammons
-// (C) 2018 Underground Software
-//
-
-#include "ay8910.h"
-
-#include <string.h>                    // for memset()
-#include "log.h"
-#include "sound.h"
-
-
-struct AY_3_8910
-{
-       // User visible registers
-       uint16_t period[3];             // Channel A-C period
-       int16_t volume[3];              // Channel A-C volume (non-envelope mode)
-       bool envEnable[3];              // Channel A-C envelope enable
-       bool toneEnable[3];             // Channel A-C tone enable
-       bool noiseEnable[3];    // Channel A-C noise enable
-       uint16_t noisePeriod;   // Noise period (5 bits * 16)
-       uint32_t envPeriod;             // Envelope period (16 bits * 256)
-       bool envAttack;                 // Envelope Attack bit
-       bool envAlternate;              // Envelope Alternate bit
-       bool envHold;                   // Envelope Hold bit
-       // Internal registers
-       uint16_t count[3];              // Channel A-C current count
-       bool state[3];                  // Channel A-C current state
-       uint16_t noiseCount;    // Noise current count
-       bool noiseState;                // Noise state
-       uint32_t envCount[3];   // Envelope current count
-       int16_t envDirection[3];// Envelope direction (rising, 0, or falling)
-       uint32_t prng;                  // Psuedo RNG (17 bits)
-};
-
-
-// Maximum volume that can be generated by one voice
-float maxVolume = 8192.0f;
-
-// Normalized volumes (zero to one) for AY-3-8910 output, in 16 steps
-static float normalizedVolume[16];// = {};
-
-// AY-3-8910 register IDs
-enum { AY_AFINE = 0, AY_ACOARSE, AY_BFINE, AY_BCOARSE, AY_CFINE, AY_CCOARSE,
-       AY_NOISEPER, AY_ENABLE, AY_AVOL, AY_BVOL, AY_CVOL, AY_EFINE, AY_ECOARSE,
-       AY_ESHAPE, AY_PORTA, AY_PORTB };
-
-// Chip structs (for up to four separate chips)
-static AY_3_8910 ay[4];
-
-
-void AYInit(void)
-{
-       for(int chip=0; chip<4; chip++)
-               AYReset(chip);
-
-       // Our normalized volume levels are from 0 to -48 dB, in 3 dB steps.
-       // N.B.: It's 3dB steps because those sound the best.  Dunno what it really
-       //       is, as nothing in the documentation tells you (it only says that
-       //       each channel's volume is normalized from 0 to 1.0V).
-       float level = 1.0f;
-
-       for(int i=15; i>=0; i--)
-       {
-               normalizedVolume[i] = level;
-               level /= 1.4125375446228;       // 10.0 ^ (3.0 / 20.0) = 3 dB
-       }
-
-       // In order to get a scale that goes from 0 to 1 smoothly, we renormalize
-       // our volumes so that volume[0] is actually 0, and volume[15] is 1.
-       // Basically, we're sliding the curve down the Y-axis so that volume[0]
-       // touches the X-axis, then stretching the result so that it fits into the
-       // interval (0, 1).
-       float vol0 = normalizedVolume[0];
-       float vol15 = normalizedVolume[15] - vol0;
-
-       for(int i=0; i<16; i++)
-               normalizedVolume[i] = (normalizedVolume[i] - vol0) / vol15;
-
-#if 0
-       WriteLog("\nRenormalized volume, level (max=%d):\n", (int)maxVolume);
-       for(int i=0; i<16; i++)
-               WriteLog("%lf, %d\n", normalizedVolume[i], (int)(normalizedVolume[i] * maxVolume));
-       WriteLog("\n");
-#endif
-}
-/*
-Renormalized:
-0.000000, 0
-0.002333, 13
-0.005628, 33
-0.010283, 61
-0.016859, 101
-0.026146, 156
-0.039266, 235
-0.057797, 346
-0.083974, 503
-0.120949, 725
-0.173178, 1039
-0.246954, 1481
-0.351165, 2106
-0.498366, 2990
-0.706294, 4237
-1.000000, 6000
-*/
-
-
-void AYReset(int chipNum)
-{
-       memset(&ay[chipNum], 0, sizeof(struct AY_3_8910));
-       ay[chipNum].prng = 1;   // Set correct PRNG seed
-}
-
-
-void AYWrite(int chipNum, int reg, int value)
-{
-#if 0
-static char regname[16][32] = {
-       "AY_AFINE   ",
-       "AY_ACOARSE ",
-       "AY_BFINE   ",
-       "AY_BCOARSE ",
-       "AY_CFINE   ",
-       "AY_CCOARSE ",
-       "AY_NOISEPER",
-       "AY_ENABLE  ",
-       "AY_AVOL    ",
-       "AY_BVOL    ",
-       "AY_CVOL    ",
-       "AY_EFINE   ",
-       "AY_ECOARSE ",
-       "AY_ESHAPE  ",
-       "AY_PORTA   ",
-       "AY_PORTB   "
-};
-WriteLog("*** AY(%d) Reg: %s = $%02X\n", chipNum, regname[reg], value);
-#endif
-       AY_3_8910 * chip = &ay[chipNum];
-       value &= 0xFF;  // Ensure passed in value is no larger than 8 bits
-
-       switch (reg)
-       {
-       case AY_AFINE:
-               // The square wave period is the passed in value times 16, so we handle
-               // that here.
-               chip->period[0] = (chip->period[0] & 0xF000) | (value << 4);
-               break;
-       case AY_ACOARSE:
-               chip->period[0] = ((value & 0x0F) << 12) | (chip->period[0] & 0xFF0);
-               break;
-       case AY_BFINE:
-               chip->period[1] = (chip->period[1] & 0xF000) | (value << 4);
-               break;
-       case AY_BCOARSE:
-               chip->period[1] = ((value & 0x0F) << 12) | (chip->period[1] & 0xFF0);
-               break;
-       case AY_CFINE:
-               chip->period[2] = (chip->period[2] & 0xF000) | (value << 4);
-               break;
-       case AY_CCOARSE:
-               chip->period[2] = ((value & 0x0F) << 12) | (chip->period[2] & 0xFF0);
-               break;
-       case AY_NOISEPER:
-               // Like the square wave period, the value is the what's passed * 16.
-               chip->noisePeriod = (value & 0x1F) << 4;
-               break;
-       case AY_ENABLE:
-               chip->toneEnable[0] = (value & 0x01 ? false : true);
-               chip->toneEnable[1] = (value & 0x02 ? false : true);
-               chip->toneEnable[2] = (value & 0x04 ? false : true);
-               chip->noiseEnable[0] = (value & 0x08 ? false : true);
-               chip->noiseEnable[1] = (value & 0x10 ? false : true);
-               chip->noiseEnable[2] = (value & 0x20 ? false : true);
-               break;
-       case AY_AVOL:
-               chip->volume[0]    = value & 0x0F;
-               chip->envEnable[0] = (value & 0x10 ? true : false);
-
-               if (chip->envEnable[0])
-               {
-                       chip->envCount[0]     = 0;
-                       chip->volume[0]       = (chip->envAttack ? 0 : 15);
-                       chip->envDirection[0] = (chip->envAttack ? 1 : -1);
-               }
-               break;
-       case AY_BVOL:
-               chip->volume[1]    = value & 0x0F;
-               chip->envEnable[1] = (value & 0x10 ? true : false);
-
-               if (chip->envEnable[1])
-               {
-                       chip->envCount[1]     = 0;
-                       chip->volume[1]       = (chip->envAttack ? 0 : 15);
-                       chip->envDirection[1] = (chip->envAttack ? 1 : -1);
-               }
-               break;
-       case AY_CVOL:
-               chip->volume[2]    = value & 0x0F;
-               chip->envEnable[2] = (value & 0x10 ? true : false);
-
-               if (chip->envEnable[2])
-               {
-                       chip->envCount[2]     = 0;
-                       chip->volume[2]       = (chip->envAttack ? 0 : 15);
-                       chip->envDirection[2] = (chip->envAttack ? 1 : -1);
-               }
-               break;
-       case AY_EFINE:
-               // The envelope period is 256 times the passed in value
-               chip->envPeriod = (chip->envPeriod & 0xFF0000) | (value << 8);
-               break;
-       case AY_ECOARSE:
-               chip->envPeriod = (value << 16) | (chip->envPeriod & 0xFF00);
-               break;
-       case AY_ESHAPE:
-               chip->envAttack    = (value & 0x04 ? true : false);
-               chip->envAlternate = (value & 0x02 ? true : false);
-               chip->envHold      = (value & 0x01 ? true : false);
-
-               // If the Continue bit is *not* set, the Alternate bit is forced to the
-               // Attack bit, and Hold is forced on.
-               if (!(value & 0x08))
-               {
-                       chip->envAlternate = chip->envAttack;
-                       chip->envHold = true;
-               }
-
-               // Reset all voice envelope counts...
-               for(int i=0; i<3; i++)
-               {
-                       chip->envCount[i]     = 0;
-                       chip->envDirection[i] = (chip->envAttack ? 1 : -1);
-
-                       // Only reset the volume if the envelope is enabled!
-                       if (chip->envEnable[i])
-                               chip->volume[i] = (chip->envAttack ? 0 : 15);
-               }
-               break;
-       }
-}
-
-
-//
-// Generate one sample and quit
-//
-bool logAYInternal = false;
-uint16_t AYGetSample(int chipNum)
-{
-       AY_3_8910 * chip = &ay[chipNum];
-       uint16_t sample = 0;
-
-       // Number of cycles per second to run the PSG is the 6502 clock rate
-       // divided by the host sample rate
-       const static double exactCycles = 1020484.32 / (double)SAMPLE_RATE;
-       static double overflow = 0;
-
-       int fullCycles = (int)exactCycles;
-       overflow += exactCycles - (double)fullCycles;
-
-       if (overflow >= 1.0)
-       {
-               fullCycles++;
-               overflow -= 1.0;
-       }
-
-       for(int i=0; i<fullCycles; i++)
-       {
-               for(int j=0; j<3; j++)
-               {
-                       // Tone generators only run if the corresponding voice is enabled.
-                       // N.B.: We also reject any period set that is less than 2.
-                       if (chip->toneEnable[j] && (chip->period[j] > 16))
-                       {
-                               chip->count[j]++;
-
-                               // It's (period / 2) because one full period of a square wave
-                               // is 0 for half of its period and 1 for the other half!
-                               if (chip->count[j] > (chip->period[j] / 2))
-                               {
-                                       chip->count[j] = 0;
-                                       chip->state[j] = !chip->state[j];
-                               }
-                       }
-
-                       // Envelope generator only runs if the corresponding voice flag is
-                       // enabled.
-                       if (chip->envEnable[j])
-                       {
-                               chip->envCount[j]++;
-
-                               // It's (EP / 16) because there are 16 volume steps in each EP.
-                               if (chip->envCount[j] > (chip->envPeriod / 16))
-                               {
-                                       // Attack 0 = \, 1 = / (attack lasts one EP)
-                                       // Alternate = mirror envelope's last attack
-                                       // Hold = run 1 EP, hold at level (Alternate XOR Attack)
-                                       chip->envCount[j] = 0;
-
-                                       // We've hit a point where we need to make a change to the
-                                       // envelope's volume, so do it:
-                                       chip->volume[j] += chip->envDirection[j];
-
-                                       // If we hit the end of the EP, change the state of the
-                                       // envelope according to the envelope's variables.
-                                       if ((chip->volume[j] > 15) || (chip->volume[j] < 0))
-                                       {
-                                               // Hold means we set the volume to (Alternate XOR
-                                               // Attack) and stay there after the Attack EP.
-                                               if (chip->envHold)
-                                               {
-                                                       chip->volume[j] = (chip->envAttack != chip->envAlternate ? 15: 0);
-                                                       chip->envDirection[j] = 0;
-                                               }
-                                               else
-                                               {
-                                                       // If the Alternate bit is set, we mirror the
-                                                       // Attack pattern; otherwise we reset it to the
-                                                       // whatever level was set by the Attack bit.
-                                                       if (chip->envAlternate)
-                                                       {
-                                                               chip->envDirection[j] = -chip->envDirection[j];
-                                                               chip->volume[j] += chip->envDirection[j];
-                                                       }
-                                                       else
-                                                               chip->volume[j] = (chip->envAttack ? 0 : 15);
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               // Noise generator (the PRNG) runs all the time:
-               chip->noiseCount++;
-
-               if (chip->noiseCount > chip->noisePeriod)
-               {
-                       chip->noiseCount = 0;
-
-                       // The following is from MAME's AY-3-8910 code:
-                       // The Pseudo Random Number Generator of the 8910 is a 17-bit shift
-                       // register. The input to the shift register is bit0 XOR bit3 (bit0
-                       // is the output). This was verified on AY-3-8910 and YM2149 chips.
-
-                       // The following is a fast way to compute bit17 = bit0 ^ bit3.
-                       // Instead of doing all the logic operations, we only check bit0,
-                       // relying on the fact that after three shifts of the register,
-                       // what now is bit3 will become bit0, and will invert, if
-                       // necessary, bit14, which previously was bit17.
-                       if (chip->prng & 0x00001)
-                       {
-                               // This version is called the "Galois configuration".
-                               chip->prng ^= 0x24000;
-                               // The noise wave *toggles* when a one shows up in bit0...
-                               chip->noiseState = !chip->noiseState;
-                       }
-
-                       chip->prng >>= 1;
-               }
-       }
-
-       // We mix channels A-C here into one sample, because the Mockingboard just
-       // sums the output of the AY-3-8910 by tying their lines together.
-       // We also handle the various cases (of which there are four) of mixing
-       // pure tones and "noise" tones together.
-       for(int i=0; i<3; i++)
-       {
-               // Set the volume level scaled by the maximum volume (which can be
-               // altered outside of this module).
-               int level = (int)(normalizedVolume[chip->volume[i]] * maxVolume);
-
-               if (chip->toneEnable[i] && !chip->noiseEnable[i])
-                       sample += (chip->state[i] ? level : 0);
-               else if (!chip->toneEnable[i] && chip->noiseEnable[i])
-                       sample += (chip->noiseState ? level : 0);
-               else if (chip->toneEnable[i] && chip->noiseEnable[i])
-                       sample += (chip->state[i] & chip->noiseState ? level : 0);
-               else if (!chip->toneEnable[i] && !chip->noiseEnable[i])
-                       sample += level;
-       }
-
-       if (logAYInternal)
-       {
-               WriteLog("    (%d) State A,B,C: %s %s %s, Sample: $%04X, P: $%X, $%X, $%X\n", chipNum, (chip->state[0] ? "1" : "0"), (chip->state[1] ? "1" : "0"), (chip->state[2] ? "1" : "0"), sample, chip->period[0], chip->period[1], chip->period[2]);
-       }
-
-       return sample;
-}
-
-
-
-
-
-// STUFF TO DELETE...
-
-#if 0
-
-/***************************************************************************
-
-  ay8910.cpp
-
-  Emulation of the AY-3-8910 / YM2149 sound chip.
-
-  Based on various code snippets by Ville Hallik, Michael Cuddy,
-  Tatsuyuki Satoh, Fabrice Frances, Nicola Salmoria.
-
-***************************************************************************/
-
-//
-// From mame.txt (http://www.mame.net/readme.html)
-//
-// VI. Reuse of Source Code
-// --------------------------
-//    This chapter might not apply to specific portions of MAME (e.g. CPU
-//    emulators) which bear different copyright notices.
-//    The source code cannot be used in a commercial product without the
-//    written authorization of the authors. Use in non-commercial products is
-//    allowed, and indeed encouraged.  If you use portions of the MAME source
-//    code in your program, however, you must make the full source code freely
-//    available as well.
-//    Usage of the _information_ contained in the source code is free for any
-//    use. However, given the amount of time and energy it took to collect this
-//    information, if you find new information we would appreciate if you made
-//    it freely available as well.
-//
-
-// JLH: Commented out MAME specific crap
-
-#define MAX_OUTPUT 0x7FFF
-
-// See AY8910_set_clock() for definition of STEP
-#define STEP 0x8000
-
-struct AY8910
-{
-       int Channel;
-       int SampleRate;
-       int register_latch;
-       unsigned char Regs[16];
-       unsigned int UpdateStep;
-       int PeriodA, PeriodB, PeriodC, PeriodN, PeriodE;
-       int CountA, CountB, CountC, CountN, CountE;
-       unsigned int VolA, VolB, VolC, VolE;
-       unsigned char EnvelopeA, EnvelopeB, EnvelopeC;
-       unsigned char OutputA, OutputB, OutputC, OutputN;
-       signed char CountEnv;
-       unsigned char Hold, Alternate, Attack, Holding;
-       int RNG;
-       unsigned int VolTable[32];
-};
-
-static struct AY8910 AYPSG[MAX_8910];          /* array of PSG's */
-
-#define AY_AFINE       (0)
-#define AY_ACOARSE     (1)
-#define AY_BFINE       (2)
-#define AY_BCOARSE     (3)
-#define AY_CFINE       (4)
-#define AY_CCOARSE     (5)
-#define AY_NOISEPER    (6)
-#define AY_ENABLE      (7)
-#define AY_AVOL                (8)
-#define AY_BVOL                (9)
-#define AY_CVOL                (10)
-#define AY_EFINE       (11)
-#define AY_ECOARSE     (12)
-#define AY_ESHAPE      (13)
-//#define AY_PORTA     (14)
-//#define AY_PORTB     (15)
-
-
-void _AYWriteReg(int n, int r, int v)
-{
-#if 1
-static char regname[16][32] = {
-"AY_AFINE   ",
-"AY_ACOARSE ",
-"AY_BFINE   ",
-"AY_BCOARSE ",
-"AY_CFINE   ",
-"AY_CCOARSE ",
-"AY_NOISEPER",
-"AY_ENABLE  ",
-"AY_AVOL    ",
-"AY_BVOL    ",
-"AY_CVOL    ",
-"AY_EFINE   ",
-"AY_ECOARSE ",
-"AY_ESHAPE  ",
-"AY_PORTA   ",
-"AY_PORTB   "
-};
-WriteLog("*** AY(%d) Reg: %s = $%02X\n", n, regname[r], v);
-#endif
-       struct AY8910 * PSG = &AYPSG[n];
-       int old;
-
-       PSG->Regs[r] = v;
-
-       /* A note about the period of tones, noise and envelope: for speed reasons,
-        * we count down from the period to 0, but careful studies of the chip
-        * output prove that it instead counts up from 0 until the counter becomes
-        * greater or equal to the period. This is an important difference when the
-        * program is rapidly changing the period to modulate the sound.
-        * To compensate for the difference, when the period is changed we adjust
-        * our internal counter.
-        * Also, note that period = 0 is the same as period = 1. This is mentioned
-        * in the YM2203 data sheets. However, this does NOT apply to the Envelope
-        * period. In that case, period = 0 is half as period = 1.                  */
-       switch (r)
-       {
-       case AY_AFINE:
-       case AY_ACOARSE:
-               PSG->Regs[AY_ACOARSE] &= 0x0F;
-               old = PSG->PeriodA;
-//             PSG->PeriodA = (PSG->Regs[AY_AFINE] + 256 * PSG->Regs[AY_ACOARSE]) * PSG->UpdateStep;
-               PSG->PeriodA = ((PSG->Regs[AY_ACOARSE] << 8) | PSG->Regs[AY_AFINE]) * PSG->UpdateStep;
-
-               if (PSG->PeriodA == 0)
-                       PSG->PeriodA = PSG->UpdateStep;
-
-               PSG->CountA += PSG->PeriodA - old;
-
-               if (PSG->CountA <= 0)
-                       PSG->CountA = 1;
-               break;
-       case AY_BFINE:
-       case AY_BCOARSE:
-               PSG->Regs[AY_BCOARSE] &= 0x0F;
-               old = PSG->PeriodB;
-               PSG->PeriodB = (PSG->Regs[AY_BFINE] + 256 * PSG->Regs[AY_BCOARSE]) * PSG->UpdateStep;
-
-               if (PSG->PeriodB == 0)
-                       PSG->PeriodB = PSG->UpdateStep;
-
-               PSG->CountB += PSG->PeriodB - old;
-
-               if (PSG->CountB <= 0)
-                       PSG->CountB = 1;
-               break;
-       case AY_CFINE:
-       case AY_CCOARSE:
-               PSG->Regs[AY_CCOARSE] &= 0x0F;
-               old = PSG->PeriodC;
-               PSG->PeriodC = (PSG->Regs[AY_CFINE] + 256 * PSG->Regs[AY_CCOARSE]) * PSG->UpdateStep;
-
-               if (PSG->PeriodC == 0)
-                       PSG->PeriodC = PSG->UpdateStep;
-
-               PSG->CountC += PSG->PeriodC - old;
-
-               if (PSG->CountC <= 0)
-                       PSG->CountC = 1;
-               break;
-       case AY_NOISEPER:
-               PSG->Regs[AY_NOISEPER] &= 0x1F;
-               old = PSG->PeriodN;
-               PSG->PeriodN = PSG->Regs[AY_NOISEPER] * PSG->UpdateStep;
-
-               if (PSG->PeriodN == 0)
-                       PSG->PeriodN = PSG->UpdateStep;
-
-               PSG->CountN += PSG->PeriodN - old;
-
-               if (PSG->CountN <= 0)
-                       PSG->CountN = 1;
-               break;
-/*     case AY_ENABLE:
-               if ((PSG->lastEnable == -1) ||
-                   ((PSG->lastEnable & 0x40) != (PSG->Regs[AY_ENABLE] & 0x40)))
-               {
-                       // write out $FF if port set to input
-                       if (PSG->PortAwrite)
-                               (*PSG->PortAwrite)(0, (UINT8) ((PSG->Regs[AY_ENABLE] & 0x40) ? PSG->Regs[AY_PORTA] : 0xff));    // [TC: UINT8 cast]
-               }
-
-               if ((PSG->lastEnable == -1) ||
-                   ((PSG->lastEnable & 0x80) != (PSG->Regs[AY_ENABLE] & 0x80)))
-               {
-                       // write out $FF if port set to input
-                       if (PSG->PortBwrite)
-                               (*PSG->PortBwrite)(0, (UINT8) ((PSG->Regs[AY_ENABLE] & 0x80) ? PSG->Regs[AY_PORTB] : 0xff));    // [TC: UINT8 cast]
-               }
-
-               PSG->lastEnable = PSG->Regs[AY_ENABLE];
-               break;*/
-       case AY_AVOL:
-               PSG->Regs[AY_AVOL] &= 0x1F;
-               PSG->EnvelopeA = PSG->Regs[AY_AVOL] & 0x10;
-               PSG->VolA = (PSG->EnvelopeA ? PSG->VolE :
-                       (PSG->VolTable[PSG->Regs[AY_AVOL] ? PSG->Regs[AY_AVOL] * 2 + 1
-                               : 0]));
-               break;
-       case AY_BVOL:
-               PSG->Regs[AY_BVOL] &= 0x1F;
-               PSG->EnvelopeB = PSG->Regs[AY_BVOL] & 0x10;
-               PSG->VolB = (PSG->EnvelopeB ? PSG->VolE :
-                       (PSG->VolTable[PSG->Regs[AY_BVOL] ? PSG->Regs[AY_BVOL] * 2 + 1
-                               : 0]));
-               break;
-       case AY_CVOL:
-               PSG->Regs[AY_CVOL] &= 0x1F;
-               PSG->EnvelopeC = PSG->Regs[AY_CVOL] & 0x10;
-               PSG->VolC = (PSG->EnvelopeC ? PSG->VolE
-                       : (PSG->VolTable[PSG->Regs[AY_CVOL] ? PSG->Regs[AY_CVOL] * 2 + 1
-                               : 0]));
-               break;
-       case AY_EFINE:
-       case AY_ECOARSE:
-               old = PSG->PeriodE;
-               PSG->PeriodE = ((PSG->Regs[AY_EFINE] + 256 * PSG->Regs[AY_ECOARSE])) * PSG->UpdateStep;
-
-               if (PSG->PeriodE == 0)
-                       PSG->PeriodE = PSG->UpdateStep / 2;
-
-               PSG->CountE += PSG->PeriodE - old;
-
-               if (PSG->CountE <= 0)
-                       PSG->CountE = 1;
-               break;
-       case AY_ESHAPE:
-               /* envelope shapes:
-               C AtAlH
-               0 0 x x  \___
-
-               0 1 x x  /___
-
-               1 0 0 0  \\\\
-
-               1 0 0 1  \___
-
-               1 0 1 0  \/\/
-                         ___
-               1 0 1 1  \
-
-               1 1 0 0  ////
-                         ___
-               1 1 0 1  /
-
-               1 1 1 0  /\/\
-
-               1 1 1 1  /___
-
-               The envelope counter on the AY-3-8910 has 16 steps. On the YM2149 it
-               has twice the steps, happening twice as fast. Since the end result is
-               just a smoother curve, we always use the YM2149 behaviour.
-               */
-               PSG->Regs[AY_ESHAPE] &= 0x0F;
-               PSG->Attack = (PSG->Regs[AY_ESHAPE] & 0x04 ? 0x1F : 0x00);
-
-               if ((PSG->Regs[AY_ESHAPE] & 0x08) == 0)
-               {
-                       /* if Continue = 0, map the shape to the equivalent one which has Continue = 1 */
-                       PSG->Hold = 1;
-                       PSG->Alternate = PSG->Attack;
-               }
-               else
-               {
-                       PSG->Hold = PSG->Regs[AY_ESHAPE] & 0x01;
-                       PSG->Alternate = PSG->Regs[AY_ESHAPE] & 0x02;
-               }
-
-               PSG->CountE = PSG->PeriodE;
-               PSG->CountEnv = 0x1F;
-               PSG->Holding = 0;
-               PSG->VolE = PSG->VolTable[PSG->CountEnv ^ PSG->Attack];
-
-               if (PSG->EnvelopeA)
-                       PSG->VolA = PSG->VolE;
-
-               if (PSG->EnvelopeB)
-                       PSG->VolB = PSG->VolE;
-
-               if (PSG->EnvelopeC)
-                       PSG->VolC = PSG->VolE;
-               break;
-/*     case AY_PORTA:
-               if (PSG->Regs[AY_ENABLE] & 0x40)
-               {
-                       if (PSG->PortAwrite)
-                               (*PSG->PortAwrite)(0, PSG->Regs[AY_PORTA]);
-                       else
-                               logerror("PC %04x: warning - write %02x to 8910 #%d Port A\n",activecpu_get_pc(),PSG->Regs[AY_PORTA],n);
-               }
-               else
-               {
-                       logerror("warning: write to 8910 #%d Port A set as input - ignored\n",n);
-               }
-               break;
-       case AY_PORTB:
-               if (PSG->Regs[AY_ENABLE] & 0x80)
-               {
-                       if (PSG->PortBwrite)
-                               (*PSG->PortBwrite)(0, PSG->Regs[AY_PORTB]);
-                       else
-                               logerror("PC %04x: warning - write %02x to 8910 #%d Port B\n",activecpu_get_pc(),PSG->Regs[AY_PORTB],n);
-               }
-               else
-               {
-                       logerror("warning: write to 8910 #%d Port B set as input - ignored\n",n);
-               }
-               break;*/
-       }
-}
-
-
-//#define DEBUG_AY
-// /length/ is the number of samples we require
-void AY8910Update(int chip, int16_t ** buffer, int length)     // [TC: Removed static]
-{
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: chip=%d, buffer=%X, length=%d\n", chip, buffer, length);
-#endif
-       struct AY8910 * PSG = &AYPSG[chip];
-
-       int16_t * buf1 = buffer[0];
-       int16_t * buf2 = buffer[1];
-       int16_t * buf3 = buffer[2];
-
-       /* The 8910 has three outputs, each output is the mix of one of the three
-        * tone generators and of the (single) noise generator. The two are mixed
-        * BEFORE going into the DAC. The formula to mix each channel is:
-        * (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable).
-        * Note that this means that if both tone and noise are disabled, the
-        * output is 1, not 0, and can be modulated changing the volume.
-        *
-        * If the channels are disabled, set their output to 1, and increase the
-        * counter, if necessary, so they will not be inverted during this update.
-        * Setting the output to 1 is necessary because a disabled channel is
-        * locked into the ON state (see above); and it has no effect if the volume
-        * is 0. If the volume is 0, increase the counter, but don't touch the
-        * output.
-        */
-       // N.B.: The bits in AY_ENABLE (0-5) are all active LOW, which means if the
-       //       channel bit is set, it is DISABLED.  5-3 are noise, 2-0 tone.
-       if (PSG->Regs[AY_ENABLE] & 0x01)
-       {
-               if (PSG->CountA <= length * STEP)
-                       PSG->CountA += length * STEP;
-
-               PSG->OutputA = 1;
-       }
-       else if (PSG->Regs[AY_AVOL] == 0)
-       {
-               /* note that I do count += length, NOT count = length + 1. You might
-                * think it's the same since the volume is 0, but doing the latter
-                * could cause interferencies when the program is rapidly modulating
-                * the volume.
-                */
-               if (PSG->CountA <= length * STEP)
-                       PSG->CountA += length * STEP;
-       }
-
-       if (PSG->Regs[AY_ENABLE] & 0x02)
-       {
-               if (PSG->CountB <= length * STEP)
-                       PSG->CountB += length * STEP;
-
-               PSG->OutputB = 1;
-       }
-       else if (PSG->Regs[AY_BVOL] == 0)
-       {
-               if (PSG->CountB <= length * STEP)
-                       PSG->CountB += length * STEP;
-       }
-
-       if (PSG->Regs[AY_ENABLE] & 0x04)
-       {
-               if (PSG->CountC <= length * STEP)
-                       PSG->CountC += length * STEP;
-
-               PSG->OutputC = 1;
-       }
-       else if (PSG->Regs[AY_CVOL] == 0)
-       {
-               if (PSG->CountC <= length * STEP)
-                       PSG->CountC += length * STEP;
-       }
-
-       /* for the noise channel we must not touch OutputN - it's also not
-        * necessary since we use outn.                                                        */
-       if ((PSG->Regs[AY_ENABLE] & 0x38) == 0x38)      /* all off */
-               if (PSG->CountN <= length * STEP)
-                       PSG->CountN += length * STEP;
-
-       int outn = (PSG->OutputN | PSG->Regs[AY_ENABLE]);
-
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: Stepping into while (length)...\n");
-#endif
-       /* buffering loop */
-       while (length)
-       {
-               /* vola, volb and volc keep track of how long each square wave stays
-                * in the 1 position during the sample period.
-                */
-               int vola = 0, volb = 0, volc = 0;
-               int left = STEP;
-
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: Stepping into inner do loop... (length=%d)\n", length);
-#endif
-               do
-               {
-                       int nextevent = (PSG->CountN < left ? PSG->CountN : left);
-//Note: nextevent is 0 here when first initialized...
-//so let's try this:
-                       if (nextevent == 0)
-                               left = 0;
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: nextevent=$%X, left=$%X\n", nextevent, left);
-#endif
-
-                       if (outn & 0x08)
-                       {
-                               if (PSG->OutputA)
-                                       vola += PSG->CountA;
-
-                               PSG->CountA -= nextevent;
-                               /* PeriodA is the half period of the square wave. Here, in each
-                                * loop I add PeriodA twice, so that at the end of the loop the
-                                * square wave is in the same status (0 or 1) it was at the
-                                * start. vola is also incremented by PeriodA, since the wave
-                                * has been 1 exactly half of the time, regardless of the
-                                * initial position. If we exit the loop in the middle, OutputA
-                                * has to be inverted and vola incremented only if the exit
-                                * status of the square wave is 1.                                                      */
-                               while (PSG->CountA <= 0)
-                               {
-                                       PSG->CountA += PSG->PeriodA;
-
-                                       if (PSG->CountA > 0)
-                                       {
-                                               PSG->OutputA ^= 1;
-
-                                               if (PSG->OutputA)
-                                                       vola += PSG->PeriodA;
-
-                                               break;
-                                       }
-
-                                       PSG->CountA += PSG->PeriodA;
-                                       vola += PSG->PeriodA;
-                               }
-
-                               if (PSG->OutputA)
-                                       vola -= PSG->CountA;
-                       }
-                       else
-                       {
-                               PSG->CountA -= nextevent;
-
-                               while (PSG->CountA <= 0)
-                               {
-                                       PSG->CountA += PSG->PeriodA;
-
-                                       if (PSG->CountA > 0)
-                                       {
-                                               PSG->OutputA ^= 1;
-                                               break;
-                                       }
-
-                                       PSG->CountA += PSG->PeriodA;
-                               }
-                       }
-
-                       if (outn & 0x10)
-                       {
-                               if (PSG->OutputB)
-                                       volb += PSG->CountB;
-
-                               PSG->CountB -= nextevent;
-
-                               while (PSG->CountB <= 0)
-                               {
-                                       PSG->CountB += PSG->PeriodB;
-
-                                       if (PSG->CountB > 0)
-                                       {
-                                               PSG->OutputB ^= 1;
-
-                                               if (PSG->OutputB)
-                                                       volb += PSG->PeriodB;
-                                               break;
-                                       }
-
-                                       PSG->CountB += PSG->PeriodB;
-                                       volb += PSG->PeriodB;
-                               }
-
-                               if (PSG->OutputB)
-                                       volb -= PSG->CountB;
-                       }
-                       else
-                       {
-                               PSG->CountB -= nextevent;
-
-                               while (PSG->CountB <= 0)
-                               {
-                                       PSG->CountB += PSG->PeriodB;
-
-                                       if (PSG->CountB > 0)
-                                       {
-                                               PSG->OutputB ^= 1;
-                                               break;
-                                       }
-
-                                       PSG->CountB += PSG->PeriodB;
-                               }
-                       }
-
-                       if (outn & 0x20)
-                       {
-                               if (PSG->OutputC)
-                                       volc += PSG->CountC;
-
-                               PSG->CountC -= nextevent;
-
-                               while (PSG->CountC <= 0)
-                               {
-                                       PSG->CountC += PSG->PeriodC;
-
-                                       if (PSG->CountC > 0)
-                                       {
-                                               PSG->OutputC ^= 1;
-
-                                               if (PSG->OutputC)
-                                                       volc += PSG->PeriodC;
-                                               break;
-                                       }
-
-                                       PSG->CountC += PSG->PeriodC;
-                                       volc += PSG->PeriodC;
-                               }
-
-                               if (PSG->OutputC)
-                                       volc -= PSG->CountC;
-                       }
-                       else
-                       {
-                               PSG->CountC -= nextevent;
-
-                               while (PSG->CountC <= 0)
-                               {
-                                       PSG->CountC += PSG->PeriodC;
-
-                                       if (PSG->CountC > 0)
-                                       {
-                                               PSG->OutputC ^= 1;
-                                               break;
-                                       }
-
-                                       PSG->CountC += PSG->PeriodC;
-                               }
-                       }
-
-                       PSG->CountN -= nextevent;
-
-                       if (PSG->CountN <= 0)
-                       {
-                               /* Is noise output going to change? */
-                               if ((PSG->RNG + 1) & 0x00002)   // (bit0 XOR bit1) == 1?
-                               {
-                                       PSG->OutputN = ~PSG->OutputN;
-                                       outn = (PSG->OutputN | PSG->Regs[AY_ENABLE]);
-                               }
-
-                               /* The Random Number Generator of the 8910 is a 17-bit shift
-                                * register. The input to the shift register is bit0 XOR bit3
-                                * (bit0 is the output). This was verified on AY-3-8910 and
-                                * YM2149 chips.
-                                *
-                                * The following is a fast way to compute bit17 = bit0^bit3.
-                                * Instead of doing all the logic operations, we only check
-                                * bit0, relying on the fact that after three shifts of the
-                                * register, what now is bit3 will become bit0, and will
-                                * invert, if necessary, bit14, which previously was bit17.   */
-                               if (PSG->RNG & 0x00001)
-                                       PSG->RNG ^= 0x24000; /* This version is called the "Galois configuration". */
-
-                               PSG->RNG >>= 1;
-                               PSG->CountN += PSG->PeriodN;
-                       }
-
-                       left -= nextevent;
-               }
-               while (left > 0);
-
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: About to update envelope...\n");
-#endif
-               /* update envelope */
-               if (PSG->Holding == 0)
-               {
-                       PSG->CountE -= STEP;
-
-                       if (PSG->CountE <= 0)
-                       {
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: About to enter do loop... (CountEnv = $%X, CountE =$%X, PeriodE = $%X)\n", PSG->CountEnv, PSG->CountE, PSG->PeriodE);
-#endif
-                               // JLH: Sanity check...
-                               if (PSG->PeriodE > 0)
-                               {
-                                       do
-                                       {
-                                               PSG->CountEnv--;
-                                               PSG->CountE += PSG->PeriodE;
-                                       }
-                                       while (PSG->CountE <= 0);
-                               }
-
-                               /* check envelope current position */
-                               if (PSG->CountEnv < 0)
-                               {
-                                       if (PSG->Hold)
-                                       {
-                                               if (PSG->Alternate)
-                                                       PSG->Attack ^= 0x1F;
-
-                                               PSG->Holding = 1;
-                                               PSG->CountEnv = 0;
-                                       }
-                                       else
-                                       {
-                                               /* if CountEnv has looped an odd number of times
-                                                * (usually 1), invert the output.                                         */
-                                               if (PSG->Alternate && (PSG->CountEnv & 0x20))
-                                                       PSG->Attack ^= 0x1F;
-
-                                               PSG->CountEnv &= 0x1F;
-                                       }
-                               }
-
-                               PSG->VolE = PSG->VolTable[PSG->CountEnv ^ PSG->Attack];
-
-                               /* reload volume */
-                               if (PSG->EnvelopeA)
-                                       PSG->VolA = PSG->VolE;
-
-                               if (PSG->EnvelopeB)
-                                       PSG->VolB = PSG->VolE;
-
-                               if (PSG->EnvelopeC)
-                                       PSG->VolC = PSG->VolE;
-                       }
-               }
-
-#if 1
-               *(buf1++) = (vola * PSG->VolA) / STEP;
-               *(buf2++) = (volb * PSG->VolB) / STEP;
-               *(buf3++) = (volc * PSG->VolC) / STEP;
-#else  // [Tom's code...]
-               // Output PCM wave [-32768...32767] instead of MAME's voltage level [0...32767]
-               // - This allows for better s/w mixing
-
-               if (PSG->VolA)
-               {
-                       if (vola)
-                               *(buf1++) = (vola * PSG->VolA) / STEP;
-                       else
-                               *(buf1++) = -(int)PSG->VolA;
-               }
-               else
-                       *(buf1++) = 0;
-
-               if (PSG->VolB)
-               {
-                       if (volb)
-                               *(buf2++) = (volb * PSG->VolB) / STEP;
-                       else
-                               *(buf2++) = -(int)PSG->VolB;
-               }
-               else
-                       *(buf2++) = 0;
-
-               if (PSG->VolC)
-               {
-                       if (volc)
-                               *(buf3++) = (volc * PSG->VolC) / STEP;
-                       else
-                               *(buf3++) = -(int)PSG->VolC;
-               }
-               else
-                       *(buf3++) = 0;
-#endif
-               length--;
-       }
-#ifdef DEBUG_AY
-WriteLog("AY8910Update: Done.\n");
-#endif
-}
-
-
-static void AY8910_set_clock(int chip, int clock)
-{
-//     struct AY8910 * PSG = &AYPSG[chip];
-
-       /* The step clock for the tone and noise generators is the chip clock
-        * divided by 8; for the envelope generator of the AY-3-8910, it is half
-        * that much (clock/16), but the envelope of the YM2149 goes twice as
-        * fast, therefore again clock/8.
-        * Here we calculate the number of steps which happen during one sample
-        * at the given sample rate. No. of events = sample rate / (clock/8).
-        * STEP is a multiplier used to turn the fraction into a fixed point
-        * number.
-        */
-       AYPSG[chip].UpdateStep = (unsigned int)(((double)STEP * AYPSG[chip].SampleRate * 8 + clock / 2) / clock);       // [TC: unsigned int cast]
-}
-
-
-static void build_mixer_table(int chip)
-{
-       /* calculate the volume->voltage conversion table
-        * The AY-3-8910 has 16 levels, in a logarithmic scale (3dB per step)
-        * The YM2149 still has 16 levels for the tone generators, but 32 for
-        * the envelope generator (1.5dB per step).
-        */
-       double out = MAX_OUTPUT;
-
-       for(int i=31; i>0; i--)
-       {
-               AYPSG[chip].VolTable[i] = (unsigned int)(out + 0.5);    /* round to nearest */  // [TC: unsigned int cast]
-               out /= 1.188502227;     /* = 10 ^ (1.5/20) = 1.5dB */
-       }
-
-       AYPSG[chip].VolTable[0] = 0;
-}
-
-
-void AY8910_reset(int chip)
-{
-       AYPSG[chip].register_latch = 0;
-       AYPSG[chip].RNG = 1;
-       AYPSG[chip].OutputA = 0;
-       AYPSG[chip].OutputB = 0;
-       AYPSG[chip].OutputC = 0;
-       AYPSG[chip].OutputN = 0xFF;
-
-       for(int i=0; i<=AY_ESHAPE; i++)
-               _AYWriteReg(chip, i, 0);        /* AYWriteReg() uses the timer system; we
-                                                                        * cannot call it at this time because the
-                                                                        * timer system has not been initialized.                     */
-}
-
-// This stuff looks like Tom's code, so let's streamline and un-MSHungarianize this shit:
-// [DONE]
-// N.B.: Looks like 'clock' is the 65C02 clock rate, and 'sampleRate' is the
-//       sample rate set by the audio subsystem.
-
-void AY8910_InitAll(int clock, int sampleRate)
-{
-       for(int chip=0; chip<MAX_8910; chip++)
-       {
-               memset(&AYPSG[chip], 0, sizeof(struct AY8910));
-               AYPSG[chip].SampleRate = sampleRate;
-               AY8910_set_clock(chip, clock);
-               build_mixer_table(chip);
-       }
-}
-
-
-void AY8910_InitClock(int clock)
-{
-       for(int chip=0; chip<MAX_8910; chip++)
-               AY8910_set_clock(chip, clock);
-}
-#endif
-
diff --git a/src/ay8910.h b/src/ay8910.h
deleted file mode 100644 (file)
index 639a567..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef AY8910_H
-#define AY8910_H
-
-#include <stdint.h>
-
-#define USE_NEW_AY8910
-
-#define MAX_8910 4
-
-#ifndef USE_NEW_AY8910
-void _AYWriteReg(int n, int r, int v);
-void AY8910_reset(int chip);
-void AY8910Update(int chip, int16_t ** buffer, int length);
-
-void AY8910_InitAll(int clock, int sampleRate);
-void AY8910_InitClock(int clock);
-#else
-
-// Exported functions
-void AYInit(void);
-void AYReset(int chipNum);
-void AYWrite(int chipNum, int reg, int value);
-uint16_t AYGetSample(int chipNum);
-
-// Exported variables
-extern bool logAYInternal;
-extern float maxVolume;
-#endif
-
-#endif
-
index 6e59b6af873c22a6e857b6ee4be1ca88504925fa..478f00cfa700f0e6a642b2105d985b07ee16b535 100644 (file)
@@ -340,523 +340,3 @@ uint8_t textChar2e[0x3800] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-#if 0
-char textChar[0x7000] = {
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
-       0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
-       0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
-       0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-       0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
-       0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-#endif
index 8c263701cd62efc1e3be2475ba26e60d290f4a1e..0e8cb895ed6ea444547c8d30c4c2284a5df01330 100644 (file)
@@ -1,14 +1,10 @@
 //
 // CRC32 support
 //
-// by David Raingeard & James Hammons
+// by James Hammons
 // (C) 2010-2018 Underground Software
 //
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// Who  When        What
-// ---  ----------  -----------------------------------------------------------
-// JLH  01/16/2010  Created this log ;-)
+// Based on the original 1986 implementation by Gary S. Brown
 //
 
 #include "crc32.h"
@@ -51,13 +47,13 @@ static uint32_t crcTable[256] =
 };
 
 
-uint32_t CRC32(uint8_t * data, uint32_t length)
+uint32_t CRC32(const uint8_t * data, uint32_t length)
 {
        uint32_t crc = 0xFFFFFFFF;
 
        for(uint32_t i=0; i<length; i++)
                crc = crcTable[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
 
-       return crc ^ 0xFFFFFFFF;
+       return ~crc;
 }
 
index 18218479bf4124ddd735d59433d7c93ca26a75db..f390ee9cca1ae4d6818f79f59eec5744de1514be 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-uint32_t CRC32(uint8_t * data, uint32_t length);
+uint32_t CRC32(const uint8_t * data, uint32_t length);
 
 #endif // __CRC32_H__
 
diff --git a/src/floppy.cpp b/src/floppy.cpp
deleted file mode 100644 (file)
index 859db6d..0000000
+++ /dev/null
@@ -1,872 +0,0 @@
-//
-// Apple 2 floppy disk support
-//
-// by James Hammons
-// (c) 2005 Underground Software
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO  WHEN        WHAT
-// ---  ----------  -----------------------------------------------------------
-// JLH  12/03/2005  Created this file
-// JLH  12/15/2005  Fixed nybblization functions to work properly
-// JLH  12/27/2005  Added blank disk creation, fixed saving to work properly
-//
-
-#include "floppy.h"
-
-#include <stdio.h>
-#include <string.h>
-#include "apple2.h"
-#include "log.h"
-#include "video.h"             // For message spawning... Though there's probably a
-                                               // better approach than this!
-
-// Useful enums
-
-enum { IO_MODE_READ, IO_MODE_WRITE };
-
-// FloppyDrive class variable initialization
-
-uint8_t FloppyDrive::header[21] = {
-       0xD5, 0xAA, 0x96, 0xFF, 0xFE, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xDE, 0xAA, 0xFF,     0xFF, 0xFF,
-       0xFF, 0xFF, 0xD5, 0xAA, 0xAD };
-uint8_t FloppyDrive::doSector[16] = {
-       0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF };
-uint8_t FloppyDrive::poSector[16] = {
-       0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF };
-char FloppyDrive::nameBuf[MAX_PATH];
-
-
-// FloppyDrive class implementation...
-
-FloppyDrive::FloppyDrive(): motorOn(0), activeDrive(0), ioMode(IO_MODE_READ), phase(0), track(0), ioHappened(false)
-{
-       disk[0] = disk[1] = NULL;
-       diskSize[0] = diskSize[1] = 0;
-       diskType[0] = diskType[1] = DFT_UNKNOWN;
-       imageDirty[0] = imageDirty[1] = false;
-       writeProtected[0] = writeProtected[1] = false;
-       imageName[0][0] = imageName[1][0] = 0;                  // Zero out filenames
-}
-
-
-FloppyDrive::~FloppyDrive()
-{
-       if (disk[0])
-               delete[] disk[0];
-
-       if (disk[1])
-               delete[] disk[1];
-}
-
-
-bool FloppyDrive::LoadImage(const char * filename, uint8_t driveNum/*= 0*/)
-{
-       WriteLog("FLOPPY: Attempting to load image '%s' in drive #%u.\n", filename, driveNum);
-
-       if (driveNum > 1)
-       {
-               WriteLog("FLOPPY: Attempted to load image to drive #%u!\n", driveNum);
-               return false;
-       }
-
-       imageName[driveNum][0] = 0;                                     // Zero out filename, in case it doesn't load
-
-       FILE * fp = fopen(filename, "rb");
-
-       if (fp == NULL)
-       {
-               WriteLog("FLOPPY: Failed to open image file '%s' for reading...\n", filename);
-               return false;
-       }
-
-       if (disk[driveNum])
-               delete[] disk[driveNum];
-
-       fseek(fp, 0, SEEK_END);
-       diskSize[driveNum] = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
-       disk[driveNum] =  new uint8_t[diskSize[driveNum]];
-       fread(disk[driveNum], 1, diskSize[driveNum], fp);
-
-       fclose(fp);
-//printf("Read disk image: %u bytes.\n", diskSize);
-       DetectImageType(filename, driveNum);
-       strcpy(imageName[driveNum], filename);
-
-#if 0
-       WriteLog("FLOPPY: Opening image for drive #%u.\n", driveNum);
-       FILE * fp2 = fopen("bt-nybblized.nyb", "wb");
-
-       if (fp2 == NULL)
-               WriteLog("FLOPPY: Failed to open image file 'bt-nybblized.nyb' for writing...\n");
-       else
-       {
-               fwrite(nybblizedImage[driveNum], 1, 232960, fp2);
-               fclose(fp2);
-       }
-#endif
-//writeProtected[driveNum] = true;
-       WriteLog("FLOPPY: Loaded image '%s' for drive #%u.\n", filename, driveNum);
-
-       return true;
-}
-
-
-bool FloppyDrive::SaveImage(uint8_t driveNum/*= 0*/)
-{
-       // Various sanity checks...
-       if (driveNum > 1)
-       {
-               WriteLog("FLOPPY: Attempted to save image to drive #%u!\n", driveNum);
-               return false;
-       }
-
-       if (!imageDirty[driveNum])
-       {
-               WriteLog("FLOPPY: No need to save unchanged image...\n");
-               return false;
-       }
-
-       if (imageName[driveNum][0] == 0)
-       {
-               WriteLog("FLOPPY: Attempted to save non-existant image!\n");
-               return false;
-       }
-
-       // Handle nybbylization, if necessary
-       if (diskType[driveNum] == DT_NYBBLE)
-               memcpy(disk[driveNum], nybblizedImage[driveNum], 232960);
-       else
-               DenybblizeImage(driveNum);
-
-       // Finally, write the damn image
-       FILE * fp = fopen(imageName[driveNum], "wb");
-
-       if (fp == NULL)
-       {
-               WriteLog("FLOPPY: Failed to open image file '%s' for writing...\n", imageName[driveNum]);
-               return false;
-       }
-
-       fwrite(disk[driveNum], 1, diskSize[driveNum], fp);
-       fclose(fp);
-
-       WriteLog("FLOPPY: Successfully wrote image file '%s'...\n", imageName[driveNum]);
-
-       return true;
-}
-
-
-bool FloppyDrive::SaveImageAs(const char * filename, uint8_t driveNum/*= 0*/)
-{
-//WARNING: Buffer overflow possibility
-#warning "Buffer overflow possible--!!! FIX !!!"
-       strcpy(imageName[driveNum], filename);
-       return SaveImage(driveNum);
-}
-
-
-void FloppyDrive::CreateBlankImage(uint8_t driveNum/*= 0*/)
-{
-       if (disk[driveNum] != NULL)
-               delete disk[driveNum];
-
-       disk[driveNum] = new uint8_t[143360];
-       diskSize[driveNum] = 143360;
-       memset(disk[driveNum], 0x00, 143360);
-       memset(nybblizedImage[driveNum], 0x00, 232960); // Set it to 0 instead of $FF for proper formatting...
-       diskType[driveNum] = DT_DOS33;
-       strcpy(imageName[driveNum], "newblank.dsk");
-       writeProtected[driveNum] = false;
-SpawnMessage("New blank image inserted in drive %u...", driveNum);
-}
-
-
-void FloppyDrive::SwapImages(void)
-{
-       uint8_t nybblizedImageTmp[232960];
-       char imageNameTmp[MAX_PATH];
-
-       memcpy(nybblizedImageTmp, nybblizedImage[0], 232960);
-       memcpy(nybblizedImage[0], nybblizedImage[1], 232960);
-       memcpy(nybblizedImage[1], nybblizedImageTmp, 232960);
-
-       memcpy(imageNameTmp, imageName[0], MAX_PATH);
-       memcpy(imageName[0], imageName[1], MAX_PATH);
-       memcpy(imageName[1], imageNameTmp, MAX_PATH);
-
-       uint8_t * diskTmp = disk[0];
-       disk[0] = disk[1];
-       disk[1] = diskTmp;
-
-       uint32_t diskSizeTmp = diskSize[0];
-       diskSize[0] = diskSize[1];
-       diskSize[1] = diskSizeTmp;
-
-       uint8_t diskTypeTmp = diskType[0];
-       diskType[0] = diskType[1];
-       diskType[1] = diskTypeTmp;
-
-       uint8_t imageDirtyTmp = imageDirty[0];
-       imageDirty[0] = imageDirty[1];
-       imageDirty[1] = imageDirtyTmp;
-
-       uint8_t writeProtectedTmp = writeProtected[0];
-       writeProtected[0] = writeProtected[1];
-       writeProtected[1] = writeProtectedTmp;
-SpawnMessage("Drive 0: %s...", imageName[0]);
-}
-
-
-void FloppyDrive::DetectImageType(const char * filename, uint8_t driveNum)
-{
-       diskType[driveNum] = DFT_UNKNOWN;
-
-       if (diskSize[driveNum] == 232960)
-       {
-               diskType[driveNum] = DT_NYBBLE;
-               memcpy(nybblizedImage[driveNum], disk[driveNum], 232960);
-       }
-       else if (diskSize[driveNum] == 143360)
-       {
-               const char * ext = strrchr(filename, '.');
-
-               if (ext == NULL)
-                       return;
-WriteLog("FLOPPY: Found extension [%s]...\n", ext);
-
-//Apparently .dsk can house either DOS order OR PRODOS order... !!! FIX !!!
-               if (strcasecmp(ext, ".po") == 0)
-                       diskType[driveNum] = DT_PRODOS;
-               else if ((strcasecmp(ext, ".do") == 0) || (strcasecmp(ext, ".dsk") == 0))
-               {
-                       // We assume this, but check for a PRODOS fingerprint. Trust, but
-                       // verify. ;-)
-                       diskType[driveNum] = DT_DOS33;
-
-                       uint8_t fingerprint[4][4] = {
-                               { 0x00, 0x00, 0x03, 0x00 },             // @ $400
-                               { 0x02, 0x00, 0x04, 0x00 },             // @ $600
-                               { 0x03, 0x00, 0x05, 0x00 },             // @ $800
-                               { 0x04, 0x00, 0x00, 0x00 }              // @ $A00
-                       };
-
-                       bool foundProdos = true;
-
-                       for(uint32_t i=0; i<4; i++)
-                       {
-                               for(uint32_t j=0; j<4; j++)
-                               {
-                                       if (disk[driveNum][0x400 + (i * 0x200) + j] != fingerprint[i][j])
-                                       {
-                                               foundProdos = false;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if (foundProdos)
-                               diskType[driveNum] = DT_PRODOS;
-               }
-
-// Actually, it just might matter WRT to nybblyzing/denybblyzing
-// (and, it does... :-P)
-               NybblizeImage(driveNum);
-       }
-       else if (diskSize[driveNum] == 143488)
-       {
-               diskType[driveNum] = DT_DOS33_HDR;
-               NybblizeImage(driveNum);
-       }
-
-#warning "Should we attempt to nybblize unknown images here? Definitely SHOULD issue a warning!"
-
-WriteLog("FLOPPY: Detected image type %s...\n", (diskType[driveNum] == DT_NYBBLE ?
-       "Nybble image" : (diskType[driveNum] == DT_DOS33 ?
-       "DOS 3.3 image" : (diskType[driveNum] == DT_DOS33_HDR ?
-       "DOS 3.3 image (headered)" : (diskType[driveNum] == DT_PRODOS ? "ProDOS image" : "unknown")))));
-}
-
-
-void FloppyDrive::NybblizeImage(uint8_t driveNum)
-{
-       // Format of a sector is header (23) + nybbles (343) + footer (30) = 396
-       // (short by 20 bytes of 416 [413 if 48 byte header is one time only])
-// Hmph. Who'da thunk that AppleWin's nybblization routines would be wrong?
-// This is now correct, BTW
-       // hdr (21) + nybbles (343) + footer (48) = 412 bytes per sector
-       // (not incl. 64 byte track marker)
-
-       uint8_t footer[48] = {
-               0xDE, 0xAA, 0xEB, 0xFF, 0xEB, 0xFF, 0xFF, 0xFF,
-               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-
-       uint8_t diskbyte[0x40] = {
-               0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6,
-               0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
-               0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC,
-               0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3,
-               0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE,
-               0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC,
-               0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
-               0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
-
-       uint8_t * img = nybblizedImage[driveNum];
-       memset(img, 0xFF, 232960);                                      // Doesn't matter if 00s or FFs...
-
-       for(uint8_t trk=0; trk<35; trk++)
-       {
-               memset(img, 0xFF, 64);                                  // Write gap 1, 64 bytes (self-sync)
-               img += 64;
-
-               for(uint8_t sector=0; sector<16; sector++)
-               {
-                       memcpy(img, header, 21);                        // Set up the sector header
-
-                       img[5] = ((trk >> 1) & 0x55) | 0xAA;
-                       img[6] =  (trk       & 0x55) | 0xAA;
-                       img[7] = ((sector >> 1) & 0x55) | 0xAA;
-                       img[8] =  (sector       & 0x55) | 0xAA;
-                       img[9] = (((trk ^ sector ^ 0xFE) >> 1) & 0x55) | 0xAA;
-                       img[10] = ((trk ^ sector ^ 0xFE)       & 0x55) | 0xAA;
-
-                       img += 21;
-                       uint8_t * bytes = disk[driveNum];
-
-                       if (diskType[driveNum] == DT_DOS33)
-                               bytes += (doSector[sector] * 256) + (trk * 256 * 16);
-                       else if (diskType[driveNum] == DT_DOS33_HDR)
-                               bytes += (doSector[sector] * 256) + (trk * 256 * 16) + 128;
-                       else if (diskType[driveNum] == DT_PRODOS)
-                               bytes += (poSector[sector] * 256) + (trk * 256 * 16);
-                       else
-                               bytes += (sector * 256) + (trk * 256 * 16);
-
-                       // Convert the 256 8-bit bytes into 342 6-bit bytes.
-
-                       for(uint16_t i=0; i<0x56; i++)
-                       {
-                               img[i] = ((bytes[(i + 0xAC) & 0xFF] & 0x01) << 7)
-                                       | ((bytes[(i + 0xAC) & 0xFF] & 0x02) << 5)
-                                       | ((bytes[(i + 0x56) & 0xFF] & 0x01) << 5)
-                                       | ((bytes[(i + 0x56) & 0xFF] & 0x02) << 3)
-                                       | ((bytes[(i + 0x00) & 0xFF] & 0x01) << 3)
-                                       | ((bytes[(i + 0x00) & 0xFF] & 0x02) << 1);
-                       }
-
-                       img[0x54] &= 0x3F;
-                       img[0x55] &= 0x3F;
-                       memcpy(img + 0x56, bytes, 256);
-
-                       // XOR the data block with itself, offset by one byte,
-                       // creating a 343rd byte which is used as a cheksum.
-
-                       img[342] = 0x00;
-
-                       for(uint16_t i=342; i>0; i--)
-                               img[i] = img[i] ^ img[i - 1];
-
-                       // Using a lookup table, convert the 6-bit bytes into disk bytes.
-
-                       for(uint16_t i=0; i<343; i++)
-//#define TEST_NYBBLIZATION
-#ifdef TEST_NYBBLIZATION
-{
-WriteLog("FL: i = %u, img[i] = %02X, diskbyte = %02X\n", i, img[i], diskbyte[img[i] >> 2]);
-#endif
-                               img[i] = diskbyte[img[i] >> 2];
-#ifdef TEST_NYBBLIZATION
-//WriteLog("            img[i] = %02X\n", img[i]);
-}
-#endif
-                       img += 343;
-
-                       // Done with the nybblization, now for the epilogue...
-
-                       memcpy(img, footer, 48);
-                       img += 48;
-               }
-       }
-}
-
-
-void FloppyDrive::DenybblizeImage(uint8_t driveNum)
-{
-       uint8_t decodeNybble[0x80] = {
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-               0x00, 0x00, 0x08, 0x0C, 0x00, 0x10, 0x14, 0x18,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20,
-               0x00, 0x00, 0x00, 0x24, 0x28, 0x2C, 0x30, 0x34,
-               0x00, 0x00, 0x38, 0x3C, 0x40, 0x44, 0x48, 0x4C,
-               0x00, 0x50, 0x54, 0x58, 0x5C, 0x60, 0x64, 0x68,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-               0x00, 0x00, 0x00, 0x6C, 0x00, 0x70, 0x74, 0x78,
-               0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x80, 0x84,
-               0x00, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9C, 0xA0,
-               0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xA8, 0xAC,
-               0x00, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC4, 0xC8,
-               0x00, 0x00, 0xCC, 0xD0, 0xD4, 0xD8, 0xDC, 0xE0,
-               0x00, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4, 0xF8, 0xFC };
-
-       // Sanity checks...
-       if (disk[driveNum] == NULL || diskSize[driveNum] < 143360)
-       {
-               WriteLog("FLOPPY: Source disk image invalid! [drive=%u, disk=%08X, diskSize=%u]\n",
-                       driveNum, disk[driveNum], diskSize[driveNum]);
-               return;
-       }
-
-       uint8_t * srcImg = nybblizedImage[driveNum];
-       uint8_t * dstImg = disk[driveNum];
-       uint8_t buffer[345];                                                    // 2 extra bytes for the unpack routine below...
-
-       for(uint8_t trk=0; trk<35; trk++)
-       {
-               uint8_t * trackBase = srcImg + (trk * 6656);
-
-               for(uint8_t sector=0; sector<16; sector++)
-               {
-                       uint16_t sectorStart = (uint16_t)-1;
-
-                       for(uint16_t i=0; i<6656; i++)
-                       {
-                               if (trackBase[i] == header[0]
-                                       && trackBase[(i + 1) % 6656] == header[1]
-                                       && trackBase[(i + 2) % 6656] == header[2]
-                                       && trackBase[(i + 3) % 6656] == header[3]
-                                       && trackBase[(i + 4) % 6656] == header[4])
-                               {
-//Could also check the track # at +5,6...
-                                       uint8_t foundSector = ((trackBase[(i + 7) % 6656] & 0x55) << 1)
-                                               | (trackBase[(i + 8) % 6656] & 0x55);
-
-                                       if (foundSector == sector)
-                                       {
-                                               sectorStart = (i + 21) % 6656;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       // Sanity check...
-                       if (sectorStart == (uint16_t)-1)
-                       {
-                               WriteLog("FLOPPY: Failed to find sector %u (track %u) in nybble image!\n",
-                                       sector, trk);
-                               return;
-                       }
-
-                       // Using a lookup table, convert the disk bytes into 6-bit bytes.
-
-                       for(uint16_t i=0; i<343; i++)
-                               buffer[i] = decodeNybble[trackBase[(sectorStart + i) % 6656] & 0x7F];
-
-                       // XOR the data block with itself, offset by one byte.
-
-                       for(uint16_t i=1; i<342; i++)
-                               buffer[i] = buffer[i] ^ buffer[i - 1];
-
-                       // Convert the 342 6-bit bytes into 256 8-bit bytes (at buffer + $56).
-
-                       for(uint16_t i=0; i<0x56; i++)
-                       {
-                               buffer[0x056 + i] |= ((buffer[i] >> 3) & 0x01) | ((buffer[i] >> 1) & 0x02);
-                               buffer[0x0AC + i] |= ((buffer[i] >> 5) & 0x01) | ((buffer[i] >> 3) & 0x02);
-                               buffer[0x102 + i] |= ((buffer[i] >> 7) & 0x01) | ((buffer[i] >> 5) & 0x02);
-                       }
-
-                       uint8_t * bytes = dstImg;
-
-                       if (diskType[driveNum] == DT_DOS33)
-                               bytes += (doSector[sector] * 256) + (trk * 256 * 16);
-                       else if (diskType[driveNum] == DT_DOS33_HDR)
-                               bytes += (doSector[sector] * 256) + (trk * 256 * 16) + 128;
-                       else if (diskType[driveNum] == DT_PRODOS)
-                               bytes += (poSector[sector] * 256) + (trk * 256 * 16);
-                       else
-                               bytes += (sector * 256) + (trk * 256 * 16);//*/
-
-                       memcpy(bytes, buffer + 0x56, 256);
-               }
-       }
-}
-
-
-const char * FloppyDrive::ImageName(uint8_t driveNum/*= 0*/)
-{
-       // Set up a zero-length string for return value
-       nameBuf[0] = 0;
-
-       if (driveNum > 1)
-       {
-               WriteLog("FLOPPY: Attempted to get image name for drive #%u!\n", driveNum);
-               return nameBuf;
-       }
-
-       // Now we attempt to strip out extraneous paths/extensions to get just the filename
-       const char * startOfFile = strrchr(imageName[driveNum], '/');
-       const char * startOfExt = strrchr(imageName[driveNum], '.');
-
-       // If there isn't a path, assume we're starting at the beginning
-       if (startOfFile == NULL)
-               startOfFile = &imageName[driveNum][0];
-       else
-               startOfFile++;
-
-       // If there isn't an extension, assume it's at the terminating NULL
-       if (startOfExt == NULL)
-               startOfExt = &imageName[driveNum][0] + strlen(imageName[driveNum]);
-
-       // Now copy the filename (may copy nothing!)
-       int j = 0;
-
-       for(const char * i=startOfFile; i<startOfExt; i++)
-               nameBuf[j++] = *i;
-
-       nameBuf[j] = 0;
-
-       return nameBuf;
-}
-
-
-void FloppyDrive::EjectImage(uint8_t driveNum/*= 0*/)
-{
-       // Sanity check
-       if (IsEmpty(driveNum))
-               return;
-
-       // Probably want to save a dirty image... ;-)
-       if (SaveImage(driveNum))
-               WriteLog("FLOPPY: Ejected image file '%s' from drive %u...\n", imageName[driveNum], driveNum);
-
-       if (disk[driveNum])
-               delete[] disk[driveNum];
-
-       disk[driveNum] = NULL;
-       diskSize[driveNum] = 0;
-       diskType[driveNum] = DFT_UNKNOWN;
-       imageDirty[driveNum] = false;
-       writeProtected[driveNum] = false;
-       imageName[driveNum][0] = 0;                     // Zero out filenames
-       memset(nybblizedImage[driveNum], 0xFF, 232960); // Doesn't matter if 00s or FFs...
-}
-
-
-bool FloppyDrive::IsEmpty(uint8_t driveNum/*= 0*/)
-{
-       if (driveNum > 1)
-       {
-               WriteLog("FLOPPY: Attempted DriveIsEmtpy() for drive #%u!\n", driveNum);
-               return true;
-       }
-
-       // This is kinda gay, but it works
-       return (imageName[driveNum][0] == 0 ? true : false);
-}
-
-
-bool FloppyDrive::IsWriteProtected(uint8_t driveNum/*= 0*/)
-{
-       if (driveNum > 1)
-       {
-               WriteLog("FLOPPY: Attempted DiskIsWriteProtected() for drive #%u!\n", driveNum);
-               return true;
-       }
-
-       return writeProtected[driveNum];
-}
-
-
-void FloppyDrive::SetWriteProtect(bool state, uint8_t driveNum/*= 0*/)
-{
-       if (driveNum > 1)
-       {
-               WriteLog("FLOPPY: Attempted set write protect for drive #%u!\n", driveNum);
-               return;
-       }
-
-       writeProtected[driveNum] = state;
-}
-
-
-int FloppyDrive::DriveLightStatus(uint8_t driveNum/*= 0*/)
-{
-       int retval = DLS_OFF;
-
-       if (activeDrive != driveNum)
-               return DLS_OFF;
-
-       if (ioHappened)
-               retval = (ioMode == IO_MODE_READ ? DLS_READ : DLS_WRITE);
-
-       ioHappened = false;
-       return retval;
-}
-
-
-void FloppyDrive::SaveState(FILE * file)
-{
-       // Internal state vars
-       fputc(motorOn, file);
-       fputc(activeDrive, file);
-       fputc(ioMode, file);
-       fputc(latchValue, file);
-       fputc(phase, file);
-       fputc(track, file);
-       fputc((ioHappened ? 1 : 0), file);
-       WriteLong(file, currentPos);
-
-       // Disk #1
-       if (disk[0] != NULL)
-       {
-               WriteLong(file, diskSize[0]);
-               WriteLong(file, diskType[0]);
-               fputc((imageDirty[0] ? 1 : 0), file);
-               fputc((writeProtected[0] ? 1 : 0), file);
-               fwrite(nybblizedImage[0], 1, 232960, file);
-               fwrite(imageName[0], 1, MAX_PATH, file);
-       }
-       else
-               WriteLong(file, 0);
-
-       // Disk #2
-       if (disk[1] != NULL)
-       {
-               WriteLong(file, diskSize[1]);
-               WriteLong(file, diskType[1]);
-               fputc((imageDirty[1] ? 1 : 0), file);
-               fputc((writeProtected[1] ? 1 : 0), file);
-               fwrite(nybblizedImage[1], 1, 232960, file);
-               fwrite(imageName[1], 1, MAX_PATH, file);
-       }
-       else
-               WriteLong(file, 0);
-}
-
-
-void FloppyDrive::LoadState(FILE * file)
-{
-       // Eject images if they're loaded
-       EjectImage(0);
-       EjectImage(1);
-
-       // Read internal state variables
-       motorOn = fgetc(file);
-       activeDrive = fgetc(file);
-       ioMode = fgetc(file);
-       latchValue = fgetc(file);
-       phase = fgetc(file);
-       track = fgetc(file);
-       ioHappened = (fgetc(file) == 1 ? true : false);
-       currentPos = ReadLong(file);
-
-       diskSize[0] = ReadLong(file);
-
-       if (diskSize[0])
-       {
-               disk[0] = new uint8_t[diskSize[0]];
-               diskType[0] = (uint8_t)ReadLong(file);
-               imageDirty[0] = (fgetc(file) == 1 ? true : false);
-               writeProtected[0] = (fgetc(file) == 1 ? true : false);
-               fread(nybblizedImage[0], 1, 232960, file);
-               fread(imageName[0], 1, MAX_PATH, file);
-       }
-
-       diskSize[1] = ReadLong(file);
-
-       if (diskSize[1])
-       {
-               disk[1] = new uint8_t[diskSize[1]];
-               diskType[1] = (uint8_t)ReadLong(file);
-               imageDirty[1] = (fgetc(file) == 1 ? true : false);
-               writeProtected[1] = (fgetc(file) == 1 ? true : false);
-               fread(nybblizedImage[1], 1, 232960, file);
-               fread(imageName[1], 1, MAX_PATH, file);
-       }
-}
-
-
-uint32_t FloppyDrive::ReadLong(FILE * file)
-{
-       uint32_t r = 0;
-
-       for(int i=0; i<4; i++)
-               r = (r << 8) | fgetc(file);
-
-       return r;
-}
-
-
-void FloppyDrive::WriteLong(FILE * file, uint32_t l)
-{
-       for(int i=0; i<4; i++)
-       {
-               fputc((l >> 24) & 0xFF, file);
-               l = l << 8;
-       }
-}
-
-
-// Memory mapped I/O functions
-
-/*
-The DSK format is a byte-for-byte image of a 16-sector Apple II floppy disk: 35
-tracks of 16 sectors of 256 bytes each, making 143,360 bytes in total. The PO
-format is exactly the same size as DSK and is also organized as 35 sequential
-tracks, but the sectors within each track are in a different sequence. The NIB
-format is a nybblized format: a more direct representation of the disk's data
-as encoded by the Apple II floppy drive hardware. NIB contains 35 tracks of
-6656 bytes each, for a total size of 232,960 bytes. Although this format is
-much larger, it is also more versatile and can represent the older 13-sector
-disks, many copy-protected disks, and other unusual encodings.
-*/
-
-void FloppyDrive::ControlStepper(uint8_t addr)
-{
-       // $C0E0 - 7
-/*
-What I can gather here:
-bits 1-2 are the "phase" of the track (which is 1/4 of a full track (?))
-bit 0 is the "do something" bit.
-*/
-       if (addr & 0x01)
-       {
-               uint8_t newPhase = (addr >> 1) & 0x03;
-//WriteLog("*** Stepper change [%u]: track = %u, phase = %u, newPhase = %u\n", addr, track, phase, newPhase);
-
-               if (((phase + 1) & 0x03) == newPhase)
-                       phase += (phase < 79 ? 1 : 0);
-
-               if (((phase - 1) & 0x03) == newPhase)
-                       phase -= (phase > 0 ? 1 : 0);
-
-               if (!(phase & 0x01))
-               {
-                       track = ((phase >> 1) < 35 ? phase >> 1 : 34);
-                       currentPos = 0;
-               }
-//WriteLog("                        track = %u, phase = %u, newPhase = %u\n", track, phase, newPhase);
-SpawnMessage("Stepping to track %u...", track);
-       }
-
-//     return something if read mode...
-}
-
-
-void FloppyDrive::ControlMotor(uint8_t addr)
-{
-       // $C0E8 - 9
-       motorOn = addr;
-}
-
-
-void FloppyDrive::DriveEnable(uint8_t addr)
-{
-       // $C0EA - B
-       activeDrive = addr;
-}
-
-
-uint8_t FloppyDrive::ReadWrite(void)
-{
-SpawnMessage("%u:%sing %s track %u, sector %u...", activeDrive,
-       (ioMode == IO_MODE_READ ? "Read" : "Write"),
-       (ioMode == IO_MODE_READ ? "from" : "to"), track, currentPos / 396);
-       // $C0EC
-       ioHappened = true;
-/*
-I think what happens here is that once a track is read its nybblized form
-is fed through here, one byte at a time--which means for DO disks, we have
-to convert the actual 256 byte sector to a 416 byte nybblized data "sector".
-Which we now do. :-)
-*/
-       if (ioMode == IO_MODE_WRITE && (latchValue & 0x80))
-       {
-               // Does it behave like this?
-#warning "Write protection kludged in--investigate real behavior!"
-               if (writeProtected[activeDrive])
-//doesn't seem to do anything
-                       return 0;//is this more like it?
-
-               nybblizedImage[activeDrive][(track * 6656) + currentPos] = latchValue;
-               imageDirty[activeDrive] = true;
-       }
-
-       uint8_t diskByte = nybblizedImage[activeDrive][(track * 6656) + currentPos];
-       currentPos = (currentPos + 1) % 6656;
-
-//WriteLog("FL: diskByte=%02X, currentPos=%u\n", diskByte, currentPos);
-       return diskByte;
-}
-
-
-uint8_t FloppyDrive::GetLatchValue(void)
-{
-       // $C0ED
-       return latchValue;
-}
-
-
-void FloppyDrive::SetLatchValue(uint8_t value)
-{
-       // $C0ED
-       latchValue = value;
-}
-
-
-void FloppyDrive::SetReadMode(void)
-{
-       // $C0EE
-       ioMode = IO_MODE_READ;
-}
-
-
-void FloppyDrive::SetWriteMode(void)
-{
-       // $C0EF
-       ioMode = IO_MODE_WRITE;
-}
-
-/*
-PRODOS 8 MLI ERROR CODES
-
-$00:    No error
-$01:    Bad system call number
-$04:    Bad system call parameter count
-$25:    Interrupt table full
-$27:    I/O error
-$28:    No device connected
-$2B:    Disk write protected
-$2E:    Disk switched
-$40:    Invalid pathname
-$42:    Maximum number of files open
-$43:    Invalid reference number
-$44:    Directory not found
-$45:    Volume not found
-$46:    File not found
-$47:    Duplicate filename
-$48:    Volume full
-$49:    Volume directory full
-$4A:    Incompatible file format, also a ProDOS directory
-$4B:    Unsupported storage_type
-$4C:    End of file encountered
-$4D:    Position out of range
-$4E:    File access error, also file locked
-$50:    File is open
-$51:    Directory structure damaged
-$52:    Not a ProDOS volume
-$53:    Invalid system call parameter
-$55:    Volume Control Block table full
-$56:    Bad buffer address
-$57:    Duplicate volume
-$5A:    File structure damaged
-*/
diff --git a/src/floppy.h b/src/floppy.h
deleted file mode 100644 (file)
index 0438d65..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Apple 2 floppy disk support
-//
-
-#ifndef __FLOPPY_H__
-#define __FLOPPY_H__
-
-// MAX_PATH isn't defined in stdlib.h on *nix, so we do it here...
-#ifdef __GCCUNIX__
-#include <limits.h>
-#define MAX_PATH               _POSIX_PATH_MAX
-#else
-#include <stdlib.h>                                                            // for MAX_PATH on MinGW/Darwin
-// Kludge for Win64
-#ifndef MAX_PATH
-#define        MAX_PATH        _MAX_PATH
-#endif
-#endif
-#include <stdint.h>
-#include <stdio.h>
-
-enum { DFT_UNKNOWN, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE };
-enum { DLS_OFF, DLS_READ, DLS_WRITE };
-
-class FloppyDrive
-{
-       public:
-               FloppyDrive();
-               ~FloppyDrive();
-
-               bool LoadImage(const char * filename, uint8_t driveNum = 0);
-               bool SaveImage(uint8_t driveNum = 0);
-               bool SaveImageAs(const char * filename, uint8_t driveNum = 0);
-               void CreateBlankImage(uint8_t driveNum = 0);
-               void SwapImages(void);
-               const char * ImageName(uint8_t driveNum = 0);
-               void EjectImage(uint8_t driveNum = 0);
-               bool IsEmpty(uint8_t driveNum = 0);
-               bool IsWriteProtected(uint8_t driveNum = 0);
-               void SetWriteProtect(bool, uint8_t driveNum = 0);
-               int DriveLightStatus(uint8_t driveNum = 0);
-               void SaveState(FILE *);
-               void LoadState(FILE *);
-
-       private:
-               uint32_t ReadLong(FILE *);
-               void WriteLong(FILE *, uint32_t);
-
-               // I/O functions ($C0Ex accesses)
-
-       public:
-               void ControlStepper(uint8_t addr);
-               void ControlMotor(uint8_t addr);
-               void DriveEnable(uint8_t addr);
-               uint8_t ReadWrite(void);
-               uint8_t GetLatchValue(void);
-               void SetLatchValue(uint8_t value);
-               void SetReadMode(void);
-               void SetWriteMode(void);
-
-       protected:
-               void DetectImageType(const char * filename, uint8_t driveNum);
-               void NybblizeImage(uint8_t driveNum);
-               void DenybblizeImage(uint8_t driveNum);
-
-       private:
-               char imageName[2][MAX_PATH];
-               uint8_t * disk[2];
-               uint32_t diskSize[2];
-               uint8_t diskType[2];
-               bool imageDirty[2];
-               bool writeProtected[2];
-               uint8_t motorOn;
-               uint8_t activeDrive;
-               uint8_t ioMode;
-               uint8_t latchValue;
-               uint8_t phase;
-               uint8_t track;
-               bool ioHappened;
-
-               uint8_t nybblizedImage[2][232960];
-               uint32_t currentPos;
-
-               // And here are some private class variables (to reduce function redundancy):
-               static uint8_t header[21];
-               static uint8_t doSector[16];
-               static uint8_t poSector[16];
-               static char nameBuf[MAX_PATH];
-};
-
-#endif // __FLOPPY_H__
-
diff --git a/src/floppydrive.cpp b/src/floppydrive.cpp
new file mode 100644 (file)
index 0000000..056ca2b
--- /dev/null
@@ -0,0 +1,1500 @@
+//
+// Apple 2 floppy disk support
+//
+// by James Hammons
+// (c) 2005-2018 Underground Software
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// WHO  WHEN        WHAT
+// ---  ----------  -----------------------------------------------------------
+// JLH  12/03/2005  Created this file
+// JLH  12/15/2005  Fixed nybblization functions to work properly
+// JLH  12/27/2005  Added blank disk creation, fixed saving to work properly
+//
+
+#include "floppydrive.h"
+
+#include <stdio.h>
+#include <string.h>
+#include "apple2.h"
+#include "crc32.h"
+#include "firmware.h"
+#include "log.h"
+#include "mmu.h"
+#include "video.h"             // For message spawning... Though there's probably a
+                                               // better approach than this!
+
+// Useful enums
+
+enum { IO_MODE_READ, IO_MODE_WRITE };
+
+// FloppyDrive class variable initialization
+
+uint8_t FloppyDrive::doSector[16] = {
+       0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF };
+uint8_t FloppyDrive::poSector[16] = {
+       0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF };
+uint8_t FloppyDrive::wozHeader[9] = "WOZ1\xFF\x0A\x0D\x0A";
+uint8_t FloppyDrive::wozHeader2[9] = "WOZ2\xFF\x0A\x0D\x0A";
+uint8_t FloppyDrive::standardTMAP[141] = {
+       0, 0, 0xFF, 1, 1, 1, 0xFF, 2, 2, 2, 0xFF, 3, 3, 3, 0xFF, 4, 4, 4, 0xFF,
+       5, 5, 5, 0xFF, 6, 6, 6, 0xFF, 7, 7, 7, 0xFF, 8, 8, 8, 0xFF, 9, 9, 9, 0xFF,
+       10, 10, 10, 0xFF, 11, 11, 11, 0xFF, 12, 12, 12, 0xFF, 13, 13, 13, 0xFF,
+       14, 14, 14, 0xFF, 15, 15, 15, 0xFF, 16, 16, 16, 0xFF, 17, 17, 17, 0xFF,
+       18, 18, 18, 0xFF, 19, 19, 19, 0xFF, 20, 20, 20, 0xFF, 21, 21, 21, 0xFF,
+       22, 22, 22, 0xFF, 23, 23, 23, 0xFF, 24, 24, 24, 0xFF, 25, 25, 25, 0xFF,
+       26, 26, 26, 0xFF, 27, 27, 27, 0xFF, 28, 28, 28, 0xFF, 29, 29, 29, 0xFF,
+       30, 30, 30, 0xFF, 31, 31, 31, 0xFF, 32, 32, 32, 0xFF, 33, 33, 33, 0xFF,
+       34, 34, 34, 0xFF, 0xFF, 0xFF
+};
+uint8_t FloppyDrive::bitMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+uint8_t FloppyDrive::sequencerROM[256] = {
+0x18, 0x18, 0x18, 0x18, 0x0A, 0x0A, 0x0A, 0x0A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x2D, 0x38, 0x2D, 0x38, 0x0A, 0x0A, 0x0A, 0x0A, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+0x38, 0x28, 0xD8, 0x08, 0x0A, 0x0A, 0x0A, 0x0A, 0x39, 0x39, 0x39, 0x39, 0x3B, 0x3B, 0x3B, 0x3B,
+0x48, 0x48, 0xD8, 0x48, 0x0A, 0x0A, 0x0A, 0x0A, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+0x58, 0x58, 0xD8, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x68, 0x68, 0xD8, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
+0x78, 0x78, 0xD8, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+0x88, 0x88, 0xD8, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88,
+0x98, 0x98, 0xD8, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+0x29, 0xA8, 0xD8, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8,
+0xBD, 0xB8, 0xCD, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0xB9, 0xB9, 0xB9, 0xB9, 0xBB, 0xBB, 0xBB, 0xBB,
+0x59, 0xC8, 0xD9, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
+0xD9, 0xA0, 0xD9, 0xD8, 0x0A, 0x0A, 0x0A, 0x0A, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+0x08, 0xE8, 0xD8, 0xE8, 0x0A, 0x0A, 0x0A, 0x0A, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+0xFD, 0xF8, 0xFD, 0xF8, 0x0A, 0x0A, 0x0A, 0x0A, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
+0x4D, 0xE0, 0xDD, 0xE0, 0x0A, 0x0A, 0x0A, 0x0A, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x08
+};
+
+char FloppyDrive::nameBuf[MAX_PATH];
+
+
+// Static in-line functions, for clarity & speed, mostly for reading values out
+// of the WOZ struct, which stores its data in LE; some for swapping variables
+static inline uint16_t Uint16LE(uint16_t v)
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+       return ((v & 0xFF) << 8) | ((v & 0xFF00) >> 8);
+#else
+       return v;
+#endif
+}
+
+
+static inline uint32_t Uint32LE(uint32_t v)
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+       return ((v & 0xFF) << 24) | ((v & 0xFF00) << 8)
+               | ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24);
+#else
+       return v;
+#endif
+}
+
+
+static inline void Swap(uint8_t & a, uint8_t & b)
+{
+       uint8_t t = a;
+       a = b;
+       b = t;
+}
+
+
+static inline void Swap(uint32_t & a, uint32_t & b)
+{
+       uint32_t t = a;
+       a = b;
+       b = t;
+}
+
+
+static inline void Swap(bool & a, bool & b)
+{
+       bool t = a;
+       a = b;
+       b = t;
+}
+
+
+static inline void Swap(uint8_t * & a, uint8_t * & b)
+{
+       uint8_t * t = a;
+       a = b;
+       b = t;
+}
+
+
+static inline void Swap(WOZ * & a, WOZ * & b)
+{
+       WOZ * t = a;
+       a = b;
+       b = t;
+}
+
+
+// FloppyDrive class implementation...
+
+FloppyDrive::FloppyDrive(): motorOn(0), activeDrive(0), ioMode(IO_MODE_READ),  ioHappened(false)
+{
+       phase[0] = phase[1] = 0;
+       headPos[0] = headPos[1] = 0;
+       trackLength[0] = trackLength[1] = 51200;
+       disk[0] = disk[1] = NULL;
+       woz[0] = woz[1] = NULL;
+       diskSize[0] = diskSize[1] = 0;
+       diskType[0] = diskType[1] = DT_EMPTY;
+       imageDirty[0] = imageDirty[1] = false;
+       imageName[0][0] = imageName[1][0] = 0;                  // Zero out filenames
+}
+
+
+FloppyDrive::~FloppyDrive()
+{
+       if (disk[0])
+               delete[] disk[0];
+
+       if (disk[1])
+               delete[] disk[1];
+}
+
+
+bool FloppyDrive::LoadImage(const char * filename, uint8_t driveNum/*= 0*/)
+{
+       WriteLog("FLOPPY: Attempting to load image '%s' in drive #%u.\n", filename, driveNum);
+
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted to load image to drive #%u!\n", driveNum);
+               return false;
+       }
+
+       // Zero out filename, in case it doesn't load
+       imageName[driveNum][0] = 0;
+
+       FILE * fp = fopen(filename, "rb");
+
+       if (fp == NULL)
+       {
+               WriteLog("FLOPPY: Failed to open image file '%s' for reading...\n", filename);
+               return false;
+       }
+
+       if (disk[driveNum])
+               delete[] disk[driveNum];
+
+       fseek(fp, 0, SEEK_END);
+       diskSize[driveNum] = ftell(fp);
+       fseek(fp, 0, SEEK_SET);
+       disk[driveNum] =  new uint8_t[diskSize[driveNum]];
+       woz[driveNum] = (WOZ *)disk[driveNum];
+       fread(disk[driveNum], 1, diskSize[driveNum], fp);
+
+       fclose(fp);
+//printf("Read disk image: %u bytes.\n", diskSize);
+       DetectImageType(filename, driveNum);
+       strcpy(imageName[driveNum], filename);
+
+       WriteLog("FLOPPY: Loaded image '%s' for drive #%u.\n", filename, driveNum);
+
+       return true;
+}
+
+
+bool FloppyDrive::SaveImage(uint8_t driveNum/*= 0*/)
+{
+// comment out for now...
+#if 0
+       // Various sanity checks...
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted to save image to drive #%u!\n", driveNum);
+               return false;
+       }
+
+       if (!imageDirty[driveNum])
+       {
+               WriteLog("FLOPPY: No need to save unchanged image...\n");
+               return false;
+       }
+
+       if (imageName[driveNum][0] == 0)
+       {
+               WriteLog("FLOPPY: Attempted to save non-existant image!\n");
+               return false;
+       }
+
+       // Finally, write the damn image
+       FILE * fp = fopen(imageName[driveNum], "wb");
+
+       if (fp == NULL)
+       {
+               WriteLog("FLOPPY: Failed to open image file '%s' for writing...\n", imageName[driveNum]);
+               return false;
+       }
+
+       fwrite(disk[driveNum], 1, diskSize[driveNum], fp);
+       fclose(fp);
+
+       WriteLog("FLOPPY: Successfully wrote image file '%s'...\n", imageName[driveNum]);
+
+       return true;
+#else
+       char * ext = strrchr(imageName[driveNum], '.');
+
+       if ((ext != NULL) && (diskType[driveNum] != DT_WOZ))
+               memcpy(ext, ".woz", 4);
+
+       return SaveWOZ(driveNum);
+#endif
+}
+
+
+bool FloppyDrive::SaveImageAs(const char * filename, uint8_t driveNum/*= 0*/)
+{
+       strncpy(imageName[driveNum], filename, MAX_PATH);
+       // Ensure a NULL terminated string here, as strncpy() won't terminate the
+       // string if the source length is >= MAX_PATH
+       imageName[driveNum][MAX_PATH - 1] = 0;
+       return SaveImage(driveNum);
+}
+
+
+void FloppyDrive::CreateBlankImage(uint8_t driveNum/*= 0*/)
+{
+       if (disk[driveNum] != NULL)
+               delete disk[driveNum];
+
+       InitWOZ(driveNum);
+       diskType[driveNum] = DT_WOZ;
+       strcpy(imageName[driveNum], "newblank.woz");
+       SpawnMessage("New blank image inserted in drive %u...", driveNum);
+}
+
+
+void FloppyDrive::SwapImages(void)
+{
+#if 0
+WriteLog("SwapImages BEFORE:\n");
+WriteLog("\tdisk[0]=%X, disk[1]=%X\n", disk[0], disk[1]);
+WriteLog("\twoz[0]=%X, woz[1]=%X\n", woz[0], woz[1]);
+WriteLog("\tdiskSize[0]=%X, diskSize[1]=%X\n", diskSize[0], diskSize[1]);
+WriteLog("\tdiskType[0]=%X, diskType[1]=%X\n", diskType[0], diskType[1]);
+WriteLog("\timageDirty[0]=%X, imageDirty[1]=%X\n", imageDirty[0], imageDirty[1]);
+WriteLog("\tphase[0]=%X, phase[1]=%X\n", phase[0], phase[1]);
+WriteLog("\theadPos[0]=%X, headPos[1]=%X\n", headPos[0], headPos[1]);
+WriteLog("\tcurrentPos[0]=%X, currentPos[1]=%X\n", currentPos[0], currentPos[1]);
+#endif
+       char imageNameTmp[MAX_PATH];
+
+       memcpy(imageNameTmp, imageName[0], MAX_PATH);
+       memcpy(imageName[0], imageName[1], MAX_PATH);
+       memcpy(imageName[1], imageNameTmp, MAX_PATH);
+
+       Swap(disk[0], disk[1]);
+       Swap(woz[0], woz[1]);
+       Swap(diskSize[0], diskSize[1]);
+       Swap(diskType[0], diskType[1]);
+       Swap(imageDirty[0], imageDirty[1]);
+
+       Swap(phase[0], phase[1]);
+       Swap(headPos[0], headPos[1]);
+       Swap(currentPos[0], currentPos[1]);
+SpawnMessage("Drive 0: %s...", imageName[0]);
+#if 0
+WriteLog("SwapImages AFTER:\n");
+WriteLog("\tdisk[0]=%X, disk[1]=%X\n", disk[0], disk[1]);
+WriteLog("\twoz[0]=%X, woz[1]=%X\n", woz[0], woz[1]);
+WriteLog("\tdiskSize[0]=%X, diskSize[1]=%X\n", diskSize[0], diskSize[1]);
+WriteLog("\tdiskType[0]=%X, diskType[1]=%X\n", diskType[0], diskType[1]);
+WriteLog("\timageDirty[0]=%X, imageDirty[1]=%X\n", imageDirty[0], imageDirty[1]);
+WriteLog("\tphase[0]=%X, phase[1]=%X\n", phase[0], phase[1]);
+WriteLog("\theadPos[0]=%X, headPos[1]=%X\n", headPos[0], headPos[1]);
+WriteLog("\tcurrentPos[0]=%X, currentPos[1]=%X\n", currentPos[0], currentPos[1]);
+#endif
+}
+
+
+/*
+Need to add some type of error checking here, so we can report back on bad images, etc.
+*/
+void FloppyDrive::DetectImageType(const char * filename, uint8_t driveNum)
+{
+       diskType[driveNum] = DFT_UNKNOWN;
+
+       if (memcmp(disk[driveNum], wozHeader, 8) == 0)
+       {
+               diskType[driveNum] = DT_WOZ;
+               /*bool r =*/ CheckWOZ(disk[driveNum], diskSize[driveNum], driveNum);
+       }
+       else if (diskSize[driveNum] == 143360)
+       {
+               const char * ext = strrchr(filename, '.');
+
+               if (ext == NULL)
+                       return;
+
+               WriteLog("FLOPPY: Found extension [%s]...\n", ext);
+
+               if (strcasecmp(ext, ".po") == 0)
+                       diskType[driveNum] = DT_PRODOS;
+               else if ((strcasecmp(ext, ".do") == 0) || (strcasecmp(ext, ".dsk") == 0))
+               {
+                       // We assume this, but check for a PRODOS fingerprint. Trust, but
+                       // verify. ;-)
+                       diskType[driveNum] = DT_DOS33;
+
+                       uint8_t fingerprint[4][4] = {
+                               { 0x00, 0x00, 0x03, 0x00 },             // @ $400
+                               { 0x02, 0x00, 0x04, 0x00 },             // @ $600
+                               { 0x03, 0x00, 0x05, 0x00 },             // @ $800
+                               { 0x04, 0x00, 0x00, 0x00 }              // @ $A00
+                       };
+
+                       bool foundProdos = true;
+
+                       for(uint32_t i=0; i<4; i++)
+                       {
+                               for(uint32_t j=0; j<4; j++)
+                               {
+                                       if (disk[driveNum][0x400 + (i * 0x200) + j] != fingerprint[i][j])
+                                       {
+                                               foundProdos = false;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if (foundProdos)
+                               diskType[driveNum] = DT_PRODOS;
+               }
+
+// Actually, it just might matter WRT to nybblyzing/denybblyzing
+// (and, it does... :-P)
+               WOZifyImage(driveNum);
+       }
+       else if (diskSize[driveNum] == 143488)
+       {
+               diskType[driveNum] = DT_DOS33_HDR;
+               WOZifyImage(driveNum);
+       }
+
+#warning "Should we attempt to nybblize unknown images here? Definitely SHOULD issue a warning!"
+// No, we don't nybblize anymore.  But we should tell the user that the loading failed with a return value
+
+       WriteLog("FLOPPY: Detected image type %s...\n", (diskType[driveNum] == DT_DOS33 ?
+               "DOS 3.3 image" : (diskType[driveNum] == DT_DOS33_HDR ?
+               "DOS 3.3 image (headered)" : (diskType[driveNum] == DT_PRODOS ? "ProDOS image" : (diskType[driveNum] == DT_WOZ ? "WOZ image" : "unknown")))));
+}
+
+
+//
+// Write a bitstream (source left justified to bit 7) to destination buffer.
+// Writes 'bits' number of bits to 'dest', starting at bit position 'dstPtr',
+// updating 'dstPtr' for the caller.
+//
+void FloppyDrive::WriteBits(uint8_t * dest, uint8_t * src, uint16_t bits, uint16_t * dstPtr)
+{
+       for(uint16_t i=0; i<bits; i++)
+       {
+               // Get the destination location's bitmask
+               uint8_t dstMask = bitMask[*dstPtr % 8];
+
+               // Set the bit to one if there's a corresponding one in the source
+               // data, otherwise set it to zero
+               if (src[i / 8] & bitMask[i % 8])
+                       dest[*dstPtr / 8] |= dstMask;
+               else
+                       dest[*dstPtr / 8] &= ~dstMask;
+
+               (*dstPtr)++;
+       }
+}
+
+
+void FloppyDrive::WOZifyImage(uint8_t driveNum)
+{
+       // hdr (21) + nybbles (343) + footer (48) = 412 bytes per sector
+       // (not incl. 64 byte track marker)
+// let's try 394 per sector... & see what happens
+// let's go back to what we had, and see what happens  :-)
+// [still need to expand them back to what they were]
+
+       uint8_t ff10[2] = { 0xFF, 0x00 };
+       uint8_t addressHeader[14] = {
+               0xD5, 0xAA, 0x96, 0xFF, 0xFE, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0xDE, 0xAA, 0xEB };
+       uint8_t sectorHeader[3] = { 0xD5, 0xAA, 0xAD };
+       uint8_t footer[3] = { 0xDE, 0xAA, 0xEB };
+       uint8_t diskbyte[0x40] = {
+               0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6,
+               0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
+               0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC,
+               0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3,
+               0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE,
+               0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC,
+               0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6,
+               0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
+
+       uint8_t tmpNib[343];
+//     memcpy(tmpDisk, disk[driveNum], diskSize[driveNum]);
+//     delete[] disk[driveNum];
+       uint8_t * tmpDisk = disk[driveNum];
+       disk[driveNum] = NULL;//new uint8_t[diskSize[driveNum]];
+
+       // Set up track index...
+//     memcpy(woz[driveNum]->tmap, standardTMAP, 141);
+       InitWOZ(driveNum);
+
+       // Upconvert data from DSK & friends format to WOZ tracks  :-)
+       for(uint8_t trk=0; trk<35; trk++)
+       {
+               uint16_t dstBitPtr = 0;
+               uint8_t * img = woz[driveNum]->track[trk].bits;
+//already done
+//             memset(img, 0, 6646);
+
+               // Write self-sync header bytes (16, should it be 64? Dunno.)
+               for(int i=0; i<64; i++)
+                       WriteBits(img, ff10, 10, &dstBitPtr);
+
+               // Write out the following sectors
+               for(uint8_t sector=0; sector<16; sector++)
+               {
+                       // Set up the sector address header
+                       addressHeader[5] = ((trk >> 1) & 0x55) | 0xAA;
+                       addressHeader[6] =  (trk       & 0x55) | 0xAA;
+                       addressHeader[7] = ((sector >> 1) & 0x55) | 0xAA;
+                       addressHeader[8] =  (sector       & 0x55) | 0xAA;
+                       addressHeader[9] = (((trk ^ sector ^ 0xFE) >> 1) & 0x55) | 0xAA;
+                       addressHeader[10] = ((trk ^ sector ^ 0xFE)       & 0x55) | 0xAA;
+
+                       WriteBits(img, addressHeader, 14 * 8, &dstBitPtr);
+
+                       // Write 5 self-sync bytes for actual sector header
+                       for(int i=0; i<5; i++)
+                               WriteBits(img, ff10, 10, &dstBitPtr);
+
+                       // Write sector header (D5 AA AD)
+                       WriteBits(img, sectorHeader, 3 * 8, &dstBitPtr);
+//                     uint8_t * bytes = disk[driveNum];
+                       uint8_t * bytes = tmpDisk;
+
+//Need to fix this so it writes the correct sector in the correct place *and* put the correct sector # into the header above as well.  !!! FIX !!!
+                       // Figure out location of sector data in disk image
+                       if (diskType[driveNum] == DT_DOS33)
+                               bytes += (doSector[sector] * 256) + (trk * 256 * 16);
+                       else if (diskType[driveNum] == DT_DOS33_HDR)
+                               bytes += (doSector[sector] * 256) + (trk * 256 * 16) + 128;
+                       else if (diskType[driveNum] == DT_PRODOS)
+                               bytes += (poSector[sector] * 256) + (trk * 256 * 16);
+                       else
+                               bytes += (sector * 256) + (trk * 256 * 16);
+
+                       // Convert the 256 8-bit bytes into 342 6-bit bytes.
+                       for(uint16_t i=0; i<0x56; i++)
+                       {
+                               tmpNib[i] = ((bytes[(i + 0xAC) & 0xFF] & 0x01) << 7)
+                                       | ((bytes[(i + 0xAC) & 0xFF] & 0x02) << 5)
+                                       | ((bytes[(i + 0x56) & 0xFF] & 0x01) << 5)
+                                       | ((bytes[(i + 0x56) & 0xFF] & 0x02) << 3)
+                                       | ((bytes[(i + 0x00) & 0xFF] & 0x01) << 3)
+                                       | ((bytes[(i + 0x00) & 0xFF] & 0x02) << 1);
+                       }
+
+                       tmpNib[0x54] &= 0x3F;
+                       tmpNib[0x55] &= 0x3F;
+                       memcpy(tmpNib + 0x56, bytes, 256);
+
+                       // XOR the data block with itself, offset by one byte, creating a
+                       // 343rd byte which is used as a checksum.
+                       tmpNib[342] = 0x00;
+
+                       for(uint16_t i=342; i>0; i--)
+                               tmpNib[i] = tmpNib[i] ^ tmpNib[i - 1];
+
+                       // Using a lookup table, convert the 6-bit bytes into disk bytes.
+                       for(uint16_t i=0; i<343; i++)
+                               tmpNib[i] = diskbyte[tmpNib[i] >> 2];
+
+                       WriteBits(img, tmpNib, 343 * 8, &dstBitPtr);
+
+                       // Done with the nybblization, now add the epilogue...
+                       WriteBits(img, footer, 3 * 8, &dstBitPtr);
+
+                       // (Should the footer be 30 or 48? would be 45 FF10s here for 48)
+                       for(int i=0; i<27; i++)
+                               WriteBits(img, ff10, 10, &dstBitPtr);
+               }
+
+               // Set the proper bit/byte lengths in the WOZ for this track
+               woz[driveNum]->track[trk].bitCount = Uint16LE(dstBitPtr);
+               woz[driveNum]->track[trk].byteCount = Uint16LE((dstBitPtr + 7) / 8);
+       }
+
+       delete[] tmpDisk;
+}
+
+
+const char * FloppyDrive::ImageName(uint8_t driveNum/*= 0*/)
+{
+       // Set up a zero-length string for return value
+       nameBuf[0] = 0;
+
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted to get image name for drive #%u!\n", driveNum);
+               return nameBuf;
+       }
+
+       // Now we attempt to strip out extraneous paths/extensions to get just the filename
+       const char * startOfFile = strrchr(imageName[driveNum], '/');
+       const char * startOfExt = strrchr(imageName[driveNum], '.');
+
+       // If there isn't a path, assume we're starting at the beginning
+       if (startOfFile == NULL)
+               startOfFile = &imageName[driveNum][0];
+       else
+               startOfFile++;
+
+       // If there isn't an extension, assume it's at the terminating NULL
+       if (startOfExt == NULL)
+               startOfExt = &imageName[driveNum][0] + strlen(imageName[driveNum]);
+
+       // Now copy the filename (may copy nothing!)
+       int j = 0;
+
+       for(const char * i=startOfFile; i<startOfExt; i++)
+               nameBuf[j++] = *i;
+
+       nameBuf[j] = 0;
+
+       return nameBuf;
+}
+
+
+void FloppyDrive::EjectImage(uint8_t driveNum/*= 0*/)
+{
+       // Sanity check
+       if (diskType[driveNum] == DT_EMPTY)
+               return;
+
+       // Probably want to save a dirty image... ;-)
+       if (SaveImage(driveNum))
+               WriteLog("FLOPPY: Ejected image file '%s' from drive %u...\n", imageName[driveNum], driveNum);
+
+       if (disk[driveNum])
+               delete[] disk[driveNum];
+
+       disk[driveNum] = NULL;
+       woz[driveNum] = NULL;
+       diskSize[driveNum] = 0;
+       diskType[driveNum] = DT_EMPTY;
+       imageDirty[driveNum] = false;
+       imageName[driveNum][0] = 0;                     // Zero out filenames
+}
+
+
+bool FloppyDrive::IsEmpty(uint8_t driveNum/*= 0*/)
+{
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted DriveIsEmtpy() for drive #%u!\n", driveNum);
+               return true;
+       }
+
+       return (diskType[driveNum] == DT_EMPTY ? true : false);
+}
+
+
+bool FloppyDrive::IsWriteProtected(uint8_t driveNum/*= 0*/)
+{
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted DiskIsWriteProtected() for drive #%u!\n", driveNum);
+               return true;
+       }
+
+       return (bool)woz[driveNum]->writeProtected;
+}
+
+
+void FloppyDrive::SetWriteProtect(bool state, uint8_t driveNum/*= 0*/)
+{
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted set write protect for drive #%u!\n", driveNum);
+               return;
+       }
+
+       woz[driveNum]->writeProtected = (uint8_t)state;
+}
+
+
+int FloppyDrive::DriveLightStatus(uint8_t driveNum/*= 0*/)
+{
+       int retval = DLS_OFF;
+
+       if (activeDrive != driveNum)
+               return DLS_OFF;
+
+       if (ioHappened)
+               retval = (ioMode == IO_MODE_READ ? DLS_READ : DLS_WRITE);
+
+       ioHappened = false;
+       return retval;
+}
+
+
+void FloppyDrive::SaveState(FILE * file)
+{
+       // Internal state vars
+       fputc(motorOn, file);
+       fputc(activeDrive, file);
+       fputc(ioMode, file);
+       fputc(dataRegister, file);
+       fputc((ioHappened ? 1 : 0), file);
+
+       // Disk #1
+       if (disk[0] != NULL)
+       {
+               WriteLong(file, diskSize[0]);
+               WriteLong(file, diskType[0]);
+               fputc(phase[0], file);
+               fputc(headPos[0], file);
+               WriteLong(file, currentPos[0]);
+               fputc((imageDirty[0] ? 1 : 0), file);
+               fwrite(disk[0], 1, diskSize[0], file);
+               fwrite(imageName[0], 1, MAX_PATH, file);
+       }
+       else
+               WriteLong(file, 0);
+
+       // Disk #2
+       if (disk[1] != NULL)
+       {
+               WriteLong(file, diskSize[1]);
+               WriteLong(file, diskType[1]);
+               fputc(phase[1], file);
+               fputc(headPos[1], file);
+               WriteLong(file, currentPos[1]);
+               fputc((imageDirty[1] ? 1 : 0), file);
+               fwrite(disk[1], 1, diskSize[1], file);
+               fwrite(imageName[1], 1, MAX_PATH, file);
+       }
+       else
+               WriteLong(file, 0);
+}
+
+
+void FloppyDrive::LoadState(FILE * file)
+{
+       // Eject images if they're loaded
+       EjectImage(0);
+       EjectImage(1);
+
+       // Read internal state variables
+       motorOn = fgetc(file);
+       activeDrive = fgetc(file);
+       ioMode = fgetc(file);
+       dataRegister = fgetc(file);
+       ioHappened = (fgetc(file) == 1 ? true : false);
+
+       diskSize[0] = ReadLong(file);
+
+       if (diskSize[0])
+       {
+               disk[0] = new uint8_t[diskSize[0]];
+               diskType[0] = (uint8_t)ReadLong(file);
+               phase[0] = fgetc(file);
+               headPos[0] = fgetc(file);
+               currentPos[0] = ReadLong(file);
+               imageDirty[0] = (fgetc(file) == 1 ? true : false);
+               fread(disk[0], 1, diskSize[0], file);
+               fread(imageName[0], 1, MAX_PATH, file);
+               woz[0] = (WOZ *)disk[0];
+       }
+
+       diskSize[1] = ReadLong(file);
+
+       if (diskSize[1])
+       {
+               disk[1] = new uint8_t[diskSize[1]];
+               diskType[1] = (uint8_t)ReadLong(file);
+               phase[1] = fgetc(file);
+               headPos[1] = fgetc(file);
+               currentPos[1] = ReadLong(file);
+               imageDirty[1] = (fgetc(file) == 1 ? true : false);
+               fread(disk[1], 1, diskSize[1], file);
+               fread(imageName[1], 1, MAX_PATH, file);
+               woz[1] = (WOZ *)disk[1];
+       }
+}
+
+
+uint32_t FloppyDrive::ReadLong(FILE * file)
+{
+       uint32_t r = 0;
+
+       for(int i=0; i<4; i++)
+               r = (r << 8) | fgetc(file);
+
+       return r;
+}
+
+
+void FloppyDrive::WriteLong(FILE * file, uint32_t l)
+{
+       for(int i=0; i<4; i++)
+       {
+               fputc((l >> 24) & 0xFF, file);
+               l = l << 8;
+       }
+}
+
+
+void FloppyDrive::WriteLongLE(FILE * file, uint32_t l)
+{
+       for(int i=0; i<4; i++)
+       {
+               fputc(l & 0xFF, file);
+               l >>= 8;
+       }
+}
+
+
+void FloppyDrive::WriteWordLE(FILE * file, uint16_t w)
+{
+       fputc(w & 0xFF, file);
+       fputc((w >> 8) & 0xFF, file);
+}
+
+
+void FloppyDrive::WriteZeroes(FILE * file, uint32_t num)
+{
+       for(uint32_t i=0; i<num; i++)
+               fputc(0, file);
+}
+
+
+// Memory mapped I/O functions + Logic State Sequencer
+
+/*
+The DSK format is a byte-for-byte image of a 16-sector Apple II floppy disk: 35
+tracks of 16 sectors of 256 bytes each, making 143,360 bytes in total. The PO
+format is exactly the same size as DSK and is also organized as 35 sequential
+tracks, but the sectors within each track are in a different sequence. The NIB
+format is a nybblized format: a more direct representation of the disk's data
+as encoded by the Apple II floppy drive hardware. NIB contains 35 tracks of
+6656 bytes each, for a total size of 232,960 bytes. Although this format is
+much larger, it is also more versatile and can represent the older 13-sector
+disks, many copy-protected disks, and other unusual encodings.
+
+N.B.: Though the NIB format is *closer* to the representation of the disk's
+      data, it's not *quite* 100% as there can be zero bits lurking in the
+      interstices of the bytes written to the disk.  There's room for another
+      format that takes this into account (possibly even take phase 1 & 3
+      tracks into account as well).
+
+      As luck would have it, not long after I wrote that, I found out that some enterprising people have created it already--WOZ format.  Which is now supported by apple2.  :-D
+
+According to Beneath Apple DOS, DOS checks the data register to see if it changes when spinning up a drive: "A sufficient delay should be provided to allow the motor time to come up to speed.  Shugart recommends one second, but DOS is able to reduce this delay by watching the read latch until data starts to change."  Which means, we can simulate an empty/off drive by leaving the data register alone.
+*/
+
+void FloppyDrive::ControlStepper(uint8_t addr)
+{
+       // $C0E0 - 7
+/*
+How It Works
+------------
+The stepper motor has 4 phase solenoids (numbered 0-3) which corresponds to bits 1-2 of the address.  Bit 0 tells the phase solenoid to either energize (1) or de-energize (0).  By energizing the phase solenoids in ascending order, the stepper motor moves the head from a low numbered track to a higher numbered track; conversely, by energizing the solenoids in descending order, the stepper motor moves the head from a high numbered track to a lower one.  Given that this is a mechanical device, it takes a certain amount of time for the drum in the stepper motor to move from place to place--though pretty much all software written for the Disk II takes this into account.
+
+Tracks can apparently go from 0 to 79, though typically only 0 to 69 are usuable.  Further, because of the limitations of the read/write head of the drive, not every track can be written to, so typically (about 99.99% of the time in my guesstimation) only every *other* track is written to (phases 0 and 2); some disks exist that have tracks written on phase 1 or 3, but these tend to be the exception rather than the rule.
+*/
+       // Sanity check
+       if (diskType[activeDrive] == DT_EMPTY)
+               return;
+
+       // Convert phase solenoid number into a bit from 1 through 8:
+       uint8_t phaseBit = 1 << ((addr >> 1) & 0x03);
+
+       // Set the state of the phase solenoid accessed using the phase bit
+       if (addr & 0x01)
+               phase[activeDrive] |= phaseBit;
+       else
+               phase[activeDrive] &= ~phaseBit;
+
+       // See if the new phase solenoid is energized, & move the stepper/head
+       // appropriately.
+       // N.B.: The head stub is located by bits 1 & 2 of the headPos variable
+       uint8_t oldHeadPos = headPos[activeDrive];
+       uint8_t nextUp     = 1 << (((oldHeadPos >> 1) + 1) & 0x03);
+       uint8_t nextDown   = 1 << (((oldHeadPos >> 1) - 1) & 0x03);
+
+       // We simulate cogging here by seeing if there's a valid up and/or down
+       // position to go to.  If both are valid, the head goes nowhere.
+       if (phase[activeDrive] & nextUp)
+               headPos[activeDrive] += (headPos[activeDrive] < 140 ? 2 : 0);
+
+       if (phase[activeDrive] & nextDown)
+               headPos[activeDrive] -= (headPos[activeDrive] > 0 ? 2 : 0);
+
+       if (oldHeadPos != headPos[activeDrive])
+       {
+               uint8_t newTIdx = woz[activeDrive]->tmap[headPos[activeDrive]];
+               float newBitLen = (newTIdx == 0xFF ? 51200.0f
+                       : Uint16LE(woz[activeDrive]->track[newTIdx].bitCount));
+
+               uint8_t oldTIdx = woz[activeDrive]->tmap[oldHeadPos];
+               float oldBitLen = (oldTIdx == 0xFF ? 51200.0f
+                       : Uint16LE(woz[activeDrive]->track[oldTIdx].bitCount));
+               currentPos[activeDrive] = (uint32_t)((float)currentPos[activeDrive] * (newBitLen / oldBitLen));
+
+               trackLength[activeDrive] = (uint16_t)newBitLen;
+               SpawnMessage("Stepping to track %u...", headPos[activeDrive] >> 2);
+       }
+
+WriteLog("FLOPPY: Stepper phase %d set to %s [%c%c%c%c] (track=%2.2f)\n", (addr >> 1) & 0x03, (addr & 0x01 ? "ON " : "off"), (phase[activeDrive] & 0x08 ? '|' : '.'), (phase[activeDrive] & 0x04 ? '|' : '.'), (phase[activeDrive] & 0x02 ? '|' : '.'), (phase[activeDrive] & 0x01 ? '|' : '.'), (float)headPos[activeDrive] / 4.0f);
+}
+
+
+void FloppyDrive::ControlMotor(uint8_t addr)
+{
+       // $C0E8 - 9
+       motorOn = addr;
+
+       if (motorOn)
+               readPulse = 0;
+       else
+               driveOffTimeout = 2000000;
+
+WriteLog("FLOPPY: Turning drive motor %s\n", (motorOn ? "ON" : "off"));
+}
+
+
+void FloppyDrive::DriveEnable(uint8_t addr)
+{
+       // $C0EA - B
+       activeDrive = addr;
+WriteLog("FLOPPY: Selecting drive #%hhd\n", addr + 1);
+}
+
+
+/*
+So for $C08C-F, we have two switches (Q6 & Q7) which combine to make four states ($C-D is off/on for Q6, $E-F is off/on for Q7).
+
+So it forms a matrix like so:
+
+       $C08E                        $C08F
+      +-----------------------------------------------------------------------
+$C08C |Enable READ sequencing      |Data reg SHL every 8th clock while writing
+      +----------------------------+------------------------------------------
+$C08D |Check write prot./init write|Data reg LOAD every 8th clk while writing
+
+Looks like reads from even addresses in $C080-F block transfer data from the sequencer to the MPU, does write from odd do the inverse (transfer from MPU to sequencer)?  Looks like it.
+
+*/
+
+
+void FloppyDrive::SetShiftLoadSwitch(uint8_t state)
+{
+       // $C0EC - D
+       slSwitch = state;
+}
+
+
+void FloppyDrive::SetReadWriteSwitch(uint8_t state)
+{
+       // $C0EE - F
+       rwSwitch = state;
+}
+
+
+// MMIO: Reads from $C08x to $C0XX on even addresses
+uint8_t FloppyDrive::DataRegister(void)
+{
+       // Sanity check
+       if (diskType[activeDrive] != DT_EMPTY)
+       {
+               uint8_t tIdx = woz[activeDrive]->tmap[headPos[activeDrive]];
+               uint32_t bitLen = (tIdx == 0xFF ? 51200
+                       : Uint16LE(woz[activeDrive]->track[tIdx].bitCount));
+               SpawnMessage("%u:Reading $%02X from track %u, sector %u...",
+                       activeDrive, dataRegister, headPos[activeDrive] >> 2, (uint32_t)(((float)currentPos[activeDrive] / (float)bitLen) * 16.0f));
+               ioMode = IO_MODE_READ;
+               ioHappened = true;
+       }
+
+       return dataRegister;
+}
+
+
+// MMIO: Writes from $C08x to $C0XX on odd addresses
+void FloppyDrive::DataRegister(uint8_t data)
+{
+       cpuDataBus = data;
+       ioMode = IO_MODE_WRITE;
+       ioHappened = true;
+}
+
+
+/*
+        OFF switches                ON switches
+Switch  Addr   Func                 Addr   Func
+Q0      $C080  Phase 0 off          $C081  Phase 0 on
+Q1      $C082  Phase 1 off          $C083  Phase 1 on
+Q2      $C084  Phase 2 off          $C085  Phase 2 on
+Q3      $C086  Phase 3 off          $C087  Phase 3 on
+Q4      $C088  Drive off            $C089  Drive on
+Q5      $C08A  Select Drive 1       $C08B  Select Drive 2
+Q6      $C08C  Shift data register  $C08D  Load data register
+Q7      $C08E  Read                 $C08F  Write
+
+From "Beneath Apple ProDOS", description of combinations of $C0EC-EF
+
+$C08C, $C08E: Enable read sequencing
+$C08C, $C08F: Shift data register every four cycles while writing
+$C08D, $C08E: Check write protect and initialize sequencer for writing
+$C08D, $C08F: Load data register every four cycles while writing
+
+
+Sense Write Protect:
+
+       LDX #SLOT               Put slot number times 16 in X-register.
+       LDA $C08D, X
+       LDA $C08E, X    Sense write protect.
+       BMI ERROR               If high bit set, protected.
+
+*/
+
+/*
+PRODOS 8 MLI ERROR CODES
+
+$00:    No error
+$01:    Bad system call number
+$04:    Bad system call parameter count
+$25:    Interrupt table full
+$27:    I/O error
+$28:    No device connected
+$2B:    Disk write protected
+$2E:    Disk switched
+$40:    Invalid pathname
+$42:    Maximum number of files open
+$43:    Invalid reference number
+$44:    Directory not found
+$45:    Volume not found
+$46:    File not found
+$47:    Duplicate filename
+$48:    Volume full
+$49:    Volume directory full
+$4A:    Incompatible file format, also a ProDOS directory
+$4B:    Unsupported storage_type
+$4C:    End of file encountered
+$4D:    Position out of range
+$4E:    File access error, also file locked
+$50:    File is open
+$51:    Directory structure damaged
+$52:    Not a ProDOS volume
+$53:    Invalid system call parameter
+$55:    Volume Control Block table full
+$56:    Bad buffer address
+$57:    Duplicate volume
+$5A:    File structure damaged
+*/
+
+
+//
+// This is used mainly to initialize blank disks and upconvert non-WOZ disks
+//
+void FloppyDrive::InitWOZ(uint8_t driveNum/*= 0*/)
+{
+       // Sanity check
+       if (disk[driveNum] != NULL)
+       {
+               WriteLog("FLOPPY: Attempted to initialize non-NULL WOZ structure\n");
+               return;
+       }
+
+       diskSize[driveNum] = 256 + (35 * sizeof(WOZTrack));
+       disk[driveNum] = new uint8_t[diskSize[driveNum]];
+       woz[driveNum] = (WOZ *)disk[driveNum];
+
+       // Zero out WOZ image in memory
+       memset(woz[driveNum], 0, diskSize[driveNum]);
+
+       // Set up header (leave CRC as 0 for now)
+       memcpy(woz[driveNum]->magic, wozHeader, 8);
+
+       // INFO header
+       memcpy(woz[driveNum]->infoTag, "INFO", 4);
+       woz[driveNum]->infoSize = Uint32LE(60);
+       woz[driveNum]->infoVersion = 1;
+       woz[driveNum]->diskType = 1;
+       woz[driveNum]->writeProtected = 0;
+       woz[driveNum]->synchronized = 0;
+       woz[driveNum]->cleaned = 1;
+       memset(woz[driveNum]->creator, ' ', 32);
+       memcpy(woz[driveNum]->creator, "Apple2 emulator v1.0.0", 22);
+
+       // TMAP header
+       memcpy(woz[driveNum]->tmapTag, "TMAP", 4);
+       woz[driveNum]->tmapSize = Uint32LE(160);
+       memcpy(woz[driveNum]->tmap, standardTMAP, 141);
+
+       // TRKS header
+       memcpy(woz[driveNum]->trksTag, "TRKS", 4);
+       woz[driveNum]->trksSize = Uint32LE(35 * sizeof(WOZTrack));
+
+       for(int i=0; i<35; i++)
+       {
+               woz[driveNum]->track[i].bitCount = Uint16LE(51200);
+               woz[driveNum]->track[i].byteCount = Uint16LE((51200 + 7) / 8);
+       }
+
+       // META header (how to handle? prolly with a separate pointer)
+}
+
+
+//
+// Do basic sanity checks on the passed in contents (file loaded elsewhere).
+// Returns true if successful, false on failure.
+//
+bool FloppyDrive::CheckWOZ(const uint8_t * wozData, uint32_t wozSize, uint8_t driveNum/*= 0*/)
+{
+       // Hey!  This reference works!!  :-D
+       WOZ & woz1 = *((WOZ *)wozData);
+       woz[driveNum] = (WOZ *)wozData;
+
+       // Basic sanity checking
+       if (wozData == NULL)
+       {
+               WriteLog("FLOPPY: NULL pointer passed in to CheckWOZ()...\n");
+               return false;
+       }
+
+       if (memcmp(woz1.magic, wozHeader, 8) != 0)
+       {
+               WriteLog("FLOPPY: Invalid WOZ header in file\n");
+               return false;
+       }
+
+       uint32_t crc = CRC32(&wozData[12], wozSize - 12);
+       uint32_t wozCRC = Uint32LE(woz1.crc32);
+
+       if ((wozCRC != 0) && (wozCRC != crc))
+       {
+               WriteLog("FLOPPY: Corrupted data found in WOZ. CRC32: %08X, computed: %08X\n", wozCRC, crc);
+               return false;
+       }
+       else if (wozCRC == 0)
+               WriteLog("FLOPPY: Warning--WOZ file has no CRC...\n");
+
+#if 1
+       WriteLog("Track map:\n");
+       WriteLog("                                        1   1   1   1   1   1   1   1\n");
+       WriteLog("0.,.1.,.2.,.3.,.4.,.5.,.6.,.7.,.8.,.9.,.0.,.1.,.2.,.3.,.4.,.5.,.6.,.7.,.\n");
+       WriteLog("------------------------------------------------------------------------\n");
+
+       for(uint8_t j=0; j<2; j++)
+       {
+               for(uint8_t i=0; i<72; i++)
+               {
+                       char buf[64] = "..";
+                       buf[0] = buf[1] = '.';
+
+                       if (woz1.tmap[i] != 0xFF)
+                               sprintf(buf, "%02d", woz1.tmap[i]);
+
+                       WriteLog("%c", buf[j]);
+               }
+
+               WriteLog("\n");
+       }
+
+       WriteLog("\n1   1   2   2   2   2   2   2   2   2   2   2   3   3   3   3   3   3\n");
+       WriteLog("8.,.9.,.0.,.1.,.2.,.3.,.4.,.5.,.6.,.7.,.8.,.9.,.0.,.1.,.2.,.3.,.4.,.5\n");
+       WriteLog("---------------------------------------------------------------------\n");
+
+       for(uint8_t j=0; j<2; j++)
+       {
+               for(uint8_t i=72; i<141; i++)
+               {
+                       char buf[64] = "..";
+
+                       if (woz1.tmap[i] != 0xFF)
+                               sprintf(buf, "%02d", woz1.tmap[i]);
+
+                       WriteLog("%c", buf[j]);
+               }
+
+               WriteLog("\n");
+       }
+
+       WriteLog("\n");
+
+       uint8_t numTracks = woz1.trksSize / sizeof(WOZTrack);
+
+       // N.B.: Need to check the track[] to have this tell the correct track...  Right now, it doesn't
+       for(uint8_t i=0; i<numTracks; i++)
+       {
+               WriteLog("WOZ: Track %2.2f: %d bits (packed into %d bytes)\n", (float)i / 4.0f, woz1.track[i].bitCount, woz1.track[i].byteCount);
+       }
+#endif
+
+       WriteLog("FLOPPY: Well formed WOZ file found\n");
+       return true;
+}
+
+
+bool FloppyDrive::SaveWOZ(uint8_t driveNum)
+{
+       // Various sanity checks...
+       if (driveNum > 1)
+       {
+               WriteLog("FLOPPY: Attempted to save image to drive #%u!\n", driveNum);
+               return false;
+       }
+
+       if (diskType[driveNum] == DT_EMPTY)
+       {
+               WriteLog("FLOPPY: No image in drive #%u to save\n", driveNum);
+               return false;
+       }
+
+       if (!imageDirty[driveNum])
+       {
+               WriteLog("FLOPPY: No need to save unchanged image in drive #%u...\n", driveNum);
+               return false;
+       }
+
+       // Set up CRC32 before writing
+       woz[driveNum]->crc32 = Uint32LE(CRC32(&disk[driveNum][12], diskSize[driveNum] - 12));
+
+       // META header (skip for now) (actually, should be in the disk[] image already)
+
+       // Finally, write the damn image
+       FILE * fp = fopen(imageName[driveNum], "wb");
+
+       if (fp == NULL)
+       {
+               WriteLog("FLOPPY: Failed to open image file '%s' for writing...\n", imageName[driveNum]);
+               return false;
+       }
+
+       fwrite(disk[driveNum], 1, diskSize[driveNum], fp);
+       fclose(fp);
+
+       WriteLog("FLOPPY: Successfully wrote image file '%s'...\n", imageName[driveNum]);
+
+       return true;
+}
+
+
+// N.B.: The WOZ documentation says that the bitstream is normalized to 4µs.
+//       Which means on the //e that you would have to run it at that clock
+//       rate (instead of the //e clock rate 0.9799µs/cycle) to get the
+//       simulated drive running at 300 RPM.  So, instead of doing that, we're
+//       just gonna run it at twice the clock rate of the base 6502 clock,
+//       which will make the simulated drive run in the neighborhood of around
+//       306 RPM.  Should be close enough to get away with it.  :-)  (And it
+//       seems to run OK, for the most part.)
+
+
+static bool logSeq = false;
+//
+// Logic State Sequencer & Data Register
+//
+void FloppyDrive::RunSequencer(uint32_t cyclesToRun)
+{
+       static uint32_t prng = 1;
+
+       // Sanity checks
+       if (diskType[activeDrive] == DT_EMPTY)
+               return;
+       else if (motorOn == false)
+       {
+               if (driveOffTimeout == 0)
+                       return;
+               else
+                       driveOffTimeout--;
+       }
+
+       // It's x2 because the sequencer clock runs twice as fast as the CPU clock.
+       cyclesToRun *= 2;
+
+//extern bool dumpDis;
+//static bool tripwire = false;
+uint8_t chop = 0;
+//static uint32_t lastPos = 0;
+if (logSeq)
+{
+       WriteLog("DISKSEQ: Running for %d cycles [rw=%hhd, sl=%hhd, reg=%02X, bus=%02X]\n", cyclesToRun, rwSwitch, slSwitch, dataRegister, cpuDataBus);
+}
+
+       while (cyclesToRun-- > 0)
+       {
+               pulseClock = (pulseClock + 1) & 0x07;
+
+               if (pulseClock == 0)
+               {
+                       uint16_t bytePos = currentPos[activeDrive] / 8;
+                       uint8_t bitPos = currentPos[activeDrive] % 8;
+                       uint8_t tIdx = woz[activeDrive]->tmap[headPos[activeDrive]];
+
+                       if (tIdx != 0xFF)
+                       {
+                               if (woz[activeDrive]->track[tIdx].bits[bytePos] & bitMask[bitPos])
+                               {
+                                       // According to Jim Sather (Understanding the Apple II),
+                                       // the Read Pulse, when it happens, is 1µs long, which is 2
+                                       // sequencer clock pulses long.
+                                       readPulse = 2;
+                                       zeroBitCount = 0;
+                               }
+                               else
+                                       zeroBitCount++;
+#if 0
+                               currentPos[activeDrive] = (currentPos[activeDrive] + 1) % Uint16LE(woz[activeDrive]->track[tIdx].bitCount);
+                       }
+                       else
+                               currentPos[activeDrive] = (currentPos[activeDrive] + 1) % 51200;
+#else
+                       }
+
+//this doesn't work reliably for some reason...
+//seems to work OK now...
+                       currentPos[activeDrive] = (currentPos[activeDrive] + 1) % trackLength[activeDrive];
+#endif
+
+                       // If we hit more than 2 zero bits in a row, simulate the disk head
+                       // reader's Automatic Gain Control (AGC) turning itself up too high
+                       // by stuffing random bits in the bitstream.  We also do this if
+                       // the current track is marked as unformatted.
+/*
+N.B.: Had to up this to 3 because Up N' Down had some weird sync bytes (FE10).  May have to up it some more.
+*/
+                       if ((zeroBitCount > 3) || (tIdx == 0xFF))
+                       {
+                               if (prng & 0x00001)
+                               {
+                                       // This PRNG is called the "Galois configuration".
+                                       prng ^= 0x24000;
+                                       readPulse = 2;
+                               }
+
+                               prng >>= 1;
+                       }
+               }
+
+               // Find and run the Sequencer's next state
+               uint8_t nextState = (sequencerState & 0xF0) | (rwSwitch << 3)
+                       | (slSwitch << 2) | (readPulse ? 0x02 : 0)
+                       | ((dataRegister & 0x80) >> 7);
+if (logSeq)
+       WriteLog("[%02X:%02X]%s", sequencerState, nextState, (chop == 15 ? "\n" : ""));
+chop = (chop + 1) % 20;
+               sequencerState = sequencerROM[nextState];
+
+               switch (sequencerState & 0x0F)
+               {
+               case 0x00:
+               case 0x01:
+               case 0x02:
+               case 0x03:
+               case 0x04:
+               case 0x05:
+               case 0x06:
+               case 0x07:
+                       // CLR (clear data register)
+                       dataRegister = 0;
+                       break;
+               case 0x08:
+               case 0x0C:
+                       // NOP (no operation)
+                       break;
+               case 0x09:
+                       // SL0 (shift left, 0 fill LSB)
+                       dataRegister <<= 1;
+//if (!stopWriting)
+{
+                       uint8_t tIdx = woz[activeDrive]->tmap[headPos[activeDrive]];
+
+                       if (rwSwitch && (tIdx != 0xFF)
+                               && !woz[activeDrive]->writeProtected)
+                       {
+                               imageDirty[activeDrive] = true;
+                               uint16_t bytePos = currentPos[activeDrive] / 8;
+                               uint8_t bitPos = currentPos[activeDrive] % 8;
+
+                               if (dataRegister & 0x80)
+                                       // Fill in the one, if necessary
+                                       woz[activeDrive]->track[tIdx].bits[bytePos] |= bitMask[bitPos];
+                               else
+                                       // Otherwise, punch in the zero
+                                       woz[activeDrive]->track[tIdx].bits[bytePos] &= ~bitMask[bitPos];
+
+#if 0
+if (dumpDis || tripwire)
+{
+tripwire = true;
+WriteLog("[%s]", (dataRegister & 0x80 ? "1" : "0"));
+if (lastPos == currentPos[activeDrive])
+       WriteLog("{STOMP}");
+else if ((lastPos + 1) != currentPos[activeDrive])
+       WriteLog("{LAG}");
+lastPos = currentPos[activeDrive];
+}
+#endif
+                       }
+}
+                       break;
+               case 0x0A:
+               case 0x0E:
+                       // SR (shift right write protect bit)
+                       dataRegister >>= 1;
+                       dataRegister |= (woz[activeDrive]->writeProtected ? 0x80 : 0x00);
+                       break;
+               case 0x0B:
+               case 0x0F:
+                       // LD (load data register from data bus)
+                       dataRegister = cpuDataBus;
+//if (!stopWriting)
+{
+                       uint8_t tIdx = woz[activeDrive]->tmap[headPos[activeDrive]];
+
+                       if (rwSwitch && (tIdx != 0xFF)
+                               && !woz[activeDrive]->writeProtected)
+                       {
+                               imageDirty[activeDrive] = true;
+                               uint16_t bytePos = currentPos[activeDrive] / 8;
+                               uint8_t bitPos = currentPos[activeDrive] % 8;
+                               woz[activeDrive]->track[tIdx].bits[bytePos] |= bitMask[bitPos];
+#if 0
+if (dumpDis || tripwire)
+{
+tripwire = true;
+WriteLog("[%s]", (dataRegister & 0x80 ? "1" : "0"));
+if (lastPos == currentPos[activeDrive])
+       WriteLog("{STOMP}");
+else if ((lastPos + 1) != currentPos[activeDrive])
+       WriteLog("{LAG}");
+lastPos = currentPos[activeDrive];
+}
+#endif
+                       }
+}
+                       break;
+               case 0x0D:
+                       // SL1 (shift left, 1 fill LSB)
+                       dataRegister <<= 1;
+                       dataRegister |= 0x01;
+                       break;
+               }
+
+               if (readPulse > 0)
+                       readPulse--;
+       }
+
+if (logSeq)
+       WriteLog("\n");
+}
+
+
+FloppyDrive floppyDrive[2];
+
+static uint8_t SlotIOR(uint16_t address)
+{
+       uint8_t state = address & 0x0F;
+
+       switch (state)
+       {
+       case 0x00:
+       case 0x01:
+       case 0x02:
+       case 0x03:
+       case 0x04:
+       case 0x05:
+       case 0x06:
+       case 0x07:
+               floppyDrive[0].ControlStepper(state);
+               break;
+       case 0x08:
+       case 0x09:
+               floppyDrive[0].ControlMotor(state & 0x01);
+               break;
+       case 0x0A:
+       case 0x0B:
+               floppyDrive[0].DriveEnable(state & 0x01);
+               break;
+       case 0x0C:
+       case 0x0D:
+               floppyDrive[0].SetShiftLoadSwitch(state & 0x01);
+               break;
+       case 0x0E:
+       case 0x0F:
+               floppyDrive[0].SetReadWriteSwitch(state & 0x01);
+               break;
+       }
+
+       // Even addresses return the data register, odd (we suppose) returns a
+       // floating bus read...
+       return (address & 0x01 ? ReadFloatingBus(0) : floppyDrive[0].DataRegister());
+}
+
+
+static void SlotIOW(uint16_t address, uint8_t byte)
+{
+       uint8_t state = address & 0x0F;
+
+       switch (state)
+       {
+       case 0x00:
+       case 0x01:
+       case 0x02:
+       case 0x03:
+       case 0x04:
+       case 0x05:
+       case 0x06:
+       case 0x07:
+               floppyDrive[0].ControlStepper(state);
+               break;
+       case 0x08:
+       case 0x09:
+               floppyDrive[0].ControlMotor(state & 0x01);
+               break;
+       case 0x0A:
+       case 0x0B:
+               floppyDrive[0].DriveEnable(state & 0x01);
+               break;
+       case 0x0C:
+       case 0x0D:
+               floppyDrive[0].SetShiftLoadSwitch(state & 0x01);
+               break;
+       case 0x0E:
+       case 0x0F:
+               floppyDrive[0].SetReadWriteSwitch(state & 0x01);
+               break;
+       }
+
+       // Odd addresses write to the Data register, even addresses (we assume) go
+       // into the ether
+       if (state & 0x01)
+               floppyDrive[0].DataRegister(byte);
+}
+
+
+// This slot function doesn't need to differentiate between separate instances
+// of FloppyDrive
+static uint8_t SlotROM(uint16_t address)
+{
+       return diskROM[address];
+}
+
+
+void InstallFloppy(uint8_t slot)
+{
+       SlotData disk = { SlotIOR, SlotIOW, SlotROM, 0, 0, 0 };
+       InstallSlotHandler(slot, &disk);
+}
+
diff --git a/src/floppydrive.h b/src/floppydrive.h
new file mode 100644 (file)
index 0000000..a98415c
--- /dev/null
@@ -0,0 +1,210 @@
+//
+// Apple 2 floppy disk support
+//
+
+#ifndef __FLOPPY_H__
+#define __FLOPPY_H__
+
+// MAX_PATH isn't defined in stdlib.h on *nix, so we do it here...
+#ifdef __GCCUNIX__
+#include <limits.h>
+#define MAX_PATH       _POSIX_PATH_MAX
+#else
+#include <stdlib.h>            // for MAX_PATH on MinGW/Darwin
+// Kludge for Win64
+#ifndef MAX_PATH
+#define        MAX_PATH        _MAX_PATH
+#endif
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+
+enum { DT_EMPTY = 0, DT_WOZ, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE,
+       DFT_UNKNOWN };
+enum { DLS_OFF, DLS_READ, DLS_WRITE };
+
+// N.B.: All 32/16-bit values are stored in little endian.  Which means, to
+//       read/write them safely, we need to use translators as this code may or
+//       may not be compiled on an architecture that supports little endian
+//       natively.
+
+struct WOZTrack
+{
+       uint8_t bits[6646];
+       uint16_t byteCount;
+       uint16_t bitCount;
+       uint16_t splicePoint;
+       uint8_t spliceNibble;
+       uint8_t spliceBitCount;
+       uint16_t reserved;
+};
+
+struct WOZMetadata
+{
+       uint8_t metaTag[4];             // "META"
+       uint32_t metaSize;              // Size of the META chunk
+       uint8_t data[];                 // Variable length array of metadata
+};
+
+struct WOZ
+{
+       // Header
+       uint8_t magic[8];               // "WOZ1" $FF $0A $0D $0A
+       uint32_t crc32;                 // CRC32 of the remaining data in the file
+
+       // INFO chunk
+       uint8_t infoTag[4];             // "INFO"
+       uint32_t infoSize;              // Always 60 bytes long
+       uint8_t infoVersion;    // Currently 1
+       uint8_t diskType;               // 1 = 5 1/4", 2 = 3 1/2"
+       uint8_t writeProtected; // 1 = write protected disk
+       uint8_t synchronized;   // 1 = cross-track sync was used during imaging
+       uint8_t cleaned;                // 1 = fake bits removed from image
+       uint8_t creator[32];    // Software that made this image, padded with 0x20
+       uint8_t pad1[23];               // Padding to 60 bytes
+
+       // TMAP chunk
+       uint8_t tmapTag[4];             // "TMAP"
+       uint32_t tmapSize;              // Always 160 bytes long
+       uint8_t tmap[160];              // Track map, with empty tracks set to $FF
+
+       // TRKS chunk
+       uint8_t trksTag[4];             // "TRKS"
+       uint32_t trksSize;              // Varies, depending on # of tracks imaged
+       WOZTrack track[];               // Variable length array for the track data proper
+};
+
+struct WOZTrack2
+{
+       uint16_t startingBlock; // 512 byte block # where this track starts (relative to the start of the file)
+       uint16_t blockCount;    // # of blocks in this track
+       uint32_t bitCount;              // # of bits in this track
+};
+
+struct WOZ2
+{
+       // Header
+       uint8_t magic[8];               // "WOZ2" $FF $0A $0D $0A
+       uint32_t crc32;                 // CRC32 of the remaining data in the file
+
+       // INFO chunk
+       uint8_t infoTag[4];             // "INFO"
+       uint32_t infoSize;              // Always 60 bytes long
+       uint8_t infoVersion;    // Currently 1
+       uint8_t diskType;               // 1 = 5 1/4", 2 = 3 1/2"
+       uint8_t writeProtected; // 1 = write protected disk
+       uint8_t synchronized;   // 1 = cross-track sync was used during imaging
+       uint8_t cleaned;                // 1 = fake bits removed from image
+       uint8_t creator[32];    // Software that made this image, padded with 0x20
+       uint8_t diskSides;              // 5 1/4" disks always have 1 side (v2 from here on)
+       uint8_t bootSectorFmt;  // 5 1/4" only (0=unknown, 1=16 sector, 2=13 sector, 3=both)
+       uint8_t optimalBitTmg;  // In ticks, standard for 5 1/4" is 32 (4 Âµs)
+       uint16_t compatibleHW;  // Bitfield showing hardware compatibility (1=][, 2=][+, 4=//e (unenh), 8=//c, 16=//e (enh), 32=IIgs, 64=//c+, 128=///, 256=///+)
+       uint16_t requiredRAM;   // Minimum size in K, 0=unknown
+       uint16_t largestTrack;  // Number of 512 byte blocks used by largest track
+       uint8_t pad1[14];               // Padding to 60 bytes
+
+       // TMAP chunk
+       uint8_t tmapTag[4];             // "TMAP"
+       uint32_t tmapSize;              // Always 160 bytes long
+       uint8_t tmap[160];              // Track map, with empty tracks set to $FF
+
+       // TRKS chunk
+       uint8_t trksTag[4];             // "TRKS"
+       uint32_t trksSize;              // Varies, depending on # of tracks imaged
+       WOZTrack2 track[160];   // Actual track info (corresponding to TMAP data)
+       uint8_t data[];                 // Variable length array for the track data proper
+};
+
+class FloppyDrive
+{
+       public:
+               FloppyDrive();
+               ~FloppyDrive();
+
+               bool LoadImage(const char * filename, uint8_t driveNum = 0);
+               bool SaveImage(uint8_t driveNum = 0);
+               bool SaveImageAs(const char * filename, uint8_t driveNum = 0);
+               void CreateBlankImage(uint8_t driveNum = 0);
+               void SwapImages(void);
+               const char * ImageName(uint8_t driveNum = 0);
+               void EjectImage(uint8_t driveNum = 0);
+               bool IsEmpty(uint8_t driveNum = 0);
+               bool IsWriteProtected(uint8_t driveNum = 0);
+               void SetWriteProtect(bool, uint8_t driveNum = 0);
+               int DriveLightStatus(uint8_t driveNum = 0);
+               void SaveState(FILE *);
+               void LoadState(FILE *);
+               void InitWOZ(uint8_t driveNum = 0);
+               bool CheckWOZ(const uint8_t * wozData, uint32_t wozSize, uint8_t driveNum = 0);
+               bool SaveWOZ(uint8_t driveNum);
+
+       private:
+               uint32_t ReadLong(FILE *);
+               void WriteLong(FILE *, uint32_t);
+               void WriteLongLE(FILE *, uint32_t);
+               void WriteWordLE(FILE *, uint16_t);
+               void WriteZeroes(FILE *, uint32_t);
+
+               // I/O functions ($C0Ex accesses)
+
+       public:
+               void ControlStepper(uint8_t addr);
+               void ControlMotor(uint8_t addr);
+               void DriveEnable(uint8_t addr);
+               void SetShiftLoadSwitch(uint8_t state);
+               void SetReadWriteSwitch(uint8_t state);
+               uint8_t DataRegister(void);
+               void DataRegister(uint8_t);
+               void RunSequencer(uint32_t);
+
+       protected:
+               void DetectImageType(const char * filename, uint8_t driveNum);
+               void WriteBits(uint8_t * dest, uint8_t * src, uint16_t bits, uint16_t * start);
+               void WOZifyImage(uint8_t driveNum);
+
+       private:
+               char imageName[2][MAX_PATH];
+               uint8_t * disk[2];
+               uint32_t diskSize[2];
+               uint8_t diskType[2];
+               bool imageDirty[2];
+               uint8_t motorOn;
+               uint8_t activeDrive;
+               uint8_t ioMode;
+               uint8_t dataRegister;
+               uint8_t phase[2];
+               uint8_t headPos[2];
+               bool ioHappened;
+
+               uint32_t currentPos[2];
+               WOZ * woz[2];
+
+               uint8_t cpuDataBus;
+               uint8_t slSwitch;                       // Shift/Load soft switch
+               uint8_t rwSwitch;                       // Read/Write soft switch
+               uint8_t readPulse;                      // Disk read head "pulse" signal
+               uint8_t pulseClock;                     // Disk read head bitstream "pulse clock"
+               uint8_t sequencerState;
+               uint32_t driveOffTimeout;
+               uint8_t zeroBitCount;
+               uint16_t trackLength[2];
+
+               // And here are some private class variables (to reduce function
+               // redundancy):
+               static uint8_t doSector[16];
+               static uint8_t poSector[16];
+               static uint8_t wozHeader[9];
+               static uint8_t wozHeader2[9];
+               static uint8_t standardTMAP[141];
+               static uint8_t sequencerROM[256];
+               static uint8_t bitMask[8];
+               static char nameBuf[MAX_PATH];
+};
+
+void InstallFloppy(uint8_t slot);
+extern FloppyDrive floppyDrive[];
+
+#endif // __FLOPPY_H__
+
index d13d9bb7d112537b013f74affb6e229f5e891363..80595ee82e372fda31aaa2db345c05b1c2faddcf 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Floppy disk selector GUI
 // by James Hammons
-// Â© 2014 Underground Software
+// Â© 2014-2018 Underground Software
 //
 // JLH = James Hammons <jlhamm@acm.org>
 //
@@ -13,6 +13,8 @@
 //
 // STILL TO DO:
 //
+// - Fix bug where hovering on scroll image causes it to fly across the screen
+//   [DONE]
 //
 
 #include "diskselector.h"
@@ -20,7 +22,8 @@
 #include <algorithm>
 #include <string>
 #include <vector>
-#include "apple2.h"
+#include "crc32.h"
+#include "floppydrive.h"
 #include "font10pt.h"
 #include "gui.h"
 #include "log.h"
@@ -44,8 +47,6 @@ enum { DSS_SHOWING, DSS_HIDING, DSS_SHOWN, DSS_HIDDEN, DSS_LSB_SHOWING, DSS_LSB_
 #define DS_WIDTH                       402
 #define DS_HEIGHT                      322
 #define SCROLL_HOT_WIDTH       48
-// Need to add logic for left/right scroll buttons (they show when the mouse
-// is in the left or right hand portion of the rect).
 #define DS_XPOS        ((VIRTUAL_SCREEN_WIDTH - DS_WIDTH) / 2)
 #define DS_YPOS        ((VIRTUAL_SCREEN_HEIGHT - DS_HEIGHT) / 2)
 
@@ -69,6 +70,24 @@ So, how this will work for multiple columns, where the number of columns is grea
 */
 
 
+// We make provision for sets of 32 or less...
+/*
+The way the manifests are laid out, we make the assumption that the boot disk of a set is always listed first.  Therefore, image[0] will always be the boot disk.
+*/
+struct DiskSet
+{
+       uint8_t num;                    // # of disks in this set
+       std::string name;               // The name of this disk set
+//     std::string fullPath;   // The path to the containing folder
+       std::string image[32];  // List of disk images in this set
+       std::string imgName[32];// List of human readable names of disk images
+       uint32_t crc[32];               // List of CRC32s of the disk images in the set
+       uint32_t crcFound[32];  // List of CRC32s actually discovered on filesystem
+
+       DiskSet(): num(0) {}
+};
+
+
 //
 // Struct to hold filenames & full paths to same
 //
@@ -76,6 +95,10 @@ struct FileStruct
 {
        std::string image;
        std::string fullPath;
+       DiskSet diskSet;
+
+//     FileStruct(): diskSet(NULL) {}
+//     ~FileStruct() { if (diskSet != NULL) delete diskSet; }
 
        // Functor, to presumably make the std::sort go faster
        bool operator()(const FileStruct & a, const FileStruct & b) const
@@ -139,7 +162,9 @@ void DiskSelector::FindDisks(void)
        WriteLog("GUI (DiskSelector)::FindDisks(): # of columns is %i (%i files)\n", numColumns, fsList.size());
 }
 
-
+/*
+OK, so the way that you can determine if a file is a directory in a cross-platform way is to do an opendir() call on a discovered filename.  If it returns NULL, then it's a regular file and not a directory.  Though I think the Linux method is more elegant.  :-P
+*/
 //
 // Find all disks images within path (recursive call does depth first search)
 //
@@ -160,19 +185,63 @@ void DiskSelector::FindDisks(const char * path)
                char buf[0x10000];
                sprintf(buf, "%s/%s", path, ent->d_name);
 
-               if ((ent->d_type == DT_REG) && HasLegalExtension(ent->d_name))
+               // Cross-platform way to test if it's a directory...
+               DIR * test = opendir(buf);
+
+//             if ((ent->d_type == DT_REG) && HasLegalExtension(ent->d_name))
+               if (test == NULL)
                {
-                       FileStruct fs;
-                       fs.image = ent->d_name;
-                       fs.fullPath = buf;
-                       fsList.push_back(fs);
+                       if (HasLegalExtension(ent->d_name))
+                       {
+                               FileStruct fs;
+                               fs.image = ent->d_name;
+                               fs.fullPath = buf;
+                               fsList.push_back(fs);
+                       }
                }
-               else if (ent->d_type == DT_DIR)
+//             else if (ent->d_type == DT_DIR)
+               else
                {
+                       // Make sure we close the thing, since it's a bona-fide dir!
+                       closedir(test);
+
                        // Only recurse if the directory is not one of the special ones...
                        if ((strcmp(ent->d_name, "..") != 0)
                                && (strcmp(ent->d_name, ".") != 0))
-                               FindDisks(buf);
+                       {
+                               // Check to see if this is a special directory with a manifest
+                               char buf2[0x10000];
+                               sprintf(buf2, "%s/manifest.txt", buf);
+                               FILE * fp = fopen(buf2, "r");
+
+                               // No manifest means it's just a regular directory...
+                               if (fp == NULL)
+                                       FindDisks(buf);
+                               else
+                               {
+                                       // Read the manifest and all that good stuff
+                                       FileStruct fs;
+                                       ReadManifest(fp, &fs.diskSet);
+                                       fclose(fp);
+
+                                       // Finally, check that the stuff in the manifest is
+                                       // actually in the directory...
+                                       if (CheckManifest(buf, &fs.diskSet) == true)
+                                       {
+                                               fs.fullPath = buf;
+                                               fs.image = fs.diskSet.name;
+                                               fsList.push_back(fs);
+                                       }
+                                       else
+                                               WriteLog("Manifest for '%s' failed check phase.\n", fs.diskSet.name.c_str());
+#if 0
+                                       printf("Name found: \"%s\" (%d)\nDisks:\n", fs.diskSet.name.c_str(), fs.diskSet.num);
+                                       for(int i=0; i<fs.diskSet.num; i++)
+                                               printf("%s (CRC: %08X)\n", fs.diskSet.image[i].c_str(), fs.diskSet.crc[i]);
+#endif
+
+                               }
+                       }
                }
        }
 
@@ -180,6 +249,117 @@ void DiskSelector::FindDisks(const char * path)
 }
 
 
+void DiskSelector::ReadManifest(FILE * fp, DiskSet * ds)
+{
+       char line[0x10000];
+       int disksFound = 0;
+       int lineNo = 0;
+
+       while (!feof(fp))
+       {
+               fgets(line, 0x10000, fp);
+               lineNo++;
+
+               if ((line[0] == '#') || (line[0] == '\n'))
+                       ; // Do nothing with comments or blank lines...
+               else
+               {
+                       char buf[1024];
+                       char crcbuf[16];
+                       char altName[1024];
+
+                       if (strncmp(line, "diskset", 7) == 0)
+                       {
+                               sscanf(line, "diskset=\"%[^\"]\"", buf);
+                               ds->name = buf;
+                       }
+                       else if (strncmp(line, "disks", 5) == 0)
+                       {
+                               sscanf(line, "disks=%hhd", &ds->num);
+                       }
+                       else if (strncmp(line, "disk", 4) == 0)
+                       {
+                               int n = sscanf(line, "disk=%s %s (%s)", buf, crcbuf, altName);
+
+                               if ((n == 2) || (n == 3))
+                               {
+                                       ds->image[disksFound] = buf;
+                                       ds->crc[disksFound] = strtoul(crcbuf, NULL, 16);
+                                       disksFound++;
+
+                                       if (n == 3)
+                                               ds->imgName[disksFound] = altName;
+                                       else
+                                       {
+                                               // Find the file's extension, if any
+                                               char * ext = strrchr(buf, '.');
+
+                                               // Kill the disk extension, if it exists
+                                               if (ext != NULL)
+                                                       *ext = 0;
+
+                                               ds->imgName[disksFound] = buf;
+                                       }
+                               }
+                               else
+                                       WriteLog("Malformed disk descriptor in manifest at line %d\n", lineNo);
+                       }
+               }
+       }
+
+       if (disksFound != ds->num)
+               WriteLog("Found only %d entries in manifest, expected %hhd\n", disksFound, ds->num);
+}
+
+
+bool DiskSelector::CheckManifest(const char * path, DiskSet * ds)
+{
+       uint8_t found = 0;
+
+       for(int i=0; i<ds->num; i++)
+       {
+               std::string filename = path;
+               filename += "/";
+               filename += ds->image[i];
+               uint32_t size;
+               uint8_t * buf = ReadFile(filename.c_str(), &size);
+
+               if (buf != NULL)
+               {
+                       ds->crcFound[i] = CRC32(buf, size);
+                       free(buf);
+                       found++;
+
+                       if (ds->crc[i] != ds->crcFound[i])
+                       {
+                               WriteLog("Warning: Bad CRC32 for '%s'. Expected: %08X, found: %08X\n", ds->image[i], ds->crc[i], ds->crcFound[i]);
+                       }
+               }
+       }
+
+       return (found == ds->num ? true : false);
+}
+
+
+uint8_t * DiskSelector::ReadFile(const char * filename, uint32_t * size)
+{
+       FILE * fp = fopen(filename, "r");
+
+       if (!fp)
+               return NULL;
+
+       fseek(fp, 0, SEEK_END);
+       *size = ftell(fp);
+       fseek(fp, 0, SEEK_SET);
+
+       uint8_t * buffer = (uint8_t *)malloc(*size);
+       fread(buffer, 1, *size, fp);
+       fclose(fp);
+
+       return buffer;
+}
+
+
 bool DiskSelector::HasLegalExtension(const char * name)
 {
        // Find the file's extension, if any
@@ -194,7 +374,7 @@ bool DiskSelector::HasLegalExtension(const char * name)
        if ((strcasecmp(ext, ".dsk") == 0)
                || (strcasecmp(ext, ".do") == 0)
                || (strcasecmp(ext, ".po") == 0)
-               || (strcasecmp(ext, ".nib") == 0))
+               || (strcasecmp(ext, ".woz") == 0))
                return true;
 
        return false;
@@ -317,6 +497,7 @@ void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t
 
 void DiskSelector::ShowWindow(int drive)
 {
+       diskSelectorState = DSS_SHOWN;
        entered = false;
        showWindow = true;
        driveNumber = drive;
@@ -325,24 +506,18 @@ void DiskSelector::ShowWindow(int drive)
 
 void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
 {
-       if (!showWindow)
-               return;
-
-       if (!entered)
+       if (!showWindow || !entered)
                return;
 
        if ((diskSelectorState == DSS_LSB_SHOWING) || (diskSelectorState == DSS_LSB_SHOWN))
        {
-               if (colStart > 0)
-               {
-                       colStart--;
-                       textScrollCount = 21;
+               colStart--;
+               textScrollCount = 21;
 
-                       if (colStart == 0)
-                       {
-                               diskSelectorState = DSS_LSB_HIDING;
-                               dxLeft = -8;
-                       }
+               if (colStart == 0)
+               {
+                       diskSelectorState = DSS_LSB_HIDING;
+                       dxLeft = -8;
                }
 
                return;
@@ -350,16 +525,13 @@ void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
 
        if ((diskSelectorState == DSS_RSB_SHOWING) || (diskSelectorState == DSS_RSB_SHOWN))
        {
-               if (colStart + 3 < numColumns)
-               {
-                       colStart++;
-                       textScrollCount = -21;
+               colStart++;
+               textScrollCount = -21;
 
-                       if ((colStart + 3) == numColumns)
-                       {
-                               diskSelectorState = DSS_RSB_HIDING;
-                               dxRight = 8;
-                       }
+               if ((colStart + 3) == numColumns)
+               {
+                       diskSelectorState = DSS_RSB_HIDING;
+                       dxRight = 8;
                }
 
                return;
@@ -367,7 +539,7 @@ void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
 
        if (diskSelected != -1)
        {
-               floppyDrive.LoadImage(fsList[diskSelected].fullPath.c_str(), driveNumber);
+               floppyDrive[0].LoadImage(fsList[diskSelected].fullPath.c_str(), driveNumber);
        }
 
        showWindow = false;
@@ -395,60 +567,66 @@ void DiskSelector::MouseMove(int32_t x, int32_t y, uint32_t buttons)
 
        // Check to see if the DS, since being hovered, is now no longer being
        // hovered
+//N.B.: Should probably make like a 1/2 to 1 second timeout to allow for overshooting the edge of the thing, maybe have the window fade out gradually and let it come back if you enter before it leaves...
        if (entered && ((x < DS_XPOS) || (x > (DS_XPOS + DS_WIDTH))
                || (y < DS_YPOS) || (y > (DS_YPOS + DS_HEIGHT))))
        {
+               diskSelectorState = DSS_HIDDEN;
+               dxLeft = 0;
+               dxRight = 0;
+               rsbPos = DS_WIDTH;
+               lsbPos = -40;
                showWindow = false;
+               refresh = true;
                return;
        }
 
-       if (entered && (colStart > 0))
+       // Bail out if the DS hasn't been entered yet
+       if (!entered)
+               return;
+
+/*
+states:
++-----+---------------------+-----+
+|     |                     |     |
+|     |                     |     |
++-----+---------------------+-----+
+ ^           ^                ^
+ |           |                x is here and state is DSS_SHOWN
+ |           x is here and state is DSS_LSB_SHOWING or DSS_RSB_SHOWING
+ x is here and state is DSS_SHOWN
+
+*/
+       if (x < (DS_XPOS + SCROLL_HOT_WIDTH))
        {
-               if (diskSelectorState != DSS_LSB_SHOWN)
+               if ((colStart > 0) && (diskSelectorState == DSS_SHOWN))
                {
-                       if (x < (DS_XPOS + SCROLL_HOT_WIDTH))
-                       {
-                               diskSelectorState = DSS_LSB_SHOWING;
-                               dxLeft = 8;
-                       }
-                       else
-                       {
-                               diskSelectorState = DSS_LSB_HIDING;
-                               dxLeft = -8;
-                       }
+                       diskSelectorState = DSS_LSB_SHOWING;
+                       dxLeft = 8;
                }
-               else
+       }
+       else if (x > (DS_XPOS + DS_WIDTH - SCROLL_HOT_WIDTH))
+       {
+               if (((colStart + 3) < numColumns) && (diskSelectorState == DSS_SHOWN))
                {
-                       if (x >= (DS_XPOS + SCROLL_HOT_WIDTH))
-                       {
-                               diskSelectorState = DSS_LSB_HIDING;
-                               dxLeft = -8;
-                       }
+                       diskSelectorState = DSS_RSB_SHOWING;
+                       dxRight = -8;
                }
        }
-
-       if (entered && ((colStart + 3) < numColumns))
+       else
        {
-               if (diskSelectorState != DSS_RSB_SHOWN)
+               // Handle the excluded middle  :-P
+               if ((diskSelectorState == DSS_LSB_SHOWING)
+                       || (diskSelectorState == DSS_LSB_SHOWN))
                {
-                       if (x > (DS_XPOS + DS_WIDTH - SCROLL_HOT_WIDTH))
-                       {
-                               diskSelectorState = DSS_RSB_SHOWING;
-                               dxRight = -8;
-                       }
-                       else
-                       {
-                               diskSelectorState = DSS_RSB_HIDING;
-                               dxRight = 8;
-                       }
+                       diskSelectorState = DSS_LSB_HIDING;
+                       dxLeft = -8;
                }
-               else
+               else if ((diskSelectorState == DSS_RSB_SHOWING)
+                       || (diskSelectorState == DSS_RSB_SHOWN))
                {
-                       if (x <= (DS_XPOS + DS_WIDTH - SCROLL_HOT_WIDTH))
-                       {
-                               diskSelectorState = DSS_RSB_HIDING;
-                               dxRight = 8;
-                       }
+                       diskSelectorState = DSS_RSB_HIDING;
+                       dxRight = 8;
                }
        }
 
index 961e99a99fc88a35818fa3d4fd56efce95bb96c7..98891725575b877a86aa44408e0a61edbb85d349 100644 (file)
@@ -4,6 +4,9 @@
 #include <stdint.h>
 #include <SDL2/SDL.h>
 
+class DiskSet;
+class FileStruct;
+
 class DiskSelector
 {
        public:
@@ -14,6 +17,9 @@ class DiskSelector
                static void Init(SDL_Renderer *);
                static void FindDisks();
                static void FindDisks(const char *);
+               static void ReadManifest(FILE *, DiskSet *);
+               static bool CheckManifest(const char *, DiskSet *);
+               static uint8_t * ReadFile(const char *, uint32_t *);
                static bool HasLegalExtension(const char *);
                static void DrawFilenames(SDL_Renderer *);
                static void DrawCharacter(SDL_Renderer *, int, int, uint8_t, bool inv=false);
index 1ce4121f05c76210718b285cd619ed46477ea2f0..8a4f38d38bd6c653fe8c083fc3fd7835b02c9d14 100644 (file)
 #include <stdint.h>
 
 uint8_t font10pt[] = {
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x15, 0xAF, 0x06, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x02, 0xAE, 0x44, 0x42, 0xA5, 0x03, 
-       0x00, 0x9A, 0x39, 0x34, 0x97, 0x00, 
-       0x00, 0x7A, 0x2C, 0x25, 0x7A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x6D, 0x34, 0x87, 0x23, 
-       0x00, 0x03, 0xA9, 0x18, 0xB2, 0x06, 
-       0x26, 0xC6, 0xC4, 0xD3, 0xC0, 0x85, 
-       0x00, 0x2A, 0x74, 0x40, 0x5D, 0x00, 
-       0x00, 0x41, 0x5A, 0x68, 0x35, 0x00, 
-       0x7C, 0xDC, 0xB3, 0xE3, 0xAD, 0x30, 
-       0x03, 0xA9, 0x17, 0xAF, 0x06, 0x00, 
-       0x13, 0x87, 0x2C, 0x79, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x18, 0xDE, 0x39, 0x06, 0x00, 
-       0x05, 0xBA, 0xFD, 0x7B, 0x81, 0x02, 
-       0x16, 0xF5, 0xB9, 0x0A, 0x00, 0x13, 
-       0x11, 0xDA, 0xB9, 0x0A, 0x00, 0x13, 
-       0x00, 0x82, 0xC4, 0x2F, 0x00, 0x01, 
-       0x00, 0x18, 0xF0, 0xF2, 0x5B, 0x00, 
-       0x00, 0x16, 0xD9, 0x3D, 0xAA, 0x07, 
-       0x0C, 0x23, 0xD9, 0x51, 0xA0, 0x05, 
-       0x21, 0xC5, 0xFF, 0xA6, 0x26, 0x07, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x1A, 0x50, 
-       0x6A, 0xD4, 0x4F, 0x02, 0x9E, 0x54, 
-       0xDE, 0x3C, 0xD6, 0x55, 0x99, 0x03, 
-       0xDD, 0x36, 0xE4, 0xDA, 0x2A, 0x00, 
-       0x6B, 0xD5, 0xC7, 0x80, 0x00, 0x00, 
-       0x00, 0x18, 0xD5, 0x85, 0xD2, 0x4D, 
-       0x01, 0x90, 0x70, 0xDA, 0x3D, 0xA6, 
-       0x32, 0x9E, 0x1B, 0xDB, 0x32, 0xD7, 
-       0xB0, 0x31, 0x01, 0x79, 0xE4, 0x60, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x01, 0x00, 0x5A, 0xD2, 0x51, 0x00, 
-       0x00, 0x0C, 0xD5, 0x3C, 0xD5, 0x06, 
-       0x00, 0x13, 0xDE, 0x31, 0xD5, 0x06, 
-       0x00, 0x07, 0xC0, 0xB5, 0x70, 0x00, 
-       0x00, 0x19, 0xC6, 0x98, 0x05, 0x00, 
-       0x07, 0xB8, 0x6D, 0xD4, 0x0D, 0x1D, 
-       0x20, 0xDE, 0x0B, 0x8B, 0x87, 0x64, 
-       0x13, 0xDC, 0x2F, 0x15, 0xDA, 0xFC, 
-       0x00, 0x48, 0xDD, 0xA9, 0x77, 0xF7, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x96, 0x9B, 0x00, 0x00, 
-       0x00, 0x00, 0x76, 0x81, 0x00, 0x00, 
-       0x00, 0x00, 0x56, 0x65, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0xD5, 0x07, 0x00, 0x00, 0x00, 0x00, 
-       0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x30, 0x3D, 
-       0x00, 0x00, 0x02, 0x77, 0x93, 0x2D, 
-       0x00, 0x00, 0x49, 0x94, 0x04, 0x00, 
-       0x00, 0x03, 0xAD, 0x32, 0x00, 0x00, 
-       0x00, 0x10, 0xDE, 0x0D, 0x00, 0x00, 
-       0x00, 0x18, 0xDC, 0x08, 0x00, 0x00, 
-       0x00, 0x11, 0xDE, 0x0D, 0x00, 0x00, 
-       0x00, 0x04, 0xB0, 0x2F, 0x00, 0x00, 
-       0x00, 0x00, 0x51, 0x8E, 0x03, 0x00, 
-       0x00, 0x00, 0x02, 0x85, 0x89, 0x23, 
-       0x00, 0x00, 0x00, 0x00, 0x3E, 0x46, 
-
-       0x4E, 0x23, 0x00, 0x00, 0x00, 0x00, 
-       0x3C, 0xB5, 0x5A, 0x00, 0x00, 0x00, 
-       0x00, 0x0D, 0xC9, 0x28, 0x00, 0x00, 
-       0x00, 0x00, 0x59, 0x86, 0x00, 0x00, 
-       0x00, 0x00, 0x28, 0xA4, 0x06, 0x00, 
-       0x00, 0x00, 0x1C, 0xD9, 0x07, 0x00, 
-       0x00, 0x00, 0x27, 0xA3, 0x06, 0x00, 
-       0x00, 0x00, 0x54, 0x8A, 0x00, 0x00, 
-       0x00, 0x09, 0xC4, 0x2C, 0x00, 0x00, 
-       0x30, 0xAA, 0x64, 0x00, 0x00, 0x00, 
-       0x5A, 0x2F, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x4F, 0x59, 0x00, 0x00, 
-       0x07, 0x5B, 0x51, 0x5A, 0x56, 0x09, 
-       0x10, 0x8A, 0x52, 0x4A, 0x7D, 0x14, 
-       0x00, 0x18, 0xA5, 0x9F, 0x1E, 0x00, 
-       0x00, 0x4A, 0x4A, 0x42, 0x51, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x2F, 0xD1, 0xCB, 0xFE, 0xAA, 0x9F, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00, 
-       0x00, 0x1B, 0xD7, 0x07, 0x00, 0x00, 
-       0x00, 0x03, 0x8A, 0x04, 0x00, 0x00, 
-       0x00, 0x0C, 0x25, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x08, 0xAD, 0xD7, 0xD7, 0x9E, 0x0A, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x4F, 0x66, 
-       0x00, 0x00, 0x00, 0x05, 0xB1, 0x13, 
-       0x00, 0x00, 0x00, 0x36, 0x76, 0x00, 
-       0x00, 0x00, 0x02, 0x96, 0x22, 0x00, 
-       0x00, 0x00, 0x26, 0x83, 0x01, 0x00, 
-       0x00, 0x00, 0x85, 0x2D, 0x00, 0x00, 
-       0x00, 0x17, 0xB3, 0x03, 0x00, 0x00, 
-       0x00, 0x70, 0x3A, 0x00, 0x00, 0x00, 
-       0x0F, 0xB8, 0x06, 0x00, 0x00, 0x00, 
-       0x5A, 0x5C, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x08, 0x8B, 0xD3, 0x6C, 0x02, 
-       0x00, 0x6F, 0x71, 0x05, 0x94, 0x3C, 
-       0x06, 0xCA, 0x1A, 0x00, 0x38, 0x93, 
-       0x12, 0xDD, 0x0C, 0x00, 0x24, 0xD2, 
-       0x19, 0xDB, 0x08, 0x00, 0x1C, 0xD9, 
-       0x13, 0xDE, 0x0C, 0x00, 0x23, 0xD4, 
-       0x07, 0xCE, 0x18, 0x00, 0x35, 0x97, 
-       0x00, 0x7C, 0x66, 0x01, 0x88, 0x59, 
-       0x00, 0x0D, 0xA4, 0xAD, 0x80, 0x05, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 
-       0x03, 0x56, 0xB0, 0xB5, 0x0A, 0x00, 
-       0x07, 0x4F, 0x36, 0xDB, 0x0A, 0x00, 
-       0x06, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x08, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x07, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x01, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x0C, 0xB4, 0xCE, 0xFF, 0xAD, 0x8F, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x04, 0x88, 0xC5, 0x9E, 0x25, 0x00, 
-       0x02, 0x2F, 0x00, 0x50, 0xA3, 0x04, 
-       0x00, 0x00, 0x00, 0x23, 0xD8, 0x07, 
-       0x00, 0x00, 0x00, 0x6D, 0x83, 0x00, 
-       0x00, 0x00, 0x37, 0x97, 0x0D, 0x00, 
-       0x00, 0x1D, 0xC2, 0x10, 0x00, 0x00, 
-       0x03, 0x9F, 0x37, 0x00, 0x00, 0x00, 
-       0x1E, 0xF5, 0xAF, 0xD7, 0x91, 0x05, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x07, 0xA1, 0xC9, 0xA1, 0x2A, 0x00, 
-       0x03, 0x21, 0x01, 0x51, 0xA6, 0x04, 
-       0x00, 0x00, 0x00, 0x21, 0xD6, 0x07, 
-       0x00, 0x00, 0x02, 0x76, 0x70, 0x00, 
-       0x00, 0x4B, 0xD6, 0xAA, 0x0D, 0x00, 
-       0x00, 0x00, 0x02, 0x72, 0x8F, 0x01, 
-       0x00, 0x00, 0x00, 0x21, 0xD9, 0x07, 
-       0x02, 0x04, 0x00, 0x57, 0x9E, 0x03, 
-       0x15, 0xC3, 0xCD, 0xA2, 0x21, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x5C, 0xB7, 0x0A, 
-       0x00, 0x00, 0x14, 0xC7, 0xB6, 0x0A, 
-       0x00, 0x01, 0x83, 0x59, 0xDB, 0x0A, 
-       0x00, 0x2E, 0x85, 0x25, 0xDB, 0x0A, 
-       0x05, 0xB1, 0x20, 0x1B, 0xDB, 0x0A, 
-       0x17, 0xD8, 0xA6, 0xCB, 0xFE, 0x95, 
-       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A, 
-       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x17, 0xCB, 0xA8, 0xD3, 0x81, 0x01, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x18, 0xCE, 0xAE, 0x7A, 0x0B, 0x00, 
-       0x00, 0x00, 0x08, 0x81, 0x8E, 0x01, 
-       0x05, 0x00, 0x00, 0x21, 0xD8, 0x09, 
-       0x01, 0x01, 0x00, 0x5F, 0x9B, 0x02, 
-       0x15, 0xBD, 0xCD, 0x9E, 0x1C, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x01, 0x5F, 0xC1, 0xA6, 0x4F, 
-       0x00, 0x4C, 0xA2, 0x0D, 0x09, 0x21, 
-       0x04, 0xB2, 0x39, 0x00, 0x00, 0x00, 
-       0x0E, 0xE2, 0x15, 0x00, 0x00, 0x00, 
-       0x18, 0xE1, 0x7B, 0xC0, 0x92, 0x19, 
-       0x16, 0xEC, 0x35, 0x01, 0x6D, 0x9B, 
-       0x09, 0xCA, 0x0B, 0x00, 0x21, 0xD9, 
-       0x00, 0x89, 0x35, 0x00, 0x52, 0x95, 
-       0x00, 0x14, 0xAB, 0x9F, 0x9E, 0x1B, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x09, 0xAF, 0xD3, 0xC5, 0xAB, 0x0B, 
-       0x00, 0x00, 0x00, 0x20, 0x82, 0x01, 
-       0x00, 0x00, 0x00, 0x7E, 0x2C, 0x00, 
-       0x00, 0x00, 0x15, 0xB5, 0x03, 0x00, 
-       0x02, 0x00, 0x6E, 0x56, 0x00, 0x00, 
-       0x07, 0x0C, 0xCB, 0x13, 0x00, 0x00, 
-       0x02, 0x41, 0x99, 0x01, 0x00, 0x00, 
-       0x00, 0x82, 0x72, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x48, 0xBE, 0xA9, 0x4A, 0x00, 
-       0x0D, 0xD9, 0x19, 0x39, 0xAB, 0x06, 
-       0x15, 0xE3, 0x15, 0x2A, 0xA2, 0x05, 
-       0x02, 0x8E, 0x9A, 0xB5, 0x31, 0x00, 
-       0x00, 0x4C, 0xD3, 0xAA, 0x16, 0x00, 
-       0x07, 0xCD, 0x23, 0x93, 0x96, 0x01, 
-       0x18, 0xDD, 0x0B, 0x26, 0xDB, 0x09, 
-       0x0D, 0xDD, 0x25, 0x38, 0x9C, 0x03, 
-       0x00, 0x54, 0xDE, 0xA5, 0x26, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x17, 0xA3, 0xD8, 0x72, 0x04, 
-       0x02, 0xA1, 0x56, 0x03, 0x88, 0x5A, 
-       0x12, 0xDB, 0x0C, 0x00, 0x27, 0x94, 
-       0x16, 0xE1, 0x0D, 0x00, 0x22, 0xD5, 
-       0x05, 0xB6, 0x5F, 0x02, 0x72, 0xB6, 
-       0x00, 0x20, 0xAE, 0xA1, 0x5E, 0xA4, 
-       0x00, 0x00, 0x00, 0x00, 0x40, 0x8C, 
-       0x00, 0x0D, 0x00, 0x0A, 0xAE, 0x31, 
-       0x00, 0x7E, 0xAD, 0xDC, 0x5B, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x07, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x08, 0x16, 0xBA, 0x08, 0x00, 0x00, 
-       0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00, 
-       0x00, 0x1B, 0xD7, 0x07, 0x00, 0x00, 
-       0x00, 0x1B, 0x96, 0x04, 0x00, 0x00, 
-       0x00, 0x0C, 0x25, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x06, 0x65, 
-       0x00, 0x00, 0x02, 0x50, 0xCD, 0x62, 
-       0x00, 0x37, 0xB2, 0x79, 0x10, 0x00, 
-       0x06, 0x77, 0xA8, 0x41, 0x00, 0x00, 
-       0x00, 0x00, 0x17, 0x92, 0x95, 0x2E, 
-       0x00, 0x00, 0x00, 0x00, 0x2B, 0xA8, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 
-       0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 
-       0x68, 0xD2, 0xD3, 0xD3, 0xD3, 0x6D, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x6A, 0xD6, 0xD7, 0xD7, 0xD7, 0x6F, 
-       0x0B, 0x00, 0x00, 0x00, 0x00, 0x0A, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x6A, 0x06, 0x00, 0x00, 0x00, 0x00, 
-       0x64, 0xD0, 0x50, 0x02, 0x00, 0x00, 
-       0x00, 0x0F, 0x81, 0x9E, 0x3A, 0x00, 
-       0x00, 0x00, 0x3F, 0xC0, 0x72, 0x06, 
-       0x2B, 0xA6, 0x86, 0x17, 0x00, 0x00, 
-       0xA9, 0x2F, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x10, 0xA9, 0xAC, 0xA2, 0x42, 0x00, 
-       0x1A, 0xD9, 0x08, 0x39, 0xAA, 0x06, 
-       0x00, 0x00, 0x00, 0x30, 0xA1, 0x05, 
-       0x00, 0x00, 0x13, 0xC7, 0x33, 0x00, 
-       0x00, 0x02, 0x9E, 0x54, 0x00, 0x00, 
-       0x00, 0x11, 0xD9, 0x0C, 0x00, 0x00, 
-       0x00, 0x02, 0x1A, 0x00, 0x00, 0x00, 
-       0x00, 0x12, 0xAD, 0x06, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x4F, 0xBB, 0xA6, 0x3D, 
-       0x00, 0x37, 0xA1, 0x0E, 0x51, 0xA5, 
-       0x02, 0xA8, 0x3C, 0x4A, 0xCA, 0xB7, 
-       0x0D, 0xDD, 0x1E, 0xCE, 0x43, 0xDB, 
-       0x18, 0xDC, 0x25, 0xDD, 0x35, 0xE5, 
-       0x15, 0xDE, 0x24, 0xDE, 0x75, 0xB3, 
-       0x07, 0xD4, 0x2A, 0x93, 0x58, 0xDC, 
-       0x00, 0x7E, 0x89, 0x02, 0x0E, 0x01, 
-       0x00, 0x0C, 0xA3, 0xB5, 0x85, 0x08, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x08, 0x00, 0x95, 0x95, 0x00, 0x00, 
-       0x0A, 0x10, 0xBA, 0xD0, 0x14, 0x00, 
-       0x0A, 0x4A, 0x57, 0x77, 0x58, 0x00, 
-       0x0B, 0x9A, 0x13, 0x25, 0x92, 0x02, 
-       0x7A, 0xE1, 0xA8, 0xC6, 0xEF, 0x18, 
-       0x56, 0x3A, 0x00, 0x00, 0x6C, 0x65, 
-       0xAC, 0x14, 0x00, 0x00, 0x2B, 0x9F, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0xA0, 0xE8, 0x62, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x2B, 0xDC, 0x07, 
-       0x1B, 0xDB, 0x0B, 0x4F, 0x93, 0x02, 
-       0x1B, 0xF3, 0xA1, 0xBB, 0x4D, 0x02, 
-       0x1B, 0xDB, 0x0A, 0x09, 0x7B, 0x8A, 
-       0x1C, 0xDB, 0x0A, 0x00, 0x2B, 0xD9, 
-       0x20, 0xF3, 0xAD, 0xCC, 0xB0, 0x50, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x07, 0x80, 0xE2, 0xCD, 0x93, 
-       0x00, 0x80, 0x8D, 0x05, 0x00, 0x12, 
-       0x0C, 0xDC, 0x18, 0x00, 0x00, 0x00, 
-       0x18, 0xDC, 0x0B, 0x00, 0x00, 0x00, 
-       0x10, 0xDE, 0x19, 0x00, 0x00, 0x00, 
-       0x09, 0x86, 0x92, 0x09, 0x00, 0x06, 
-       0x00, 0x08, 0x86, 0xE6, 0xA9, 0x8D, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x21, 0xF3, 0xAD, 0xE1, 0x81, 0x0A, 
-       0x20, 0xDB, 0x0A, 0x04, 0x91, 0x7D, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x2C, 0xA6, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x1C, 0xD9, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x2C, 0xA1, 
-       0x1C, 0xDB, 0x0A, 0x06, 0x93, 0x68, 
-       0x21, 0xF3, 0x9F, 0xE3, 0x77, 0x04, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0xAD, 0xD7, 0xA4, 0x23, 
-       0x1D, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x23, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x26, 0xF3, 0xAA, 0xD3, 0x7D, 0x00, 
-       0x20, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1C, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0xAD, 0xD7, 0xD6, 0x50, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0xAD, 0xD7, 0xD6, 0x50, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0xAA, 0xD3, 0x91, 0x06, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x07, 0x7F, 0xDC, 0xCA, 0x95, 
-       0x00, 0x80, 0x8A, 0x04, 0x00, 0x0A, 
-       0x0C, 0xDC, 0x18, 0x00, 0x00, 0x00, 
-       0x18, 0xDC, 0x0B, 0x23, 0xBE, 0xA6, 
-       0x0D, 0xDD, 0x19, 0x00, 0x1B, 0xDB, 
-       0x00, 0x85, 0x91, 0x08, 0x1B, 0xDB, 
-       0x00, 0x08, 0x85, 0xE4, 0x9C, 0x99, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x22, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x1D, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x25, 0xF3, 0xAA, 0xD3, 0xCB, 0xB8, 
-       0x27, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x27, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x22, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0E, 0x92, 0xCE, 0xFF, 0xAD, 0x71, 
-       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x0E, 0x92, 0xCE, 0xFF, 0xAD, 0x71, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x1F, 0xBC, 0xCE, 0xB9, 0x0A, 
-       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A, 
-       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A, 
-       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A, 
-       0x00, 0x00, 0x00, 0x1C, 0xD8, 0x07, 
-       0x00, 0x07, 0x00, 0x39, 0xA0, 0x03, 
-       0x00, 0x71, 0xCA, 0xAD, 0x2E, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x09, 0xB7, 0x29, 
-       0x1B, 0xDB, 0x0B, 0x84, 0x59, 0x00, 
-       0x1B, 0xDB, 0x69, 0x7F, 0x02, 0x00, 
-       0x1B, 0xE7, 0xE5, 0x31, 0x00, 0x00, 
-       0x1B, 0xDB, 0x3D, 0xD8, 0x13, 0x00, 
-       0x1B, 0xDB, 0x0B, 0x5A, 0x9C, 0x07, 
-       0x1B, 0xDB, 0x0A, 0x01, 0x80, 0x82, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x23, 0xF3, 0xAD, 0xD7, 0xA8, 0x2F, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xF6, 0x69, 0x00, 0x85, 0xB9, 
-       0x1B, 0xEA, 0x8D, 0x07, 0xA7, 0xB3, 
-       0x1B, 0xDE, 0xAA, 0x28, 0x71, 0xDD, 
-       0x1B, 0xDB, 0x6D, 0x6B, 0x51, 0xDB, 
-       0x1B, 0xDB, 0x2E, 0xE1, 0x2D, 0xDB, 
-       0x1B, 0xDB, 0x0F, 0x5F, 0x24, 0xDB, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x27, 0xF5, 0x40, 0x00, 0x1B, 0xDB, 
-       0x27, 0xF6, 0xB3, 0x09, 0x1B, 0xDB, 
-       0x27, 0xE1, 0xB9, 0x69, 0x1C, 0xDB, 
-       0x27, 0xDB, 0x2E, 0xE2, 0x36, 0xDB, 
-       0x27, 0xDB, 0x0A, 0x89, 0x9A, 0xDF, 
-       0x27, 0xDB, 0x0A, 0x17, 0xDB, 0xB9, 
-       0x27, 0xDB, 0x0A, 0x00, 0x6D, 0xBA, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0A, 0x1B, 0xB4, 0xB0, 0x8F, 0x0C, 
-       0x0E, 0xA1, 0x5A, 0x00, 0x78, 0x79, 
-       0x1F, 0xDE, 0x0E, 0x00, 0x2A, 0xA4, 
-       0x26, 0xDC, 0x08, 0x00, 0x1C, 0xD9, 
-       0x1F, 0xDE, 0x0E, 0x00, 0x2A, 0xA4, 
-       0x0E, 0xA0, 0x59, 0x00, 0x77, 0x7A, 
-       0x0A, 0x1B, 0xB5, 0x9F, 0x91, 0x0C, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0xAD, 0xCB, 0xB3, 0x53, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x31, 0xDA, 
-       0x1B, 0xDB, 0x0A, 0x02, 0x62, 0x9B, 
-       0x1B, 0xF3, 0xAA, 0xA6, 0x7F, 0x14, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x1B, 0xB4, 0xB0, 0x8F, 0x0C, 
-       0x0B, 0xA1, 0x5A, 0x00, 0x78, 0x79, 
-       0x14, 0xDE, 0x0E, 0x00, 0x2A, 0xA4, 
-       0x19, 0xDC, 0x08, 0x00, 0x1C, 0xD9, 
-       0x10, 0xDD, 0x0E, 0x00, 0x2A, 0xA3, 
-       0x02, 0x9F, 0x59, 0x00, 0x77, 0x76, 
-       0x00, 0x1B, 0xB8, 0xD6, 0xA3, 0x0B, 
-       0x00, 0x00, 0x00, 0x0D, 0xA9, 0x88, 
-       0x00, 0x00, 0x00, 0x00, 0x05, 0x52, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xF3, 0x9F, 0xE9, 0x65, 0x00, 
-       0x1D, 0xDB, 0x0A, 0x2A, 0xDB, 0x07, 
-       0x22, 0xDB, 0x0B, 0x57, 0x95, 0x02, 
-       0x26, 0xF3, 0xD5, 0xAB, 0x0F, 0x00, 
-       0x21, 0xDB, 0x17, 0xCC, 0x23, 0x00, 
-       0x1C, 0xDB, 0x0A, 0x4E, 0x9A, 0x04, 
-       0x1B, 0xDB, 0x0A, 0x04, 0xA8, 0x61, 
-       0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x01, 0x65, 0xDC, 0xC9, 0xAB, 0x32, 
-       0x13, 0xE0, 0x13, 0x00, 0x05, 0x0C, 
-       0x0C, 0xCC, 0x73, 0x12, 0x00, 0x00, 
-       0x00, 0x1D, 0x92, 0xF2, 0x9B, 0x22, 
-       0x00, 0x00, 0x00, 0x06, 0x72, 0xA8, 
-       0x0B, 0x1E, 0x00, 0x00, 0x3A, 0xA4, 
-       0x19, 0xB6, 0xB0, 0xCA, 0xA0, 0x27, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x5D, 0xD6, 0xCE, 0xFF, 0xAD, 0xD6, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x05, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x05, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x54, 0xDB, 0x0A, 0x00, 0x1B, 0xE1, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB, 
-       0x18, 0xDD, 0x0B, 0x00, 0x21, 0xD6, 
-       0x07, 0xD3, 0x2E, 0x00, 0x56, 0x97, 
-       0x00, 0x3F, 0xC6, 0x9C, 0xA0, 0x1E, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0xC0, 0x36, 0x00, 0x00, 0x15, 0xC4, 
-       0x70, 0x8B, 0x00, 0x00, 0x5B, 0x64, 
-       0x24, 0xDB, 0x11, 0x04, 0xB4, 0x18, 
-       0x0B, 0xA3, 0x42, 0x24, 0x90, 0x02, 
-       0x07, 0x51, 0x9A, 0x7B, 0x56, 0x00, 
-       0x01, 0x12, 0xD5, 0xB1, 0x13, 0x00, 
-       0x00, 0x01, 0x9C, 0x93, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0xC7, 0x0C, 0x00, 0x00, 0x06, 0xAD, 
-       0x9D, 0x1A, 0x36, 0x41, 0x0E, 0xAD, 
-       0x83, 0x32, 0x93, 0x9E, 0x28, 0x75, 
-       0x62, 0x5C, 0xA7, 0xC9, 0x4E, 0x5D, 
-       0x3C, 0x83, 0x84, 0x94, 0x69, 0x35, 
-       0x28, 0xE3, 0x65, 0x61, 0xAF, 0x24, 
-       0x13, 0xEF, 0x32, 0x2F, 0xED, 0x0D, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x6E, 0x99, 0x04, 0x00, 0x65, 0x6E, 
-       0x07, 0xA8, 0x5D, 0x29, 0x93, 0x07, 
-       0x00, 0x20, 0xE1, 0xD0, 0x23, 0x00, 
-       0x00, 0x00, 0x98, 0xA2, 0x03, 0x00, 
-       0x00, 0x32, 0x95, 0xBE, 0x55, 0x00, 
-       0x0E, 0xBF, 0x16, 0x2A, 0xDD, 0x13, 
-       0x85, 0x54, 0x00, 0x00, 0x74, 0x8B, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x2F, 0xD9, 0x0E, 0x00, 0x06, 0xB6, 
-       0x01, 0x8D, 0x72, 0x00, 0x61, 0x72, 
-       0x00, 0x17, 0xDB, 0x3C, 0xC9, 0x0E, 
-       0x00, 0x00, 0x6C, 0xFB, 0x3D, 0x00, 
-       0x00, 0x00, 0x1B, 0xDC, 0x08, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x02, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x27, 0x8E, 0xD7, 0xD7, 0xCF, 0xC0, 
-       0x00, 0x00, 0x00, 0x01, 0x83, 0x72, 
-       0x00, 0x00, 0x00, 0x49, 0x9B, 0x07, 
-       0x00, 0x00, 0x1B, 0xD3, 0x20, 0x00, 
-       0x00, 0x05, 0xA6, 0x53, 0x00, 0x00, 
-       0x00, 0x6F, 0x84, 0x01, 0x00, 0x00, 
-       0x0B, 0xDA, 0xB4, 0xD7, 0xD7, 0xA0, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x1B, 0xF3, 0xAD, 0xA1, 0x14, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x0C, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x10, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x17, 0xCB, 0xA8, 0x9E, 0x13, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x5A, 0x5C, 0x00, 0x00, 0x00, 0x00, 
-       0x0F, 0xB8, 0x06, 0x00, 0x00, 0x00, 
-       0x00, 0x71, 0x39, 0x00, 0x00, 0x00, 
-       0x00, 0x17, 0xB2, 0x03, 0x00, 0x00, 
-       0x00, 0x00, 0x85, 0x2C, 0x00, 0x00, 
-       0x00, 0x00, 0x26, 0x82, 0x01, 0x00, 
-       0x00, 0x00, 0x02, 0x96, 0x19, 0x00, 
-       0x00, 0x00, 0x00, 0x36, 0x74, 0x00, 
-       0x00, 0x00, 0x00, 0x05, 0xB0, 0x12, 
-       0x00, 0x00, 0x00, 0x00, 0x4F, 0x62, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x2B, 0xC2, 0xCE, 0xB9, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x2B, 0xBE, 0xC8, 0xA6, 0x07, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 
-       0x00, 0x00, 0x4B, 0x57, 0x00, 0x00, 
-       0x00, 0x03, 0xA9, 0xA1, 0x04, 0x00, 
-       0x00, 0x24, 0x87, 0x8C, 0x2B, 0x00, 
-       0x00, 0x7C, 0x33, 0x2D, 0x7C, 0x00, 
-       0x0E, 0xB9, 0x06, 0x05, 0xB0, 0x12, 
-       0x51, 0x63, 0x00, 0x00, 0x57, 0x5B, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0xB2, 0xD7, 0xD7, 0xD7, 0xD7, 0x9F, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x03, 0x61, 0x7A, 0x08, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x67, 0xC0, 0xE9, 0x72, 0x00, 
-       0x00, 0x0D, 0x00, 0x25, 0xD9, 0x07, 
-       0x00, 0x37, 0xB5, 0xCE, 0xB8, 0x0A, 
-       0x0B, 0xD8, 0x2C, 0x1B, 0xDB, 0x0A, 
-       0x16, 0xE1, 0x13, 0x3C, 0xE7, 0x0B, 
-       0x02, 0x87, 0xB1, 0x7A, 0xAC, 0x85, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDF, 0x81, 0xC5, 0xAC, 0x24, 
-       0x1B, 0xF0, 0x52, 0x00, 0x56, 0x99, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x22, 0xD9, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x24, 0xD5, 
-       0x1B, 0xE9, 0x29, 0x00, 0x6B, 0x84, 
-       0x24, 0xD4, 0x9F, 0xCA, 0x98, 0x0F, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x20, 0xB2, 0xAF, 0xDA, 0x38, 
-       0x08, 0xB3, 0x5E, 0x00, 0x00, 0x06, 
-       0x21, 0xDF, 0x0C, 0x00, 0x00, 0x00, 
-       0x1F, 0xDF, 0x0C, 0x00, 0x00, 0x00, 
-       0x06, 0xB4, 0x5E, 0x00, 0x00, 0x05, 
-       0x00, 0x22, 0xB6, 0xB0, 0xD5, 0x36, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB, 
-       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB, 
-       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB, 
-       0x00, 0x24, 0xBE, 0xAC, 0x7E, 0xE2, 
-       0x04, 0xAE, 0x52, 0x00, 0x4E, 0xE4, 
-       0x13, 0xDF, 0x0C, 0x00, 0x1B, 0xDB, 
-       0x18, 0xDF, 0x09, 0x00, 0x1B, 0xDB, 
-       0x07, 0xD4, 0x2E, 0x01, 0x6F, 0xB7, 
-       0x00, 0x46, 0xE2, 0xA5, 0x62, 0xDD, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0A, 0x18, 0xA8, 0xC9, 0xAA, 0x2D, 
-       0x0F, 0x9F, 0x2B, 0x00, 0x33, 0x9D, 
-       0x21, 0xEE, 0xAA, 0xD3, 0xC8, 0xA5, 
-       0x23, 0xE0, 0x0D, 0x00, 0x00, 0x00, 
-       0x0E, 0xB4, 0x61, 0x00, 0x00, 0x13, 
-       0x0A, 0x1D, 0xAC, 0xAF, 0xCA, 0x91, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x69, 0xE3, 0x9B, 0x7C, 
-       0x00, 0x10, 0xE0, 0x18, 0x00, 0x02, 
-       0x00, 0x1A, 0xDB, 0x08, 0x00, 0x00, 
-       0x67, 0xCE, 0xFF, 0xAD, 0xD6, 0x58, 
-       0x03, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x07, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x01, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x05, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x21, 0xBC, 0xAB, 0x79, 0xDF, 
-       0x03, 0xAB, 0x52, 0x00, 0x52, 0xB4, 
-       0x13, 0xDE, 0x0C, 0x00, 0x1B, 0xDB, 
-       0x18, 0xDF, 0x09, 0x00, 0x1B, 0xDB, 
-       0x08, 0xD2, 0x32, 0x01, 0x72, 0xB7, 
-       0x00, 0x41, 0xE2, 0xA8, 0x6A, 0xD6, 
-       0x00, 0x06, 0x00, 0x00, 0x41, 0x8F, 
-       0x00, 0x71, 0xD9, 0xC9, 0x9A, 0x1B, 
-
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x26, 0xE1, 0x93, 0xD5, 0x76, 0x00, 
-       0x26, 0xF2, 0x39, 0x29, 0xDA, 0x07, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x24, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x15, 0xAF, 0x06, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0E, 0xB5, 0xCE, 0xB9, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x15, 0xAF, 0x06, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x25, 0xBF, 0xCE, 0xB9, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDA, 0x08, 0x00, 
-       0x09, 0x00, 0x2E, 0xA1, 0x05, 0x00, 
-       0x70, 0xDA, 0xDE, 0x49, 0x00, 0x00, 
-
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x36, 0x98, 0x08, 
-       0x1B, 0xDB, 0x25, 0xCB, 0x1E, 0x00, 
-       0x1B, 0xE5, 0xC1, 0x3F, 0x00, 0x00, 
-       0x1B, 0xDF, 0x96, 0x99, 0x06, 0x00, 
-       0x1B, 0xDB, 0x13, 0xAA, 0x79, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x14, 0xC9, 0x53, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x1C, 0xBB, 0xCE, 0xB9, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xE1, 0x9D, 0x90, 0x93, 0x92, 
-       0x1B, 0xF0, 0x4C, 0xEE, 0x47, 0xD9, 
-       0x1B, 0xDC, 0x28, 0xDB, 0x28, 0xDB, 
-       0x1B, 0xDB, 0x28, 0xDB, 0x28, 0xDB, 
-       0x1B, 0xDB, 0x28, 0xDB, 0x28, 0xDB, 
-       0x1B, 0xDB, 0x28, 0xDB, 0x28, 0xDB, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x24, 0xE1, 0x93, 0xD5, 0x76, 0x00, 
-       0x25, 0xF2, 0x39, 0x29, 0xDA, 0x07, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x27, 0xBE, 0xA1, 0x9A, 0x17, 
-       0x05, 0xB5, 0x3D, 0x00, 0x6D, 0x8D, 
-       0x15, 0xDE, 0x0C, 0x00, 0x23, 0xD7, 
-       0x15, 0xDE, 0x0C, 0x00, 0x23, 0xD7, 
-       0x05, 0xB6, 0x3B, 0x01, 0x6B, 0x8E, 
-       0x00, 0x29, 0xBF, 0xA1, 0x9B, 0x18, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xDF, 0x81, 0xC5, 0xAB, 0x24, 
-       0x1B, 0xF0, 0x51, 0x00, 0x56, 0x99, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x22, 0xD9, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x24, 0xD5, 
-       0x1B, 0xE9, 0x29, 0x00, 0x6B, 0x84, 
-       0x1B, 0xE6, 0xA6, 0xCA, 0x98, 0x0F, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x24, 0xBE, 0xAC, 0x75, 0xD9, 
-       0x07, 0xAE, 0x52, 0x00, 0x4E, 0xE4, 
-       0x20, 0xDF, 0x0C, 0x00, 0x1B, 0xDB, 
-       0x21, 0xDF, 0x09, 0x00, 0x1B, 0xDB, 
-       0x08, 0xD4, 0x2E, 0x01, 0x6F, 0xB7, 
-       0x00, 0x46, 0xE2, 0xA5, 0x62, 0xDD, 
-       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB, 
-       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0A, 0x1B, 0xDF, 0x83, 0xC5, 0xAE, 
-       0x0A, 0x1B, 0xF5, 0x5D, 0x04, 0x6F, 
-       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x0D, 0x80, 0xE3, 0xD9, 0x72, 0x00, 
-       0x1C, 0xE3, 0x13, 0x00, 0x05, 0x00, 
-       0x06, 0xAE, 0xAC, 0x55, 0x06, 0x00, 
-       0x00, 0x03, 0x46, 0xB5, 0x99, 0x02, 
-       0x0A, 0x0D, 0x00, 0x2E, 0xD9, 0x07, 
-       0x22, 0xBF, 0x9D, 0xB0, 0x4D, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x49, 0xCD, 0xFF, 0xAD, 0xA7, 0x2D, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x1A, 0xDB, 0x0A, 0x00, 0x00, 
-       0x00, 0x13, 0xDE, 0x12, 0x00, 0x00, 
-       0x00, 0x02, 0x86, 0xEE, 0xAB, 0x39, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0B, 
-       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A, 
-       0x16, 0xE3, 0x14, 0x70, 0xB8, 0x0A, 
-       0x03, 0x9C, 0xBC, 0x70, 0xDE, 0x0A, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x75, 0x6F, 0x00, 0x00, 0x3E, 0x7B, 
-       0x24, 0xD0, 0x06, 0x02, 0x97, 0x2A, 
-       0x03, 0xAD, 0x2F, 0x18, 0xBD, 0x04, 
-       0x00, 0x5B, 0x82, 0x66, 0x60, 0x00, 
-       0x00, 0x15, 0xDC, 0xD2, 0x15, 0x00, 
-       0x00, 0x01, 0x9E, 0x94, 0x01, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0xC3, 0x13, 0x29, 0x39, 0x07, 0xAF, 
-       0x9A, 0x2C, 0x89, 0x9B, 0x12, 0xAD, 
-       0x78, 0x44, 0xA1, 0xB3, 0x30, 0x6F, 
-       0x47, 0x84, 0x70, 0x7D, 0x62, 0x3F, 
-       0x2C, 0xEA, 0x3D, 0x45, 0xA9, 0x29, 
-       0x13, 0xE9, 0x19, 0x23, 0xE9, 0x0D, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x3F, 0xE2, 0x15, 0x06, 0xBA, 0x27, 
-       0x02, 0x7C, 0x91, 0x67, 0x75, 0x00, 
-       0x00, 0x0C, 0xC3, 0xB2, 0x0E, 0x00, 
-       0x00, 0x0E, 0xC2, 0xB8, 0x13, 0x00, 
-       0x00, 0x7F, 0x62, 0x7F, 0x8D, 0x02, 
-       0x32, 0x94, 0x04, 0x0C, 0xC0, 0x3E, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x53, 0x87, 0x00, 0x00, 0x3D, 0x79, 
-       0x10, 0xD1, 0x12, 0x02, 0x99, 0x27, 
-       0x00, 0x85, 0x5E, 0x1C, 0x91, 0x03, 
-       0x00, 0x2A, 0x9E, 0x7B, 0x54, 0x00, 
-       0x00, 0x04, 0xB4, 0xB2, 0x0C, 0x00, 
-       0x00, 0x00, 0x66, 0x7C, 0x00, 0x00, 
-       0x00, 0x05, 0xA6, 0x26, 0x00, 0x00, 
-       0x2F, 0xDE, 0x70, 0x01, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x05, 0x9E, 0xD7, 0xC9, 0xFB, 0x72, 
-       0x00, 0x00, 0x00, 0x29, 0xD4, 0x12, 
-       0x00, 0x00, 0x0F, 0xCB, 0x2F, 0x00, 
-       0x00, 0x03, 0x98, 0x65, 0x00, 0x00, 
-       0x00, 0x68, 0x8A, 0x03, 0x00, 0x00, 
-       0x0B, 0xDA, 0xB5, 0xD7, 0xD7, 0x6C, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x02, 0x85, 0xB3, 0x4D, 
-       0x00, 0x00, 0x17, 0xE1, 0x0D, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x2F, 0xA0, 0x05, 0x00, 
-       0x00, 0x39, 0xF1, 0x54, 0x00, 0x00, 
-       0x00, 0x00, 0x2A, 0xD4, 0x06, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x19, 0xE1, 0x0D, 0x00, 
-       0x00, 0x00, 0x03, 0x7E, 0xD6, 0x4C, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x6E, 0xE2, 0x61, 0x00, 0x00, 
-       0x00, 0x00, 0x27, 0xDA, 0x07, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x1A, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x0D, 0xD8, 0x15, 0x00, 
-       0x00, 0x00, 0x00, 0x76, 0xB8, 0x24, 
-       0x00, 0x00, 0x13, 0xDD, 0x13, 0x00, 
-       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00, 
-       0x00, 0x00, 0x27, 0xDD, 0x08, 0x00, 
-       0x00, 0x6C, 0xD7, 0x62, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x01, 0x70, 0xD2, 0x67, 0x0B, 0x72, 
-       0x07, 0x79, 0x0A, 0x69, 0xD2, 0x71, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+// " "
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// !
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x15, 0xAF, 0x06, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// "
+       0x02, 0xAE, 0x44, 0x42, 0xA5, 0x03,
+       0x00, 0x9A, 0x39, 0x34, 0x97, 0x00,
+       0x00, 0x7A, 0x2C, 0x25, 0x7A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// #
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x6D, 0x34, 0x87, 0x23,
+       0x00, 0x03, 0xA9, 0x18, 0xB2, 0x06,
+       0x26, 0xC6, 0xC4, 0xD3, 0xC0, 0x85,
+       0x00, 0x2A, 0x74, 0x40, 0x5D, 0x00,
+       0x00, 0x41, 0x5A, 0x68, 0x35, 0x00,
+       0x7C, 0xDC, 0xB3, 0xE3, 0xAD, 0x30,
+       0x03, 0xA9, 0x17, 0xAF, 0x06, 0x00,
+       0x13, 0x87, 0x2C, 0x79, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// $
+       0x00, 0x18, 0xDE, 0x39, 0x06, 0x00,
+       0x05, 0xBA, 0xFD, 0x7B, 0x81, 0x02,
+       0x16, 0xF5, 0xB9, 0x0A, 0x00, 0x13,
+       0x11, 0xDA, 0xB9, 0x0A, 0x00, 0x13,
+       0x00, 0x82, 0xC4, 0x2F, 0x00, 0x01,
+       0x00, 0x18, 0xF0, 0xF2, 0x5B, 0x00,
+       0x00, 0x16, 0xD9, 0x3D, 0xAA, 0x07,
+       0x0C, 0x23, 0xD9, 0x51, 0xA0, 0x05,
+       0x21, 0xC5, 0xFF, 0xA6, 0x26, 0x07,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// %
+       0x00, 0x00, 0x00, 0x00, 0x1A, 0x50,
+       0x6A, 0xD4, 0x4F, 0x02, 0x9E, 0x54,
+       0xDE, 0x3C, 0xD6, 0x55, 0x99, 0x03,
+       0xDD, 0x36, 0xE4, 0xDA, 0x2A, 0x00,
+       0x6B, 0xD5, 0xC7, 0x80, 0x00, 0x00,
+       0x00, 0x18, 0xD5, 0x85, 0xD2, 0x4D,
+       0x01, 0x90, 0x70, 0xDA, 0x3D, 0xA6,
+       0x32, 0x9E, 0x1B, 0xDB, 0x32, 0xD7,
+       0xB0, 0x31, 0x01, 0x79, 0xE4, 0x60,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// &
+       0x01, 0x00, 0x5A, 0xD2, 0x51, 0x00,
+       0x00, 0x0C, 0xD5, 0x3C, 0xD5, 0x06,
+       0x00, 0x13, 0xDE, 0x31, 0xD5, 0x06,
+       0x00, 0x07, 0xC0, 0xB5, 0x70, 0x00,
+       0x00, 0x19, 0xC6, 0x98, 0x05, 0x00,
+       0x07, 0xB8, 0x6D, 0xD4, 0x0D, 0x1D,
+       0x20, 0xDE, 0x0B, 0x8B, 0x87, 0x64,
+       0x13, 0xDC, 0x2F, 0x15, 0xDA, 0xFC,
+       0x00, 0x48, 0xDD, 0xA9, 0x77, 0xF7,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// '
+       0x00, 0x00, 0x96, 0x9B, 0x00, 0x00,
+       0x00, 0x00, 0x76, 0x81, 0x00, 0x00,
+       0x00, 0x00, 0x56, 0x65, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// (
+       0x00, 0x00, 0x00, 0x00, 0x30, 0x3D,
+       0x00, 0x00, 0x02, 0x77, 0x93, 0x2D,
+       0x00, 0x00, 0x49, 0x94, 0x04, 0x00,
+       0x00, 0x03, 0xAD, 0x32, 0x00, 0x00,
+       0x00, 0x10, 0xDE, 0x0D, 0x00, 0x00,
+       0x00, 0x18, 0xDC, 0x08, 0x00, 0x00,
+       0x00, 0x11, 0xDE, 0x0D, 0x00, 0x00,
+       0x00, 0x04, 0xB0, 0x2F, 0x00, 0x00,
+       0x00, 0x00, 0x51, 0x8E, 0x03, 0x00,
+       0x00, 0x00, 0x02, 0x85, 0x89, 0x23,
+       0x00, 0x00, 0x00, 0x00, 0x3E, 0x46,
+
+// )
+       0x4E, 0x23, 0x00, 0x00, 0x00, 0x00,
+       0x3C, 0xB5, 0x5A, 0x00, 0x00, 0x00,
+       0x00, 0x0D, 0xC9, 0x28, 0x00, 0x00,
+       0x00, 0x00, 0x59, 0x86, 0x00, 0x00,
+       0x00, 0x00, 0x28, 0xA4, 0x06, 0x00,
+       0x00, 0x00, 0x1C, 0xD9, 0x07, 0x00,
+       0x00, 0x00, 0x27, 0xA3, 0x06, 0x00,
+       0x00, 0x00, 0x54, 0x8A, 0x00, 0x00,
+       0x00, 0x09, 0xC4, 0x2C, 0x00, 0x00,
+       0x30, 0xAA, 0x64, 0x00, 0x00, 0x00,
+       0x5A, 0x2F, 0x00, 0x00, 0x00, 0x00,
+
+// *
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x4F, 0x59, 0x00, 0x00,
+       0x07, 0x5B, 0x51, 0x5A, 0x56, 0x09,
+       0x10, 0x8A, 0x52, 0x4A, 0x7D, 0x14,
+       0x00, 0x18, 0xA5, 0x9F, 0x1E, 0x00,
+       0x00, 0x4A, 0x4A, 0x42, 0x51, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// +
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x2F, 0xD1, 0xCB, 0xFE, 0xAA, 0x9F,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// ,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1E, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00,
+       0x00, 0x1B, 0xD7, 0x07, 0x00, 0x00,
+       0x00, 0x03, 0x8A, 0x04, 0x00, 0x00,
+       0x00, 0x0C, 0x25, 0x00, 0x00, 0x00,
+
+// -
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x08, 0xAD, 0xD7, 0xD7, 0x9E, 0x0A,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// .
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+// /
+       0x00, 0x00, 0x00, 0x00, 0x4F, 0x66,
+       0x00, 0x00, 0x00, 0x05, 0xB1, 0x13,
+       0x00, 0x00, 0x00, 0x36, 0x76, 0x00,
+       0x00, 0x00, 0x02, 0x96, 0x22, 0x00,
+       0x00, 0x00, 0x26, 0x83, 0x01, 0x00,
+       0x00, 0x00, 0x85, 0x2D, 0x00, 0x00,
+       0x00, 0x17, 0xB3, 0x03, 0x00, 0x00,
+       0x00, 0x70, 0x3A, 0x00, 0x00, 0x00,
+       0x0F, 0xB8, 0x06, 0x00, 0x00, 0x00,
+       0x5A, 0x5C, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x08, 0x8B, 0xD3, 0x6C, 0x02,
+       0x00, 0x6F, 0x71, 0x05, 0x94, 0x3C,
+       0x06, 0xCA, 0x1A, 0x00, 0x38, 0x93,
+       0x12, 0xDD, 0x0C, 0x00, 0x24, 0xD2,
+       0x19, 0xDB, 0x08, 0x00, 0x1C, 0xD9,
+       0x13, 0xDE, 0x0C, 0x00, 0x23, 0xD4,
+       0x07, 0xCE, 0x18, 0x00, 0x35, 0x97,
+       0x00, 0x7C, 0x66, 0x01, 0x88, 0x59,
+       0x00, 0x0D, 0xA4, 0xAD, 0x80, 0x05,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x0A, 0x00, 0x00,
+       0x03, 0x56, 0xB0, 0xB5, 0x0A, 0x00,
+       0x07, 0x4F, 0x36, 0xDB, 0x0A, 0x00,
+       0x06, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x08, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x07, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x01, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x0C, 0xB4, 0xCE, 0xFF, 0xAD, 0x8F,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x04, 0x88, 0xC5, 0x9E, 0x25, 0x00,
+       0x02, 0x2F, 0x00, 0x50, 0xA3, 0x04,
+       0x00, 0x00, 0x00, 0x23, 0xD8, 0x07,
+       0x00, 0x00, 0x00, 0x6D, 0x83, 0x00,
+       0x00, 0x00, 0x37, 0x97, 0x0D, 0x00,
+       0x00, 0x1D, 0xC2, 0x10, 0x00, 0x00,
+       0x03, 0x9F, 0x37, 0x00, 0x00, 0x00,
+       0x1E, 0xF5, 0xAF, 0xD7, 0x91, 0x05,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x07, 0xA1, 0xC9, 0xA1, 0x2A, 0x00,
+       0x03, 0x21, 0x01, 0x51, 0xA6, 0x04,
+       0x00, 0x00, 0x00, 0x21, 0xD6, 0x07,
+       0x00, 0x00, 0x02, 0x76, 0x70, 0x00,
+       0x00, 0x4B, 0xD6, 0xAA, 0x0D, 0x00,
+       0x00, 0x00, 0x02, 0x72, 0x8F, 0x01,
+       0x00, 0x00, 0x00, 0x21, 0xD9, 0x07,
+       0x02, 0x04, 0x00, 0x57, 0x9E, 0x03,
+       0x15, 0xC3, 0xCD, 0xA2, 0x21, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x5C, 0xB7, 0x0A,
+       0x00, 0x00, 0x14, 0xC7, 0xB6, 0x0A,
+       0x00, 0x01, 0x83, 0x59, 0xDB, 0x0A,
+       0x00, 0x2E, 0x85, 0x25, 0xDB, 0x0A,
+       0x05, 0xB1, 0x20, 0x1B, 0xDB, 0x0A,
+       0x17, 0xD8, 0xA6, 0xCB, 0xFE, 0x95,
+       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A,
+       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x17, 0xCB, 0xA8, 0xD3, 0x81, 0x01,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x18, 0xCE, 0xAE, 0x7A, 0x0B, 0x00,
+       0x00, 0x00, 0x08, 0x81, 0x8E, 0x01,
+       0x05, 0x00, 0x00, 0x21, 0xD8, 0x09,
+       0x01, 0x01, 0x00, 0x5F, 0x9B, 0x02,
+       0x15, 0xBD, 0xCD, 0x9E, 0x1C, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x01, 0x5F, 0xC1, 0xA6, 0x4F,
+       0x00, 0x4C, 0xA2, 0x0D, 0x09, 0x21,
+       0x04, 0xB2, 0x39, 0x00, 0x00, 0x00,
+       0x0E, 0xE2, 0x15, 0x00, 0x00, 0x00,
+       0x18, 0xE1, 0x7B, 0xC0, 0x92, 0x19,
+       0x16, 0xEC, 0x35, 0x01, 0x6D, 0x9B,
+       0x09, 0xCA, 0x0B, 0x00, 0x21, 0xD9,
+       0x00, 0x89, 0x35, 0x00, 0x52, 0x95,
+       0x00, 0x14, 0xAB, 0x9F, 0x9E, 0x1B,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x09, 0xAF, 0xD3, 0xC5, 0xAB, 0x0B,
+       0x00, 0x00, 0x00, 0x20, 0x82, 0x01,
+       0x00, 0x00, 0x00, 0x7E, 0x2C, 0x00,
+       0x00, 0x00, 0x15, 0xB5, 0x03, 0x00,
+       0x02, 0x00, 0x6E, 0x56, 0x00, 0x00,
+       0x07, 0x0C, 0xCB, 0x13, 0x00, 0x00,
+       0x02, 0x41, 0x99, 0x01, 0x00, 0x00,
+       0x00, 0x82, 0x72, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x48, 0xBE, 0xA9, 0x4A, 0x00,
+       0x0D, 0xD9, 0x19, 0x39, 0xAB, 0x06,
+       0x15, 0xE3, 0x15, 0x2A, 0xA2, 0x05,
+       0x02, 0x8E, 0x9A, 0xB5, 0x31, 0x00,
+       0x00, 0x4C, 0xD3, 0xAA, 0x16, 0x00,
+       0x07, 0xCD, 0x23, 0x93, 0x96, 0x01,
+       0x18, 0xDD, 0x0B, 0x26, 0xDB, 0x09,
+       0x0D, 0xDD, 0x25, 0x38, 0x9C, 0x03,
+       0x00, 0x54, 0xDE, 0xA5, 0x26, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x17, 0xA3, 0xD8, 0x72, 0x04,
+       0x02, 0xA1, 0x56, 0x03, 0x88, 0x5A,
+       0x12, 0xDB, 0x0C, 0x00, 0x27, 0x94,
+       0x16, 0xE1, 0x0D, 0x00, 0x22, 0xD5,
+       0x05, 0xB6, 0x5F, 0x02, 0x72, 0xB6,
+       0x00, 0x20, 0xAE, 0xA1, 0x5E, 0xA4,
+       0x00, 0x00, 0x00, 0x00, 0x40, 0x8C,
+       0x00, 0x0D, 0x00, 0x0A, 0xAE, 0x31,
+       0x00, 0x7E, 0xAD, 0xDC, 0x5B, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x07, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x08, 0x16, 0xBA, 0x08, 0x00, 0x00,
+       0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x16, 0xBA, 0x08, 0x00, 0x00,
+       0x00, 0x1B, 0xD7, 0x07, 0x00, 0x00,
+       0x00, 0x1B, 0x96, 0x04, 0x00, 0x00,
+       0x00, 0x0C, 0x25, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x06, 0x65,
+       0x00, 0x00, 0x02, 0x50, 0xCD, 0x62,
+       0x00, 0x37, 0xB2, 0x79, 0x10, 0x00,
+       0x06, 0x77, 0xA8, 0x41, 0x00, 0x00,
+       0x00, 0x00, 0x17, 0x92, 0x95, 0x2E,
+       0x00, 0x00, 0x00, 0x00, 0x2B, 0xA8,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x07, 0x00, 0x00, 0x00, 0x00, 0x07,
+       0x03, 0x00, 0x00, 0x00, 0x00, 0x02,
+       0x68, 0xD2, 0xD3, 0xD3, 0xD3, 0x6D,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x6A, 0xD6, 0xD7, 0xD7, 0xD7, 0x6F,
+       0x0B, 0x00, 0x00, 0x00, 0x00, 0x0A,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x6A, 0x06, 0x00, 0x00, 0x00, 0x00,
+       0x64, 0xD0, 0x50, 0x02, 0x00, 0x00,
+       0x00, 0x0F, 0x81, 0x9E, 0x3A, 0x00,
+       0x00, 0x00, 0x3F, 0xC0, 0x72, 0x06,
+       0x2B, 0xA6, 0x86, 0x17, 0x00, 0x00,
+       0xA9, 0x2F, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x10, 0xA9, 0xAC, 0xA2, 0x42, 0x00,
+       0x1A, 0xD9, 0x08, 0x39, 0xAA, 0x06,
+       0x00, 0x00, 0x00, 0x30, 0xA1, 0x05,
+       0x00, 0x00, 0x13, 0xC7, 0x33, 0x00,
+       0x00, 0x02, 0x9E, 0x54, 0x00, 0x00,
+       0x00, 0x11, 0xD9, 0x0C, 0x00, 0x00,
+       0x00, 0x02, 0x1A, 0x00, 0x00, 0x00,
+       0x00, 0x12, 0xAD, 0x06, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x4F, 0xBB, 0xA6, 0x3D,
+       0x00, 0x37, 0xA1, 0x0E, 0x51, 0xA5,
+       0x02, 0xA8, 0x3C, 0x4A, 0xCA, 0xB7,
+       0x0D, 0xDD, 0x1E, 0xCE, 0x43, 0xDB,
+       0x18, 0xDC, 0x25, 0xDD, 0x35, 0xE5,
+       0x15, 0xDE, 0x24, 0xDE, 0x75, 0xB3,
+       0x07, 0xD4, 0x2A, 0x93, 0x58, 0xDC,
+       0x00, 0x7E, 0x89, 0x02, 0x0E, 0x01,
+       0x00, 0x0C, 0xA3, 0xB5, 0x85, 0x08,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00, 0x95, 0x95, 0x00, 0x00,
+       0x0A, 0x10, 0xBA, 0xD0, 0x14, 0x00,
+       0x0A, 0x4A, 0x57, 0x77, 0x58, 0x00,
+       0x0B, 0x9A, 0x13, 0x25, 0x92, 0x02,
+       0x7A, 0xE1, 0xA8, 0xC6, 0xEF, 0x18,
+       0x56, 0x3A, 0x00, 0x00, 0x6C, 0x65,
+       0xAC, 0x14, 0x00, 0x00, 0x2B, 0x9F,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0xA0, 0xE8, 0x62, 0x00,
+       0x1B, 0xDB, 0x0A, 0x2B, 0xDC, 0x07,
+       0x1B, 0xDB, 0x0B, 0x4F, 0x93, 0x02,
+       0x1B, 0xF3, 0xA1, 0xBB, 0x4D, 0x02,
+       0x1B, 0xDB, 0x0A, 0x09, 0x7B, 0x8A,
+       0x1C, 0xDB, 0x0A, 0x00, 0x2B, 0xD9,
+       0x20, 0xF3, 0xAD, 0xCC, 0xB0, 0x50,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x07, 0x80, 0xE2, 0xCD, 0x93,
+       0x00, 0x80, 0x8D, 0x05, 0x00, 0x12,
+       0x0C, 0xDC, 0x18, 0x00, 0x00, 0x00,
+       0x18, 0xDC, 0x0B, 0x00, 0x00, 0x00,
+       0x10, 0xDE, 0x19, 0x00, 0x00, 0x00,
+       0x09, 0x86, 0x92, 0x09, 0x00, 0x06,
+       0x00, 0x08, 0x86, 0xE6, 0xA9, 0x8D,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x21, 0xF3, 0xAD, 0xE1, 0x81, 0x0A,
+       0x20, 0xDB, 0x0A, 0x04, 0x91, 0x7D,
+       0x1B, 0xDB, 0x0A, 0x00, 0x2C, 0xA6,
+       0x1B, 0xDB, 0x0A, 0x00, 0x1C, 0xD9,
+       0x1B, 0xDB, 0x0A, 0x00, 0x2C, 0xA1,
+       0x1C, 0xDB, 0x0A, 0x06, 0x93, 0x68,
+       0x21, 0xF3, 0x9F, 0xE3, 0x77, 0x04,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0xAD, 0xD7, 0xA4, 0x23,
+       0x1D, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x23, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x26, 0xF3, 0xAA, 0xD3, 0x7D, 0x00,
+       0x20, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1C, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0xAD, 0xD7, 0xD6, 0x50,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0xAD, 0xD7, 0xD6, 0x50,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0xAA, 0xD3, 0x91, 0x06,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x07, 0x7F, 0xDC, 0xCA, 0x95,
+       0x00, 0x80, 0x8A, 0x04, 0x00, 0x0A,
+       0x0C, 0xDC, 0x18, 0x00, 0x00, 0x00,
+       0x18, 0xDC, 0x0B, 0x23, 0xBE, 0xA6,
+       0x0D, 0xDD, 0x19, 0x00, 0x1B, 0xDB,
+       0x00, 0x85, 0x91, 0x08, 0x1B, 0xDB,
+       0x00, 0x08, 0x85, 0xE4, 0x9C, 0x99,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x22, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x1D, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x25, 0xF3, 0xAA, 0xD3, 0xCB, 0xB8,
+       0x27, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x27, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x22, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0E, 0x92, 0xCE, 0xFF, 0xAD, 0x71,
+       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x0A, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x0E, 0x92, 0xCE, 0xFF, 0xAD, 0x71,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1F, 0xBC, 0xCE, 0xB9, 0x0A,
+       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A,
+       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A,
+       0x00, 0x00, 0x00, 0x1B, 0xDB, 0x0A,
+       0x00, 0x00, 0x00, 0x1C, 0xD8, 0x07,
+       0x00, 0x07, 0x00, 0x39, 0xA0, 0x03,
+       0x00, 0x71, 0xCA, 0xAD, 0x2E, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x09, 0xB7, 0x29,
+       0x1B, 0xDB, 0x0B, 0x84, 0x59, 0x00,
+       0x1B, 0xDB, 0x69, 0x7F, 0x02, 0x00,
+       0x1B, 0xE7, 0xE5, 0x31, 0x00, 0x00,
+       0x1B, 0xDB, 0x3D, 0xD8, 0x13, 0x00,
+       0x1B, 0xDB, 0x0B, 0x5A, 0x9C, 0x07,
+       0x1B, 0xDB, 0x0A, 0x01, 0x80, 0x82,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x23, 0xF3, 0xAD, 0xD7, 0xA8, 0x2F,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xF6, 0x69, 0x00, 0x85, 0xB9,
+       0x1B, 0xEA, 0x8D, 0x07, 0xA7, 0xB3,
+       0x1B, 0xDE, 0xAA, 0x28, 0x71, 0xDD,
+       0x1B, 0xDB, 0x6D, 0x6B, 0x51, 0xDB,
+       0x1B, 0xDB, 0x2E, 0xE1, 0x2D, 0xDB,
+       0x1B, 0xDB, 0x0F, 0x5F, 0x24, 0xDB,
+       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x27, 0xF5, 0x40, 0x00, 0x1B, 0xDB,
+       0x27, 0xF6, 0xB3, 0x09, 0x1B, 0xDB,
+       0x27, 0xE1, 0xB9, 0x69, 0x1C, 0xDB,
+       0x27, 0xDB, 0x2E, 0xE2, 0x36, 0xDB,
+       0x27, 0xDB, 0x0A, 0x89, 0x9A, 0xDF,
+       0x27, 0xDB, 0x0A, 0x17, 0xDB, 0xB9,
+       0x27, 0xDB, 0x0A, 0x00, 0x6D, 0xBA,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0A, 0x1B, 0xB4, 0xB0, 0x8F, 0x0C,
+       0x0E, 0xA1, 0x5A, 0x00, 0x78, 0x79,
+       0x1F, 0xDE, 0x0E, 0x00, 0x2A, 0xA4,
+       0x26, 0xDC, 0x08, 0x00, 0x1C, 0xD9,
+       0x1F, 0xDE, 0x0E, 0x00, 0x2A, 0xA4,
+       0x0E, 0xA0, 0x59, 0x00, 0x77, 0x7A,
+       0x0A, 0x1B, 0xB5, 0x9F, 0x91, 0x0C,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0xAD, 0xCB, 0xB3, 0x53,
+       0x1B, 0xDB, 0x0A, 0x00, 0x31, 0xDA,
+       0x1B, 0xDB, 0x0A, 0x02, 0x62, 0x9B,
+       0x1B, 0xF3, 0xAA, 0xA6, 0x7F, 0x14,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1B, 0xB4, 0xB0, 0x8F, 0x0C,
+       0x0B, 0xA1, 0x5A, 0x00, 0x78, 0x79,
+       0x14, 0xDE, 0x0E, 0x00, 0x2A, 0xA4,
+       0x19, 0xDC, 0x08, 0x00, 0x1C, 0xD9,
+       0x10, 0xDD, 0x0E, 0x00, 0x2A, 0xA3,
+       0x02, 0x9F, 0x59, 0x00, 0x77, 0x76,
+       0x00, 0x1B, 0xB8, 0xD6, 0xA3, 0x0B,
+       0x00, 0x00, 0x00, 0x0D, 0xA9, 0x88,
+       0x00, 0x00, 0x00, 0x00, 0x05, 0x52,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xF3, 0x9F, 0xE9, 0x65, 0x00,
+       0x1D, 0xDB, 0x0A, 0x2A, 0xDB, 0x07,
+       0x22, 0xDB, 0x0B, 0x57, 0x95, 0x02,
+       0x26, 0xF3, 0xD5, 0xAB, 0x0F, 0x00,
+       0x21, 0xDB, 0x17, 0xCC, 0x23, 0x00,
+       0x1C, 0xDB, 0x0A, 0x4E, 0x9A, 0x04,
+       0x1B, 0xDB, 0x0A, 0x04, 0xA8, 0x61,
+       0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x01, 0x65, 0xDC, 0xC9, 0xAB, 0x32,
+       0x13, 0xE0, 0x13, 0x00, 0x05, 0x0C,
+       0x0C, 0xCC, 0x73, 0x12, 0x00, 0x00,
+       0x00, 0x1D, 0x92, 0xF2, 0x9B, 0x22,
+       0x00, 0x00, 0x00, 0x06, 0x72, 0xA8,
+       0x0B, 0x1E, 0x00, 0x00, 0x3A, 0xA4,
+       0x19, 0xB6, 0xB0, 0xCA, 0xA0, 0x27,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x5D, 0xD6, 0xCE, 0xFF, 0xAD, 0xD6,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x05, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x05, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x54, 0xDB, 0x0A, 0x00, 0x1B, 0xE1,
+       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x1B, 0xDB, 0x0A, 0x00, 0x1B, 0xDB,
+       0x18, 0xDD, 0x0B, 0x00, 0x21, 0xD6,
+       0x07, 0xD3, 0x2E, 0x00, 0x56, 0x97,
+       0x00, 0x3F, 0xC6, 0x9C, 0xA0, 0x1E,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0xC0, 0x36, 0x00, 0x00, 0x15, 0xC4,
+       0x70, 0x8B, 0x00, 0x00, 0x5B, 0x64,
+       0x24, 0xDB, 0x11, 0x04, 0xB4, 0x18,
+       0x0B, 0xA3, 0x42, 0x24, 0x90, 0x02,
+       0x07, 0x51, 0x9A, 0x7B, 0x56, 0x00,
+       0x01, 0x12, 0xD5, 0xB1, 0x13, 0x00,
+       0x00, 0x01, 0x9C, 0x93, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0xC7, 0x0C, 0x00, 0x00, 0x06, 0xAD,
+       0x9D, 0x1A, 0x36, 0x41, 0x0E, 0xAD,
+       0x83, 0x32, 0x93, 0x9E, 0x28, 0x75,
+       0x62, 0x5C, 0xA7, 0xC9, 0x4E, 0x5D,
+       0x3C, 0x83, 0x84, 0x94, 0x69, 0x35,
+       0x28, 0xE3, 0x65, 0x61, 0xAF, 0x24,
+       0x13, 0xEF, 0x32, 0x2F, 0xED, 0x0D,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x6E, 0x99, 0x04, 0x00, 0x65, 0x6E,
+       0x07, 0xA8, 0x5D, 0x29, 0x93, 0x07,
+       0x00, 0x20, 0xE1, 0xD0, 0x23, 0x00,
+       0x00, 0x00, 0x98, 0xA2, 0x03, 0x00,
+       0x00, 0x32, 0x95, 0xBE, 0x55, 0x00,
+       0x0E, 0xBF, 0x16, 0x2A, 0xDD, 0x13,
+       0x85, 0x54, 0x00, 0x00, 0x74, 0x8B,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x2F, 0xD9, 0x0E, 0x00, 0x06, 0xB6,
+       0x01, 0x8D, 0x72, 0x00, 0x61, 0x72,
+       0x00, 0x17, 0xDB, 0x3C, 0xC9, 0x0E,
+       0x00, 0x00, 0x6C, 0xFB, 0x3D, 0x00,
+       0x00, 0x00, 0x1B, 0xDC, 0x08, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x02, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x27, 0x8E, 0xD7, 0xD7, 0xCF, 0xC0,
+       0x00, 0x00, 0x00, 0x01, 0x83, 0x72,
+       0x00, 0x00, 0x00, 0x49, 0x9B, 0x07,
+       0x00, 0x00, 0x1B, 0xD3, 0x20, 0x00,
+       0x00, 0x05, 0xA6, 0x53, 0x00, 0x00,
+       0x00, 0x6F, 0x84, 0x01, 0x00, 0x00,
+       0x0B, 0xDA, 0xB4, 0xD7, 0xD7, 0xA0,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x1B, 0xF3, 0xAD, 0xA1, 0x14,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x0C, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x10, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x17, 0xCB, 0xA8, 0x9E, 0x13,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x5A, 0x5C, 0x00, 0x00, 0x00, 0x00,
+       0x0F, 0xB8, 0x06, 0x00, 0x00, 0x00,
+       0x00, 0x71, 0x39, 0x00, 0x00, 0x00,
+       0x00, 0x17, 0xB2, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x85, 0x2C, 0x00, 0x00,
+       0x00, 0x00, 0x26, 0x82, 0x01, 0x00,
+       0x00, 0x00, 0x02, 0x96, 0x19, 0x00,
+       0x00, 0x00, 0x00, 0x36, 0x74, 0x00,
+       0x00, 0x00, 0x00, 0x05, 0xB0, 0x12,
+       0x00, 0x00, 0x00, 0x00, 0x4F, 0x62,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x2B, 0xC2, 0xCE, 0xB9, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x2B, 0xBE, 0xC8, 0xA6, 0x07, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x05, 0x05, 0x00, 0x00,
+       0x00, 0x00, 0x4B, 0x57, 0x00, 0x00,
+       0x00, 0x03, 0xA9, 0xA1, 0x04, 0x00,
+       0x00, 0x24, 0x87, 0x8C, 0x2B, 0x00,
+       0x00, 0x7C, 0x33, 0x2D, 0x7C, 0x00,
+       0x0E, 0xB9, 0x06, 0x05, 0xB0, 0x12,
+       0x51, 0x63, 0x00, 0x00, 0x57, 0x5B,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0xB2, 0xD7, 0xD7, 0xD7, 0xD7, 0x9F,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x03, 0x61, 0x7A, 0x08, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x67, 0xC0, 0xE9, 0x72, 0x00,
+       0x00, 0x0D, 0x00, 0x25, 0xD9, 0x07,
+       0x00, 0x37, 0xB5, 0xCE, 0xB8, 0x0A,
+       0x0B, 0xD8, 0x2C, 0x1B, 0xDB, 0x0A,
+       0x16, 0xE1, 0x13, 0x3C, 0xE7, 0x0B,
+       0x02, 0x87, 0xB1, 0x7A, 0xAC, 0x85,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDF, 0x81, 0xC5, 0xAC, 0x24,
+       0x1B, 0xF0, 0x52, 0x00, 0x56, 0x99,
+       0x1B, 0xDB, 0x0A, 0x00, 0x22, 0xD9,
+       0x1B, 0xDB, 0x0A, 0x00, 0x24, 0xD5,
+       0x1B, 0xE9, 0x29, 0x00, 0x6B, 0x84,
+       0x24, 0xD4, 0x9F, 0xCA, 0x98, 0x0F,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x20, 0xB2, 0xAF, 0xDA, 0x38,
+       0x08, 0xB3, 0x5E, 0x00, 0x00, 0x06,
+       0x21, 0xDF, 0x0C, 0x00, 0x00, 0x00,
+       0x1F, 0xDF, 0x0C, 0x00, 0x00, 0x00,
+       0x06, 0xB4, 0x5E, 0x00, 0x00, 0x05,
+       0x00, 0x22, 0xB6, 0xB0, 0xD5, 0x36,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB,
+       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB,
+       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB,
+       0x00, 0x24, 0xBE, 0xAC, 0x7E, 0xE2,
+       0x04, 0xAE, 0x52, 0x00, 0x4E, 0xE4,
+       0x13, 0xDF, 0x0C, 0x00, 0x1B, 0xDB,
+       0x18, 0xDF, 0x09, 0x00, 0x1B, 0xDB,
+       0x07, 0xD4, 0x2E, 0x01, 0x6F, 0xB7,
+       0x00, 0x46, 0xE2, 0xA5, 0x62, 0xDD,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0A, 0x18, 0xA8, 0xC9, 0xAA, 0x2D,
+       0x0F, 0x9F, 0x2B, 0x00, 0x33, 0x9D,
+       0x21, 0xEE, 0xAA, 0xD3, 0xC8, 0xA5,
+       0x23, 0xE0, 0x0D, 0x00, 0x00, 0x00,
+       0x0E, 0xB4, 0x61, 0x00, 0x00, 0x13,
+       0x0A, 0x1D, 0xAC, 0xAF, 0xCA, 0x91,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x69, 0xE3, 0x9B, 0x7C,
+       0x00, 0x10, 0xE0, 0x18, 0x00, 0x02,
+       0x00, 0x1A, 0xDB, 0x08, 0x00, 0x00,
+       0x67, 0xCE, 0xFF, 0xAD, 0xD6, 0x58,
+       0x03, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x07, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x01, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x05, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x21, 0xBC, 0xAB, 0x79, 0xDF,
+       0x03, 0xAB, 0x52, 0x00, 0x52, 0xB4,
+       0x13, 0xDE, 0x0C, 0x00, 0x1B, 0xDB,
+       0x18, 0xDF, 0x09, 0x00, 0x1B, 0xDB,
+       0x08, 0xD2, 0x32, 0x01, 0x72, 0xB7,
+       0x00, 0x41, 0xE2, 0xA8, 0x6A, 0xD6,
+       0x00, 0x06, 0x00, 0x00, 0x41, 0x8F,
+       0x00, 0x71, 0xD9, 0xC9, 0x9A, 0x1B,
+
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x26, 0xE1, 0x93, 0xD5, 0x76, 0x00,
+       0x26, 0xF2, 0x39, 0x29, 0xDA, 0x07,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x24, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x15, 0xAF, 0x06, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0E, 0xB5, 0xCE, 0xB9, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x15, 0xAF, 0x06, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x25, 0xBF, 0xCE, 0xB9, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDA, 0x08, 0x00,
+       0x09, 0x00, 0x2E, 0xA1, 0x05, 0x00,
+       0x70, 0xDA, 0xDE, 0x49, 0x00, 0x00,
+
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x36, 0x98, 0x08,
+       0x1B, 0xDB, 0x25, 0xCB, 0x1E, 0x00,
+       0x1B, 0xE5, 0xC1, 0x3F, 0x00, 0x00,
+       0x1B, 0xDF, 0x96, 0x99, 0x06, 0x00,
+       0x1B, 0xDB, 0x13, 0xAA, 0x79, 0x00,
+       0x1B, 0xDB, 0x0A, 0x14, 0xC9, 0x53,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x1C, 0xBB, 0xCE, 0xB9, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xE1, 0x9D, 0x90, 0x93, 0x92,
+       0x1B, 0xF0, 0x4C, 0xEE, 0x47, 0xD9,
+       0x1B, 0xDC, 0x28, 0xDB, 0x28, 0xDB,
+       0x1B, 0xDB, 0x28, 0xDB, 0x28, 0xDB,
+       0x1B, 0xDB, 0x28, 0xDB, 0x28, 0xDB,
+       0x1B, 0xDB, 0x28, 0xDB, 0x28, 0xDB,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x24, 0xE1, 0x93, 0xD5, 0x76, 0x00,
+       0x25, 0xF2, 0x39, 0x29, 0xDA, 0x07,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x26, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x27, 0xBE, 0xA1, 0x9A, 0x17,
+       0x05, 0xB5, 0x3D, 0x00, 0x6D, 0x8D,
+       0x15, 0xDE, 0x0C, 0x00, 0x23, 0xD7,
+       0x15, 0xDE, 0x0C, 0x00, 0x23, 0xD7,
+       0x05, 0xB6, 0x3B, 0x01, 0x6B, 0x8E,
+       0x00, 0x29, 0xBF, 0xA1, 0x9B, 0x18,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xDF, 0x81, 0xC5, 0xAB, 0x24,
+       0x1B, 0xF0, 0x51, 0x00, 0x56, 0x99,
+       0x1B, 0xDB, 0x0A, 0x00, 0x22, 0xD9,
+       0x1B, 0xDB, 0x0A, 0x00, 0x24, 0xD5,
+       0x1B, 0xE9, 0x29, 0x00, 0x6B, 0x84,
+       0x1B, 0xE6, 0xA6, 0xCA, 0x98, 0x0F,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x24, 0xBE, 0xAC, 0x75, 0xD9,
+       0x07, 0xAE, 0x52, 0x00, 0x4E, 0xE4,
+       0x20, 0xDF, 0x0C, 0x00, 0x1B, 0xDB,
+       0x21, 0xDF, 0x09, 0x00, 0x1B, 0xDB,
+       0x08, 0xD4, 0x2E, 0x01, 0x6F, 0xB7,
+       0x00, 0x46, 0xE2, 0xA5, 0x62, 0xDD,
+       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB,
+       0x00, 0x00, 0x00, 0x00, 0x1B, 0xDB,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0A, 0x1B, 0xDF, 0x83, 0xC5, 0xAE,
+       0x0A, 0x1B, 0xF5, 0x5D, 0x04, 0x6F,
+       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x0A, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x0D, 0x80, 0xE3, 0xD9, 0x72, 0x00,
+       0x1C, 0xE3, 0x13, 0x00, 0x05, 0x00,
+       0x06, 0xAE, 0xAC, 0x55, 0x06, 0x00,
+       0x00, 0x03, 0x46, 0xB5, 0x99, 0x02,
+       0x0A, 0x0D, 0x00, 0x2E, 0xD9, 0x07,
+       0x22, 0xBF, 0x9D, 0xB0, 0x4D, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x49, 0xCD, 0xFF, 0xAD, 0xA7, 0x2D,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1B, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x1A, 0xDB, 0x0A, 0x00, 0x00,
+       0x00, 0x13, 0xDE, 0x12, 0x00, 0x00,
+       0x00, 0x02, 0x86, 0xEE, 0xAB, 0x39,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0B,
+       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x1B, 0xDB, 0x0A, 0x1B, 0xDB, 0x0A,
+       0x16, 0xE3, 0x14, 0x70, 0xB8, 0x0A,
+       0x03, 0x9C, 0xBC, 0x70, 0xDE, 0x0A,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x75, 0x6F, 0x00, 0x00, 0x3E, 0x7B,
+       0x24, 0xD0, 0x06, 0x02, 0x97, 0x2A,
+       0x03, 0xAD, 0x2F, 0x18, 0xBD, 0x04,
+       0x00, 0x5B, 0x82, 0x66, 0x60, 0x00,
+       0x00, 0x15, 0xDC, 0xD2, 0x15, 0x00,
+       0x00, 0x01, 0x9E, 0x94, 0x01, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0xC3, 0x13, 0x29, 0x39, 0x07, 0xAF,
+       0x9A, 0x2C, 0x89, 0x9B, 0x12, 0xAD,
+       0x78, 0x44, 0xA1, 0xB3, 0x30, 0x6F,
+       0x47, 0x84, 0x70, 0x7D, 0x62, 0x3F,
+       0x2C, 0xEA, 0x3D, 0x45, 0xA9, 0x29,
+       0x13, 0xE9, 0x19, 0x23, 0xE9, 0x0D,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x3F, 0xE2, 0x15, 0x06, 0xBA, 0x27,
+       0x02, 0x7C, 0x91, 0x67, 0x75, 0x00,
+       0x00, 0x0C, 0xC3, 0xB2, 0x0E, 0x00,
+       0x00, 0x0E, 0xC2, 0xB8, 0x13, 0x00,
+       0x00, 0x7F, 0x62, 0x7F, 0x8D, 0x02,
+       0x32, 0x94, 0x04, 0x0C, 0xC0, 0x3E,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x53, 0x87, 0x00, 0x00, 0x3D, 0x79,
+       0x10, 0xD1, 0x12, 0x02, 0x99, 0x27,
+       0x00, 0x85, 0x5E, 0x1C, 0x91, 0x03,
+       0x00, 0x2A, 0x9E, 0x7B, 0x54, 0x00,
+       0x00, 0x04, 0xB4, 0xB2, 0x0C, 0x00,
+       0x00, 0x00, 0x66, 0x7C, 0x00, 0x00,
+       0x00, 0x05, 0xA6, 0x26, 0x00, 0x00,
+       0x2F, 0xDE, 0x70, 0x01, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x05, 0x9E, 0xD7, 0xC9, 0xFB, 0x72,
+       0x00, 0x00, 0x00, 0x29, 0xD4, 0x12,
+       0x00, 0x00, 0x0F, 0xCB, 0x2F, 0x00,
+       0x00, 0x03, 0x98, 0x65, 0x00, 0x00,
+       0x00, 0x68, 0x8A, 0x03, 0x00, 0x00,
+       0x0B, 0xDA, 0xB5, 0xD7, 0xD7, 0x6C,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x02, 0x85, 0xB3, 0x4D,
+       0x00, 0x00, 0x17, 0xE1, 0x0D, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x2F, 0xA0, 0x05, 0x00,
+       0x00, 0x39, 0xF1, 0x54, 0x00, 0x00,
+       0x00, 0x00, 0x2A, 0xD4, 0x06, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x19, 0xE1, 0x0D, 0x00,
+       0x00, 0x00, 0x03, 0x7E, 0xD6, 0x4C,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x6E, 0xE2, 0x61, 0x00, 0x00,
+       0x00, 0x00, 0x27, 0xDA, 0x07, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x1A, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x0D, 0xD8, 0x15, 0x00,
+       0x00, 0x00, 0x00, 0x76, 0xB8, 0x24,
+       0x00, 0x00, 0x13, 0xDD, 0x13, 0x00,
+       0x00, 0x00, 0x1B, 0xDB, 0x0A, 0x00,
+       0x00, 0x00, 0x27, 0xDD, 0x08, 0x00,
+       0x00, 0x6C, 0xD7, 0x62, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x01, 0x70, 0xD2, 0x67, 0x0B, 0x72,
+       0x07, 0x79, 0x0A, 0x69, 0xD2, 0x71,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
 };
index 78d4a7471d6a456d1da84da1d84e02d604a7076c..022c2fdbb53f3288a86b9b6343091d1193d9afe8 100644 (file)
@@ -23,6 +23,7 @@
 #include "gui.h"
 #include "apple2.h"
 #include "diskselector.h"
+#include "floppydrive.h"
 #include "log.h"
 #include "video.h"
 
@@ -224,9 +225,9 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
        case 1:
                SpawnMessage("*** DISK #1 ***");
 
-               if (disk1EjectHovered && !floppyDrive.IsEmpty(0))
+               if (disk1EjectHovered && !floppyDrive[0].IsEmpty(0))
                {
-                       floppyDrive.EjectImage(0);
+                       floppyDrive[0].EjectImage(0);
                        SpawnMessage("*** DISK #1 EJECTED ***");
                }
 
@@ -241,9 +242,9 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
        case 2:
                SpawnMessage("*** DISK #2 ***");
 
-               if (disk2EjectHovered && !floppyDrive.IsEmpty(1))
+               if (disk2EjectHovered && !floppyDrive[0].IsEmpty(1))
                {
-                       floppyDrive.EjectImage(1);
+                       floppyDrive[0].EjectImage(1);
                        SpawnMessage("*** DISK #2 EJECTED ***");
                }
 
@@ -256,7 +257,7 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
                break;
        // Swap disks
        case 3:
-               floppyDrive.SwapImages();
+               floppyDrive[0].SwapImages();
                SpawnMessage("*** DISKS SWAPPED ***");
                break;
        // Save state
@@ -345,8 +346,8 @@ void GUI::MouseMove(int32_t x, int32_t y, uint32_t buttons)
                                // Show what's in the selected drive
                                if (iconSelected >= 1 && iconSelected <= 2)
                                {
-                                       if (!floppyDrive.IsEmpty(iconSelected - 1))
-                                               SpawnMessage("\"%s\"", floppyDrive.ImageName(iconSelected - 1));
+                                       if (!floppyDrive[0].IsEmpty(iconSelected - 1))
+                                               SpawnMessage("\"%s\"", floppyDrive[0].ImageName(iconSelected - 1));
                                }
                        }
                }
@@ -401,7 +402,7 @@ void GUI::AssembleDriveIcon(SDL_Renderer * renderer, int driveNumber)
        // Drive door @ (16, 7)
        SDL_Rect dst;
        dst.w = 8, dst.h = 10, dst.x = 16, dst.y = 7;
-       SDL_RenderCopy(renderer, (floppyDrive.IsEmpty(driveNumber) ?
+       SDL_RenderCopy(renderer, (floppyDrive[0].IsEmpty(driveNumber) ?
                doorOpen : doorClosed), NULL, &dst);
 
        // Numeral @ (30, 20)
@@ -416,7 +417,7 @@ void GUI::AssembleDriveIcon(SDL_Renderer * renderer, int driveNumber)
 
 void GUI::DrawEjectButton(SDL_Renderer * renderer, int driveNumber)
 {
-       if (floppyDrive.IsEmpty(driveNumber))
+       if (floppyDrive[0].IsEmpty(driveNumber))
                return;
 
        uint8_t r = 0x00, g = 0xAA, b = 0x00;
@@ -431,7 +432,7 @@ void GUI::DrawEjectButton(SDL_Renderer * renderer, int driveNumber)
 
 void GUI::DrawDriveLight(SDL_Renderer * renderer, int driveNumber)
 {
-       int lightState = floppyDrive.DriveLightStatus(driveNumber);
+       int lightState = floppyDrive[0].DriveLightStatus(driveNumber);
        int r = 0x77, g = 0x00, b = 0x00;
 
        if (lightState == DLS_READ)
index fb05d3629cbcbc11638342f2c94e7e8cb4aef039..0c20bf434e0e9dace270f72fb5dfd253e8b56a10 100644 (file)
@@ -27,7 +27,7 @@ static uint32_t logSize = 0;
 
 bool InitLog(const char * path)
 {
-       log_stream = fopen(path, "wrt");
+       log_stream = fopen(path, "w");
 
        if (log_stream == NULL)
                return false;
index 653eac9eeb61e392da8d1255faa6e5a652b5a126..d0f6b5df042e2789e6701de3eac3a6e59d17247f 100644 (file)
 
 #include "mmu.h"
 #include "apple2.h"
-#include "ay8910.h"
 #include "firmware.h"
 #include "log.h"
-#include "mos6522via.h"
+#include "mockingboard.h"
 #include "sound.h"
 #include "video.h"
 
 // Address Map enumeration
 enum { AM_RAM, AM_ROM, AM_BANKED, AM_READ, AM_WRITE, AM_READ_WRITE, AM_END_OF_LIST };
 
-// Macros for function pointers
-#define READFUNC(x) uint8_t (* x)(uint16_t)
-#define WRITEFUNC(x) void (* x)(uint16_t, uint8_t)
-
 // Internal vars
 uint8_t ** addrPtrRead[0x10000];
 uint8_t ** addrPtrWrite[0x10000];
@@ -39,6 +34,14 @@ uint16_t addrOffset[0x10000];
 READFUNC(funcMapRead[0x10000]);
 WRITEFUNC(funcMapWrite[0x10000]);
 
+READFUNC(slotHandlerR[8]);
+WRITEFUNC(slotHandlerW[8]);
+
+READFUNC(slotHandler2KR[8]);
+WRITEFUNC(slotHandler2KW[8]);
+
+uint8_t enabledSlot;
+
 struct AddressMap
 {
        uint16_t start;
@@ -69,7 +72,8 @@ uint8_t * mainMemoryTextW = &ram[0x0400];     // $0400 - $07FF (write)
 uint8_t * mainMemoryHGRR  = &ram[0x2000];      // $2000 - $3FFF (read)
 uint8_t * mainMemoryHGRW  = &ram[0x2000];      // $2000 - $3FFF (write)
 
-uint8_t * slotMemory      = &rom[0xC100];      // $C100 - $CFFF
+uint8_t * slotMemory      = &rom[0xC100];      // $C100 - $C7FF
+uint8_t * peripheralMemory= &rom[0xC800];      // $C800 - $CFFF
 uint8_t * slot3Memory     = &rom[0xC300];      // $C300 - $C3FF
 uint8_t * slot4Memory     = &rom[0xC400];      // $C400 - $C4FF
 uint8_t * slot6Memory     = &diskROM[0];       // $C600 - $C6FF
@@ -84,6 +88,10 @@ uint8_t ReadNOP(uint16_t);
 void WriteNOP(uint16_t, uint8_t);
 uint8_t ReadMemory(uint16_t);
 void WriteMemory(uint16_t, uint8_t);
+uint8_t SlotR(uint16_t address);
+void SlotW(uint16_t address, uint8_t byte);
+uint8_t Slot2KR(uint16_t address);
+void Slot2KW(uint16_t address, uint8_t byte);
 uint8_t ReadKeyboard(uint16_t);
 void Switch80STORE(uint16_t, uint8_t);
 void SwitchRAMRD(uint16_t, uint8_t);
@@ -91,6 +99,8 @@ void SwitchRAMWRT(uint16_t, uint8_t);
 void SwitchSLOTCXROM(uint16_t, uint8_t);
 void SwitchALTZP(uint16_t, uint8_t);
 void SwitchSLOTC3ROM(uint16_t, uint8_t);
+uint8_t SwitchINTC8ROMR(uint16_t);
+void SwitchINTC8ROMW(uint16_t, uint8_t);
 void Switch80COL(uint16_t, uint8_t);
 void SwitchALTCHARSET(uint16_t, uint8_t);
 uint8_t ReadKeyStrobe(uint16_t);
@@ -126,19 +136,11 @@ void SwitchHIRESW(uint16_t, uint8_t);
 uint8_t SwitchDHIRESR(uint16_t);
 void SwitchDHIRESW(uint16_t, uint8_t);
 void SwitchIOUDIS(uint16_t, uint8_t);
-uint8_t Slot6R(uint16_t);
-void Slot6W(uint16_t, uint8_t);
-void HandleSlot6(uint16_t, uint8_t);
-uint8_t MBRead(uint16_t);
-void MBWrite(uint16_t, uint8_t);
 uint8_t ReadButton0(uint16_t);
 uint8_t ReadButton1(uint16_t);
 uint8_t ReadPaddle0(uint16_t);
 uint8_t ReadIOUDIS(uint16_t);
 uint8_t ReadDHIRES(uint16_t);
-uint8_t ReadFloatingBus(uint16_t);
-//uint8_t SwitchR(uint16_t);
-//void SwitchW(uint16_t, uint8_t);
 
 
 // The main Apple //e memory map
@@ -191,22 +193,42 @@ AddressMap memoryMap[] = {
        { 0xC061, 0xC061, AM_READ, 0, 0, ReadButton0, 0 },
        { 0xC062, 0xC062, AM_READ, 0, 0, ReadButton1, 0 },
        { 0xC064, 0xC067, AM_READ, 0, 0, ReadPaddle0, 0 },
-//     { 0xC07E, 0xC07F, AM_READ_WRITE, 0, 0, SwitchIOUDISR, SwitchIOUDISW },
        { 0xC07E, 0xC07E, AM_READ_WRITE, 0, 0, ReadIOUDIS, SwitchIOUDIS },
        { 0xC07F, 0xC07F, AM_READ_WRITE, 0, 0, ReadDHIRES, SwitchIOUDIS },
        { 0xC080, 0xC08F, AM_READ_WRITE, 0, 0, SwitchLCR, SwitchLCW },
-       { 0xC0E0, 0xC0EF, AM_READ_WRITE, 0, 0, Slot6R, Slot6W },
-       { 0xC100, 0xCFFF, AM_ROM, &slotMemory, 0, 0, 0 },
 
-       // This will overlay the slotMemory accessors for slot 6 ROM
-       { 0xC300, 0xC3FF, AM_ROM, &slot3Memory, 0, 0, 0 },
-       { 0xC600, 0xC6FF, AM_ROM, &slot6Memory, 0, 0, 0 },
-       { 0xC400, 0xC4FF, AM_READ_WRITE, 0, 0, MBRead, MBWrite },
+       { 0xC100, 0xC7FF, AM_READ_WRITE, 0, 0, SlotR, SlotW },
+       { 0xC800, 0xCFFE, AM_READ_WRITE, 0, 0, Slot2KR, Slot2KW },
+       { 0xCFFF, 0xCFFF, AM_READ_WRITE, 0, 0, SwitchINTC8ROMR, SwitchINTC8ROMW },
 
        { 0xD000, 0xDFFF, AM_BANKED, &lcBankMemoryR, &lcBankMemoryW, 0, 0 },
        { 0xE000, 0xFFFF, AM_BANKED, &upperMemoryR, &upperMemoryW, 0, 0 },
        ADDRESS_MAP_END
 };
+/*
+Some stuff that may be useful:
+
+N.B.: Page 5-22 of UTA2E has INTC8ROM ON/OFF backwards
+INTC8ROM is turned OFF by R/W access to $CFFF
+INTC8ROM is turned ON by $C3xx access and SLOTC3ROM' (off)
+WRONG: (INTC8ROM on puts card's slot ROM/RAM(?) access in $C800-$CFFF)
+
+OK, so it's slightly more complex than that.  Basically, when there is an access to $CFFF, all peripheral cards must *stop* responding to  I/O STROBE'.  Only when a card gets an I/O SELECT' signal, can it respond to I/O STROBE'.
+
+INTC8ROM inhibits I/O STROBE' and activates the MB ROM in $C800-$CFFF
+INTC8ROM is 1 by access to $C3xx when SLOTC3ROM is 0
+INTC8ROM is 0 by access to $CFFF
+
+ICX = INTCXROM (aka SLOTCXROM), SC3 = SLOTC3ROM
+
+             ICX=0,SC3=0  ICX=0,SC3=1  ICX=1,SC3=0  ICX=1,SC3=1
+$C100-$C2FF   slot         slot         internal     internal
+$C300-$C3FF   internal     slot         internal     internal
+$C400-$CFFF   slot         slot         internal     internal
+
+Read from $C800-$CFFF causes I/O STROBE to go low (and INTCXROM and INTC8ROM are not set)
+
+*/
 
 
 void SetupAddressMap(void)
@@ -220,6 +242,14 @@ void SetupAddressMap(void)
                addrOffset[i] = 0;
        }
 
+       for(uint32_t i=0; i<8; i++)
+       {
+               slotHandlerR[i] = ReadNOP;
+               slotHandlerW[i] = WriteNOP;
+               slotHandler2KR[i] = ReadNOP;
+               slotHandler2KW[i] = WriteNOP;
+       }
+
        uint32_t i=0;
 
        while (memoryMap[i].type != AM_END_OF_LIST)
@@ -310,10 +340,54 @@ void ResetMMUPointers(void)
        mainMemoryW = (ramwrt ?  &ram2[0x0200] : &ram[0x0200]);
        mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]);
 
-       slot6Memory = (slotCXROM ? &diskROM[0] : &rom[0xC600]);
-       slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]);
+//     slot6Memory = (intCXROM ? &rom[0xC600] : &diskROM[0]);
+//     slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]);
        pageZeroMemory = (altzp ? &ram2[0x0000] : &ram[0x0000]);
        SwitchLC();
+#if 1
+WriteLog("RAMWRT = %s\n", (ramwrt ? "ON" : "off"));
+WriteLog("RAMRD = %s\n", (ramrd ? "ON" : "off"));
+WriteLog("SLOTCXROM = %s\n", (intCXROM ? "ON" : "off"));
+WriteLog("SLOTC3ROM = %s\n", (slotC3ROM ? "ON" : "off"));
+WriteLog("ALTZP = %s\n", (altzp ? "ON" : "off"));
+#endif
+}
+
+
+//
+// Set up slot access
+//
+void InstallSlotHandler(uint8_t slot, SlotData * slotData)
+{
+       // Sanity check
+       if (slot > 7)
+       {
+               WriteLog("InstallSlotHanlder: Caller attempted to put device into slot #%u...\n", slot);
+               return;
+       }
+
+       // Set up I/O read & write functions
+       for(uint32_t i=0; i<16; i++)
+       {
+               if (slotData->ioR)
+                       funcMapRead[0xC080 + (slot * 16) + i] = slotData->ioR;
+
+               if (slotData->ioW)
+                       funcMapWrite[0xC080 + (slot * 16) + i] = slotData->ioW;
+       }
+
+       // Set up memory access read/write functions
+       if (slotData->pageR)
+               slotHandlerR[slot] = slotData->pageR;
+
+       if (slotData->pageW)
+               slotHandlerW[slot] = slotData->pageW;
+
+       if (slotData->extraR)
+               slotHandler2KR[slot] = slotData->extraR;
+
+       if (slotData->extraW)
+               slotHandler2KW[slot] = slotData->extraW;
 }
 
 
@@ -322,7 +396,8 @@ void ResetMMUPointers(void)
 //
 uint8_t ReadNOP(uint16_t)
 {
-       return 0;
+       // This is for unconnected reads, and some software looks at addresses like these.  In particular, Mr. Robot and His Robot Factory failed in that it was looking at the first byte of each slots 256 byte driver space and failing if it saw a zero there.  Now I have no idea what happens in the real hardware, but I suspect it would return something that looks like ReadFloatingBus().
+       return 0xFF;
 }
 
 
@@ -357,16 +432,130 @@ void WriteMemory(uint16_t address, uint8_t byte)
 //
 uint8_t AppleReadMem(uint16_t address)
 {
+#if 0
+if (address == 0xD4 || address == 0xAC20)
+       WriteLog("Reading $%X...\n", address);
+#endif
+#if 0
+       uint8_t memRead = (*(funcMapRead[address]))(address);
+static uint16_t lastAddr = 0;
+static uint32_t lastCount = 0;
+if ((address > 0xC000 && address < 0xC100) || address == 0xC601)
+{
+       if (lastAddr == address)
+               lastCount++;
+       else
+       {
+               if (lastCount > 1)
+                       WriteLog("%d times...\n", lastCount);
+
+               WriteLog("Reading $%02X from $%X ($%02X, $%02X)\n", memRead, address, diskROM[1], rom[0xC601]);
+               lastCount = 1;
+               lastAddr = address;
+       }
+}
+       return memRead;
+#else
        return (*(funcMapRead[address]))(address);
+#endif
 }
 
 
 void AppleWriteMem(uint16_t address, uint8_t byte)
 {
+#if 0
+static uint16_t lastAddr = 0;
+static uint32_t lastCount = 0;
+if ((address > 0xC000 && address < 0xC100) || address == 0xC601)
+{
+       if (lastAddr == address)
+               lastCount++;
+       else
+       {
+               if (lastCount > 1)
+                       WriteLog("%d times...\n", lastCount);
+
+               WriteLog("Writing to $%X\n", address);
+               lastCount = 1;
+               lastAddr = address;
+       }
+}
+#endif
+#if 0
+if (address == 0xD4 || address == 0xAC20)
+       WriteLog("Writing $%02X @ $%X...\n", byte, address);
+#endif
+#if 0
+//if (address >= 0x0827 && address <= 0x082A)
+if (address == 0x000D)
+       WriteLog("Writing $%02X @ $%X (PC=$%04X)...\n", byte, address, mainCPU.pc);
+#endif
        (*(funcMapWrite[address]))(address, byte);
 }
 
 
+//
+// Generic slot handlers.  These are set up here so that we can catch INTCXROM,
+// INTC8ROM & SLOTC3ROM here instead of having to catch them in each slot handler.
+//
+uint8_t SlotR(uint16_t address)
+{
+//WriteLog("SlotR: address=$%04X, intCXROM=%d, slotC3ROM=%d, intC8ROM=%d\n", address, intCXROM, slotC3ROM, intC8ROM);
+       if (intCXROM)
+               return rom[address];
+
+       uint8_t slot = (address & 0xF00) >> 8;
+       enabledSlot = slot;
+
+       if ((slotC3ROM == 0) && (slot == 3))
+       {
+               intC8ROM = 1;
+               return rom[address];
+       }
+
+       return (*(slotHandlerR[slot]))(address & 0xFF);
+}
+
+
+void SlotW(uint16_t address, uint8_t byte)
+{
+       if (intCXROM)
+               return;
+
+       uint8_t slot = (address & 0xF00) >> 8;
+       enabledSlot = slot;
+
+       if ((slotC3ROM == 0) && (slot == 3))
+       {
+               intC8ROM = 1;
+               return;
+       }
+
+       (*(slotHandlerW[slot]))(address & 0xFF, byte);
+}
+
+
+//
+// Slot handling for 2K address space at $C800-$CFFF
+//
+uint8_t Slot2KR(uint16_t address)
+{
+       if (intCXROM || intC8ROM)
+               return rom[address];
+
+       return (*(slotHandler2KR[enabledSlot]))(address & 0x7FF);
+}
+
+
+void Slot2KW(uint16_t address, uint8_t byte)
+{
+       if (intCXROM || intC8ROM)
+               return;
+
+       (*(slotHandler2KW[enabledSlot]))(address & 0x7FF, byte);
+}
+
+
 //
 // Actual emulated I/O functions follow
 //
@@ -420,13 +609,39 @@ void SwitchRAMWRT(uint16_t address, uint8_t)
 }
 
 
+//
+// Since any slots that aren't populated are set to read from the ROM anyway,
+// we only concern ourselves with switching populated slots here.  (Note that
+// the MB slot is a split ROM / I/O device, and it's taken care of in the
+// MB handler.)
+//
+// N.B.: SLOTCXROM is also INTCXROM
+//
 void SwitchSLOTCXROM(uint16_t address, uint8_t)
 {
-//WriteLog("Setting SLOTCXROM to %s...\n", ((address & 0x01) ^ 0x01 ? "ON" : "off"));
-       // This is the only soft switch that breaks the usual convention.
-       slotCXROM = !((bool)(address & 0x01));
-//     slot3Memory = (slotCXROM ? &rom[0] : &rom[0xC300]);
-       slot6Memory = (slotCXROM ? &diskROM[0] : &rom[0xC600]);
+WriteLog("Setting SLOTCXROM to %s...\n", (address & 0x01 ? "ON" : "off"));
+       intCXROM = (bool)(address & 0x01);
+
+       // INTC8ROM trumps all (only in the $C800--$CFFF range... which we don't account for yet...  :-/)
+//     if (intC8ROM)
+//             return;
+#if 0
+#if 1
+       if (intCXROM)
+       {
+               slot3Memory = &rom[0xC300];
+               slot6Memory = &rom[0xC600];
+       }
+       else
+       {
+               slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]);
+               slot6Memory = &diskROM[0];
+       }
+#else
+//     slot3Memory = (intCXROM ? &rom[0xC300] : &rom[0]);
+       slot6Memory = (intCXROM ? &rom[0xC600] : &diskROM[0]);
+#endif
+#endif
 }
 
 
@@ -438,16 +653,54 @@ void SwitchALTZP(uint16_t address, uint8_t)
 }
 
 //extern bool dumpDis;
-
+//
+// The interpretation of this name is that if it's set then we access the ROM
+// for the card actually sitting in SLOT 3 (if any)
+//
 void SwitchSLOTC3ROM(uint16_t address, uint8_t)
 {
 //dumpDis = true;
 //WriteLog("Setting SLOTC3ROM to %s...\n", (address & 0x01 ? "ON" : "off"));
        slotC3ROM = (bool)(address & 0x01);
+#if 1
+       if (intCXROM)
+               slot3Memory = &rom[0xC300];
+       else
+               slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]);
+#else
 //     slotC3ROM = false;
 // Seems the h/w forces this with an 80 column card in slot 3...
        slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]);
 //     slot3Memory = &rom[0xC300];
+#endif
+}
+
+
+/*
+We need to see where this is being switched from; if we know that, we can switch in the appropriate ROM to $C800-$CFFF.  N.B.: Will probably need a custom handler routine, as some cards (like the Apple Hi-Speed SCSI card) split the 2K range into a 1K RAM space and a 1K bank switch ROM space.
+*/
+//
+// This is a problem with split ROM / I/O regions.  Because we can't do that
+// cleanly, we have to have a read handler for this.
+//
+// N.B.: We could add AM_IOREAD_WRITE and AM_READ_IOWRITE to the memory handlers
+//       to take care of split ROM / I/O regions...
+//
+uint8_t SwitchINTC8ROMR(uint16_t)
+{
+WriteLog("Hitting INTC8ROM (read)...\n");
+       intC8ROM = false;
+       return rom[0xCFFF];
+}
+
+
+//
+// This resets the INTC8ROM switch (RW)
+//
+void SwitchINTC8ROMW(uint16_t, uint8_t)
+{
+WriteLog("Hitting INTC8ROM (write)...\n");
+       intC8ROM = false;
 }
 
 
@@ -460,13 +713,14 @@ void Switch80COL(uint16_t address, uint8_t)
 void SwitchALTCHARSET(uint16_t address, uint8_t)
 {
        alternateCharset = (bool)(address & 0x01);
+WriteLog("Setting ALTCHARSET to %s...\n", (alternateCharset ? "ON" : "off"));
 }
 
 
 uint8_t ReadKeyStrobe(uint16_t)
 {
-// No character data is read from here, just the 'any key was pressed' signal...
-//     uint8_t byte = lastKeyPressed | ((uint8_t)keyDown << 7);
+       // No character data is read from here, just the 'any key was pressed'
+       // signal...
        uint8_t byte = (uint8_t)keyDown << 7;
        keyDown = false;
        return byte;
@@ -501,7 +755,7 @@ uint8_t ReadRAMWRT(uint16_t)
 
 uint8_t ReadSLOTCXROM(uint16_t)
 {
-       return (uint8_t)slotCXROM << 7;
+       return (uint8_t)intCXROM << 7;
 }
 
 
@@ -513,7 +767,6 @@ uint8_t ReadALTZP(uint16_t)
 
 uint8_t ReadSLOTC3ROM(uint16_t)
 {
-//     return 0;
        return (uint8_t)slotC3ROM << 7;
 }
 
@@ -774,300 +1027,6 @@ void SwitchIOUDIS(uint16_t address, uint8_t)
 }
 
 
-uint8_t Slot6R(uint16_t address)
-{
-//WriteLog("Slot6R: address = %X\n", address & 0x0F);
-//     HandleSlot6(address, 0);
-//     return 0;
-       uint8_t state = address & 0x0F;
-
-       switch (state)
-       {
-       case 0x00:
-       case 0x01:
-       case 0x02:
-       case 0x03:
-       case 0x04:
-       case 0x05:
-       case 0x06:
-       case 0x07:
-               floppyDrive.ControlStepper(state);
-               break;
-       case 0x08:
-       case 0x09:
-               floppyDrive.ControlMotor(state & 0x01);
-               break;
-       case 0x0A:
-       case 0x0B:
-               floppyDrive.DriveEnable(state & 0x01);
-               break;
-       case 0x0C:
-               return floppyDrive.ReadWrite();
-               break;
-       case 0x0D:
-               return floppyDrive.GetLatchValue();
-               break;
-       case 0x0E:
-               floppyDrive.SetReadMode();
-               break;
-       case 0x0F:
-               floppyDrive.SetWriteMode();
-               break;
-       }
-
-       return 0;
-}
-
-
-void Slot6W(uint16_t address, uint8_t byte)
-{
-//WriteLog("Slot6W: address = %X, byte= %X\n", address & 0x0F, byte);
-//     HandleSlot6(address, byte);
-       uint8_t state = address & 0x0F;
-
-       switch (state)
-       {
-       case 0x00:
-       case 0x01:
-       case 0x02:
-       case 0x03:
-       case 0x04:
-       case 0x05:
-       case 0x06:
-       case 0x07:
-               floppyDrive.ControlStepper(state);
-               break;
-       case 0x08:
-       case 0x09:
-               floppyDrive.ControlMotor(state & 0x01);
-               break;
-       case 0x0A:
-       case 0x0B:
-               floppyDrive.DriveEnable(state & 0x01);
-               break;
-       case 0x0C:
-               floppyDrive.ReadWrite();
-               break;
-       case 0x0D:
-               floppyDrive.SetLatchValue(byte);
-               break;
-       case 0x0E:
-               floppyDrive.SetReadMode();
-               break;
-       case 0x0F:
-               floppyDrive.SetWriteMode();
-               break;
-       }
-}
-
-
-void HandleSlot6(uint16_t address, uint8_t byte)
-{
-}
-
-
-uint8_t MBRead(uint16_t address)
-{
-#if 1
-       // Not sure [Seems to work OK]
-       if (!slotCXROM)
-       {
-               return slot4Memory[address & 0x00FF];
-       }
-#endif
-
-       uint8_t regNum = address & 0x0F;
-       uint8_t chipNum = (address & 0x80) >> 7;
-
-#if 0
-       WriteLog("MBRead: address = %X [chip %d, reg %X, clock=$%X]\n", address & 0xFF, chipNum, regNum, GetCurrentV65C02Clock());
-#endif
-
-       switch (regNum)
-       {
-       case 0x00:
-               return mbvia[chipNum].orb & mbvia[chipNum].ddrb;
-
-       case 0x01:
-               return mbvia[chipNum].ora & mbvia[chipNum].ddra;
-
-       case 0x02:
-               return mbvia[chipNum].ddrb;
-
-       case 0x03:
-               return mbvia[chipNum].ddra;
-
-       case 0x04:
-               return mbvia[chipNum].timer1counter & 0xFF;
-
-       case 0x05:
-               return (mbvia[chipNum].timer1counter & 0xFF00) >> 8;
-
-       case 0x06:
-               return mbvia[chipNum].timer1latch & 0xFF;
-
-       case 0x07:
-               return (mbvia[chipNum].timer1latch & 0xFF00) >> 8;
-
-       case 0x08:
-               return mbvia[chipNum].timer2counter & 0xFF;
-
-       case 0x09:
-               return (mbvia[chipNum].timer2counter & 0xFF00) >> 8;
-
-       case 0x0B:
-               return mbvia[chipNum].acr;
-
-       case 0x0D:
-               return (mbvia[chipNum].ifr & 0x7F)
-                       | (mbvia[chipNum].ifr & 0x7F ? 0x80 : 0);
-
-       case 0x0E:
-               return mbvia[chipNum].ier | 0x80;
-
-       default:
-               WriteLog("Unhandled 6522 register %X read (chip %d)\n", regNum, chipNum);
-       }
-
-       return 0;
-}
-
-
-static uint8_t regLatch[2];
-void MBWrite(uint16_t address, uint8_t byte)
-{
-       uint8_t regNum = address & 0x0F;
-       uint8_t chipNum = (address & 0x80) >> 7;
-/*
-NOTES:
-bit 7 = L/R channel select (AY chip 1 versus AY chip 2)
-        0 = Left, 1 = Right
-
-Reg. B is connected to BC1, BDIR, RST' (bits 0, 1, 2)
-
-Left VIA IRQ line is tied to 6502 IRQ line
-Rght VIA IRQ line is tied to 6502 NMI line
-
-Register  Function
---------  -------------------------
-0         Output Register B
-1         Output Register A
-2         Data Direction Register B
-3         Data Direction Register A
-4         Timer 1 Low byte counter (& latch)
-5         Timer 1 Hgh byte counter (& latch)
-6         Timer 1 Low byte latch
-7         Timer 1 Hgh byte latch (& reset IRQ flag)
-B         Aux Control Register
-D         Interrupt Flag Register
-E         Interrupt Enable Register
-
-bit 6 of ACR is like so:
-0: Timed interrupt each time Timer 1 is loaded
-1: Continuous interrupts
-
-bit 7 enables PB7 (bit 6 controls output type):
-0: One shot output
-1: Square wave output
-
-
-*/
-#if 0
-       WriteLog("MBWrite: address = %X, byte= %X [clock=$%X]", address & 0xFF, byte, GetCurrentV65C02Clock());
-
-       if (regNum == 0)
-               WriteLog("[OUTB -> %s%s%s]\n", (byte & 0x01 ? "BC1" : ""), (byte & 0x02 ? " BDIR" : ""), (byte & 0x04 ? " RST'" : ""));
-       else if (regNum == 1)
-               WriteLog("[OUTA -> %02X]\n", byte);
-       else if (regNum == 2)
-               WriteLog("[DDRB -> %02X]\n", byte);
-       else if (regNum == 3)
-               WriteLog("[DDRA -> %02X]\n", byte);
-       else
-               WriteLog("\n");
-#endif
-
-       switch (regNum)
-       {
-       case 0x00:
-               // Control of the AY-3-8912 is thru this port pretty much...
-               mbvia[chipNum].orb = byte;
-
-               if ((byte & 0x04) == 0)
-#ifdef USE_NEW_AY8910
-                       AYReset(chipNum);
-#else
-                       AY8910_reset(chipNum);
-#endif
-               else if ((byte & 0x03) == 0x03)
-                       regLatch[chipNum] = mbvia[chipNum].ora;
-               else if ((byte & 0x03) == 0x02)
-#ifdef USE_NEW_AY8910
-                       AYWrite(chipNum, regLatch[chipNum], mbvia[chipNum].ora);
-#else
-                       _AYWriteReg(chipNum, regLatch[chipNum], mbvia[chipNum].ora);
-#endif
-
-               break;
-
-       case 0x01:
-               mbvia[chipNum].ora = byte;
-               break;
-
-       case 0x02:
-               mbvia[chipNum].ddrb = byte;
-               break;
-
-       case 0x03:
-               mbvia[chipNum].ddra = byte;
-               break;
-
-       case 0x04:
-               mbvia[chipNum].timer1latch = (mbvia[chipNum].timer1latch & 0xFF00)
-                       | byte;
-               break;
-
-       case 0x05:
-               mbvia[chipNum].timer1latch = (mbvia[chipNum].timer1latch & 0x00FF)
-                       | (((uint16_t)byte) << 8);
-               mbvia[chipNum].timer1counter = mbvia[chipNum].timer1latch;
-               mbvia[chipNum].ifr &= 0x3F; // Clear T1 interrupt flag
-               break;
-
-       case 0x06:
-               mbvia[chipNum].timer1latch = (mbvia[chipNum].timer1latch & 0xFF00)
-                       | byte;
-               break;
-
-       case 0x07:
-               mbvia[chipNum].timer1latch = (mbvia[chipNum].timer1latch & 0x00FF)
-                       | (((uint16_t)byte) << 8);
-               mbvia[chipNum].ifr &= 0x3F; // Clear T1 interrupt flag
-               break;
-
-       case 0x0B:
-               mbvia[chipNum].acr = byte;
-               break;
-
-       case 0x0D:
-               mbvia[chipNum].ifr &= ~byte;
-               break;
-
-       case 0x0E:
-               if (byte & 0x80)
-                       // Setting bits in the IER
-                       mbvia[chipNum].ier |= byte;
-               else
-                       // Clearing bits in the IER
-                       mbvia[chipNum].ier &= ~byte;
-
-               break;
-       default:
-               WriteLog("Unhandled 6522 register $%X write $%02X (chip %d)\n", regNum, byte, chipNum);
-       }
-}
-
-
 uint8_t ReadButton0(uint16_t)
 {
        return (uint8_t)openAppleDown << 7;
index aed258b6da91774d46a5cbcbaacb5c88f230faaf..8427e769dffcec87bba50253a360bd91e2c71866 100644 (file)
--- a/src/mmu.h
+++ b/src/mmu.h
@@ -3,11 +3,27 @@
 
 #include <stdint.h>
 
+// Macros for function pointers
+#define READFUNC(x) uint8_t (* x)(uint16_t)
+#define WRITEFUNC(x) void (* x)(uint16_t, uint8_t)
+
+struct SlotData
+{
+       READFUNC(ioR);          // I/O read function
+       WRITEFUNC(ioW);         // I/O write function
+       READFUNC(pageR);        // Driver page read function
+       WRITEFUNC(pageW);       // Driver page write function
+       READFUNC(extraR);       // Driver 2K read function
+       WRITEFUNC(extraW);      // Driver 2K write function
+};
+
 void SetupAddressMap(void);
 void ResetMMUPointers(void);
+void InstallSlotHandler(uint8_t slot, SlotData *);
 uint8_t AppleReadMem(uint16_t);
 void AppleWriteMem(uint16_t, uint8_t);
 void SwitchLC(void);
+uint8_t ReadFloatingBus(uint16_t);
 
 #endif // __MMU_H__
 
diff --git a/src/mockingboard.cpp b/src/mockingboard.cpp
new file mode 100644 (file)
index 0000000..c32e5e3
--- /dev/null
@@ -0,0 +1,100 @@
+//
+// Mockingboard support
+//
+// by James Hammons
+// (C) 2018 Underground Software
+//
+// NOTES:
+// bit 7 = L/R channel select (AY chip 1 versus AY chip 2)
+//         0 = Left, 1 = Right
+//
+// Reg. B is connected to BC1, BDIR, RST' (bits 0, 1, 2)
+//
+// Left VIA IRQ line is tied to 6502 IRQ line
+// Rght VIA IRQ line is tied to 6502 NMI line
+//
+
+
+#include "mockingboard.h"
+#include "apple2.h"
+#include "mmu.h"
+
+
+MOCKINGBOARD mb[2];
+
+
+void MBReset(void)
+{
+       mb[0].via[0].Reset();
+       mb[0].via[1].Reset();
+       mb[0].ay[0].Reset();
+       mb[0].ay[1].Reset();
+}
+
+
+void MBWrite(int chipNum, uint8_t reg, uint8_t byte)
+{
+       V6522VIA * chip1 = &mb[0].via[chipNum];
+       chip1->Write(reg, byte);
+
+       if (reg == 0)
+               mb[0].ay[chipNum].WriteControl(chip1->orb & chip1->ddrb);
+       else if (reg == 1)
+               mb[0].ay[chipNum].WriteData(chip1->ora & chip1->ddra);
+}
+
+
+uint8_t MBRead(int chipNum, uint8_t reg)
+{
+       return mb[0].via[chipNum].Read(reg);
+}
+
+
+void MBRun(uint16_t cycles)
+{
+       if (mb[0].via[0].Run(cycles))
+               mainCPU.cpuFlags |= V65C02_ASSERT_LINE_IRQ;
+
+       if (mb[0].via[1].Run(cycles))
+               mainCPU.cpuFlags |= V65C02_ASSERT_LINE_NMI;
+}
+
+
+void MBSaveState(FILE * file)
+{
+       fwrite(&mb[0], 1, sizeof(struct MOCKINGBOARD), file);
+       fwrite(&mb[1], 1, sizeof(struct MOCKINGBOARD), file);
+}
+
+
+void MBLoadState(FILE * file)
+{
+       fread(&mb[0], 1, sizeof(struct MOCKINGBOARD), file);
+       fread(&mb[1], 1, sizeof(struct MOCKINGBOARD), file);
+}
+
+
+static uint8_t SlotPageR(uint16_t address)
+{
+       uint8_t regNum = address & 0x0F;
+       uint8_t chipNum = (address & 0x80) >> 7;
+
+       return MBRead(chipNum, regNum);
+}
+
+
+static void SlotPageW(uint16_t address, uint8_t byte)
+{
+       uint8_t regNum = address & 0x0F;
+       uint8_t chipNum = (address & 0x80) >> 7;
+
+       MBWrite(chipNum, regNum, byte);
+}
+
+
+void InstallMockingboard(uint8_t slot)
+{
+       SlotData mbDevice = { 0, 0, SlotPageR, SlotPageW, 0, 0 };
+       InstallSlotHandler(slot, &mbDevice);
+}
+
diff --git a/src/mockingboard.h b/src/mockingboard.h
new file mode 100644 (file)
index 0000000..f0b99f8
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// Mockingboard support
+//
+// by James Hammons
+// (C) 2018 Underground Software
+//
+
+#ifndef __MOCKINGBOARD_H__
+#define __MOCKINGBOARD_H__
+
+#include <stdint.h>
+#include <stdio.h>
+#include "v6522via.h"
+#include "vay8910.h"
+
+struct MOCKINGBOARD
+{
+       V6522VIA via[2];
+       VAY_3_8910 ay[2];
+};
+
+// Exported variables
+extern MOCKINGBOARD mb[];
+
+// Exported functions
+void MBReset(void);
+void MBWrite(int chipNum, uint8_t reg, uint8_t byte);
+uint8_t MBRead(int chipNum, uint8_t reg);
+void MBRun(uint16_t cycles);
+void MBSaveState(FILE *);
+void MBLoadState(FILE *);
+void InstallMockingboard(uint8_t slot);
+
+#endif // __MOCKINGBOARD_H__
+
diff --git a/src/mos6522via.cpp b/src/mos6522via.cpp
deleted file mode 100644 (file)
index 6632691..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Mockingboard support (6522 interface)
-//
-// by James Hammons
-// (C) 2018 Underground Software
-//
-
-#include "mos6522via.h"
-
-#include <string.h>                                                            // for memset()
-
-
-MOS6522VIA mbvia[4];
-
-
-void ResetMBVIAs(void)
-{
-       for(int i=0; i<4; i++)
-               memset(&mbvia[i], 0, sizeof(MOS6522VIA));
-}
-
index 67b3090b6be2efa9c17f1f64a2efc4a7678fd74d..04b2670cb9ab2987b5e9add084089f1299936452 100644 (file)
@@ -24,8 +24,9 @@
 
 #include <string.h>                    // For memset, memcpy
 #include <SDL2/SDL.h>
-#include "ay8910.h"
 #include "log.h"
+#include "mockingboard.h"
+
 
 // Useful defines
 
@@ -133,7 +134,7 @@ sndFrmCnt++;
 
        if (soundBufferPos < length)
        {
-WriteLog("*** Sound buffer starved (%d short) *** [%d delta %d]\n", length - soundBufferPos, sndFrmCnt, sndFrmCnt - lastStarve);
+//WriteLog("*** Sound buffer starved (%d short) *** [%d delta %d]\n", length - soundBufferPos, sndFrmCnt, sndFrmCnt - lastStarve);
 lastStarve = sndFrmCnt;
 #if 1
                for(uint32_t i=0; i<length; i++)
@@ -171,18 +172,10 @@ lastStarve = sndFrmCnt;
 //
 void WriteSampleToBuffer(void)
 {
-#ifdef USE_NEW_AY8910
-       uint16_t s1 = AYGetSample(0);
-       uint16_t s2 = AYGetSample(1);
-       uint16_t adjustedMockingboard = s1 + s2;
-#else
-       int16_t s1, s2, s3, s4, s5, s6;
-       int16_t * bufPtrs[6] = { &s1, &s2, &s3, &s4, &s5, &s6 };
-       AY8910Update(0, bufPtrs, 1);
-       AY8910Update(1, &bufPtrs[3], 1);
-       int16_t adjustedMockingboard = (s1 / 8) + (s2 / 8) + (s3 / 8)
-               + (s4 / 8) + (s5 / 8) + (s6 / 8);
-#endif
+//     uint16_t s1 = AYGetSample(0);
+//     uint16_t s2 = AYGetSample(1);
+       uint16_t s1 = mb[0].ay[0].GetSample();
+       uint16_t s2 = mb[0].ay[1].GetSample();
 
        // This should almost never happen, but, if it does...
        while (soundBufferPos >= (SOUND_BUFFER_SIZE - 1))
@@ -192,7 +185,7 @@ void WriteSampleToBuffer(void)
        }
 
        SDL_LockAudioDevice(device);
-       soundBuffer[soundBufferPos++] = sample + adjustedMockingboard;
+       soundBuffer[soundBufferPos++] = sample + s1 + s2;
        SDL_UnlockAudioDevice(device);
 }
 
diff --git a/src/v6522via.cpp b/src/v6522via.cpp
new file mode 100644 (file)
index 0000000..f43a267
--- /dev/null
@@ -0,0 +1,198 @@
+//
+// Virtual 6522 Versatile Interface Adapter
+//
+// by James Hammons
+// (C) 2018 Underground Software
+//
+
+#include "v6522via.h"
+
+#include <string.h>            // for memset()
+#include "log.h"
+
+
+/*
+Register  Function
+--------  -------------------------
+0         Output Register B
+1         Output Register A
+2         Data Direction Register B
+3         Data Direction Register A
+4         Timer 1 Low byte counter (& latch)
+5         Timer 1 Hgh byte counter (& latch)
+6         Timer 1 Low byte latch
+7         Timer 1 Hgh byte latch (& reset IRQ flag)
+B         Aux Control Register
+D         Interrupt Flag Register
+E         Interrupt Enable Register
+
+bit 6 of ACR:
+0: Timed interrupt each time Timer 1 is loaded
+1: Continuous interrupts
+
+bit 7 enables PB7 (bit 6 controls output type):
+0: One shot output
+1: Square wave output
+*/
+
+
+V6522VIA::V6522VIA(): orb(0), ora(0), ddrb(0), ddra(0),
+       timer1counter(0), timer1latch(0), timer2counter(0),
+       acr(0), ifr(0), ier(0)
+{
+}
+
+
+void V6522VIA::Reset(void)
+{
+       memset(this, 0, sizeof(V6522VIA));
+}
+
+
+uint8_t V6522VIA::Read(uint8_t regNum)
+{
+       switch (regNum)
+       {
+       case 0x00:
+//For some reason, this prevents Ankh from loading.  Need to figure out what the MB *really* returns in its uninitialized state...
+//             return orb & ddrb;
+               return 0xFF;
+
+       case 0x01:
+               return ora & ddra;
+
+       case 0x02:
+               return ddrb;
+
+       case 0x03:
+               return ddra;
+
+       case 0x04:
+               return timer1counter & 0xFF;
+
+       case 0x05:
+               return (timer1counter & 0xFF00) >> 8;
+
+       case 0x06:
+               return timer1latch & 0xFF;
+
+       case 0x07:
+               return (timer1latch & 0xFF00) >> 8;
+
+       case 0x08:
+               return timer2counter & 0xFF;
+
+       case 0x09:
+               return (timer2counter & 0xFF00) >> 8;
+
+       case 0x0B:
+               return acr;
+
+       case 0x0D:
+               return (ifr & 0x7F) | (ifr & 0x7F ? 0x80 : 0);
+
+       case 0x0E:
+               return ier | 0x80;
+
+       default:
+               WriteLog("Unhandled 6522 register %X read (chip %d)\n", regNum, id);
+       }
+
+       return 0;
+}
+
+
+void V6522VIA::Write(uint8_t regNum, uint8_t byte)
+{
+       switch (regNum)
+       {
+       case 0x00:
+               orb = byte;
+               break;
+
+       case 0x01:
+               ora = byte;
+               break;
+
+       case 0x02:
+               ddrb = byte;
+               break;
+
+       case 0x03:
+               ddra = byte;
+               break;
+
+       case 0x04:
+               timer1latch = (timer1latch & 0xFF00) | byte;
+               break;
+
+       case 0x05:
+               timer1latch = (timer1latch & 0x00FF) | (((uint16_t)byte) << 8);
+               timer1counter = timer1latch;
+               ifr &= 0x3F; // Clear T1 interrupt flag
+               break;
+
+       case 0x06:
+               timer1latch = (timer1latch & 0xFF00)
+                       | byte;
+               break;
+
+       case 0x07:
+               timer1latch = (timer1latch & 0x00FF) | (((uint16_t)byte) << 8);
+               ifr &= 0x3F; // Clear T1 interrupt flag
+               break;
+
+       case 0x0B:
+               acr = byte;
+               break;
+
+       case 0x0D:
+               ifr &= ~byte;
+               break;
+
+       case 0x0E:
+               if (byte & 0x80)
+                       // Setting bits in the IER
+                       ier |= byte;
+               else
+                       // Clearing bits in the IER
+                       ier &= ~byte;
+
+               break;
+       default:
+               WriteLog("Unhandled 6522 register $%X write $%02X (chip %d)\n", regNum, byte, id);
+       }
+}
+
+
+bool V6522VIA::Run(uint16_t cycles)
+{
+       // This is to signal to the caller that we hit an IRQ condition
+       bool response = false;
+       bool viaT1HitZero = (timer1counter <= cycles ? true : false);
+
+       timer1counter -= cycles;
+       timer2counter -= cycles;
+
+       if (viaT1HitZero)
+       {
+               if (acr & 0x40)
+               {
+                       timer1counter += timer1latch;
+
+                       if (ier & 0x40)
+                       {
+                               ifr |= (0x80 | 0x40);
+                               response = true;
+                       }
+               }
+               else
+               {
+                       // Disable T1 interrupt
+                       ier &= 0x3F;
+               }
+       }
+
+       return response;
+}
+
similarity index 61%
rename from src/mos6522via.h
rename to src/v6522via.h
index 4d494a96fc84216e9b599efad816a3e47e824aa1..6e52022eaa2c9d604fe9a464269e5f924cb53177 100644 (file)
@@ -1,15 +1,16 @@
-// Mockingboard support
+//
+// Virtual 6522 Versatile Interface Adapter
 //
 // by James Hammons
 // (C) 2018 Underground Software
 //
 
-#ifndef __MOS6522VIA_H__
-#define __MOS6522VIA_H__
+#ifndef __V6522VIA_H__
+#define __V6522VIA_H__
 
 #include <stdint.h>
 
-struct MOS6522VIA
+struct V6522VIA
 {
        uint8_t orb, ora;               // Output Register B, A
        uint8_t ddrb, ddra;             // Data Direction Register B, A
@@ -19,13 +20,14 @@ struct MOS6522VIA
        uint8_t acr;                    // Auxillary Control Register
        uint8_t ifr;                    // Interrupt Flags Register
        uint8_t ier;                    // Interrupt Enable Register
-};
-
+       uint8_t id;                             // Chip ID # (optional)
 
-extern MOS6522VIA mbvia[];
-
-
-void ResetMBVIAs(void);
+       V6522VIA();
+       void Reset(void);
+       uint8_t Read(uint8_t);
+       void Write(uint8_t, uint8_t);
+       bool Run(uint16_t);
+};
 
-#endif // __MOS6522VIA_H__
+#endif // __V6522VIA_H__
 
index 02dd8461d4e4dff367f5e1271a4ee5bd10d2634a..6a525b7147008b7a5b8c1b40bb60916e263d3bb1 100644 (file)
@@ -17,6 +17,8 @@
 //Apple versions do not--which would seem to indicate a bug either in the RNG
 //algorithm, the 65C02 core, or the Apple hardware. Need to investigate all
 //three!
+//N.B.: There were some lingering bugs in the BCD portions of the ADC and SBC
+//      opcodes; need to test to see if that clears up the problem.
 
 #define __DEBUG__
 //#define __DEBUGMON__
@@ -24,6 +26,7 @@
 #include "v65c02.h"
 
 #ifdef __DEBUG__
+#include <string.h>
 #include "dis65c02.h"
 #include "log.h"
 #endif
 #define SET_I                          (regs->cc |= FLAG_I)
 
 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
+/*
+Not 100% sure (for SET_C_CMP), when we have things like this:
+D0BE: AC 6F D3  LDY  $D36F     [SP=01EC, CC=--.--IZ-, A=AA, X=60, Y=00]
+D0C1: CC 5A D3  CPY  $D35A     [SP=01EC, CC=--.--IZC, A=AA, X=60, Y=00]
+D0C4: F0 0F     BEQ  $D0D5     [SP=01EC, CC=--.--IZC, A=AA, X=60, Y=00]
+D0D5: AD 6E D3  LDA  $D36E     [SP=01EC, CC=--.--I-C, A=0A, X=60, Y=00]
+
+Which shows that $D35A has to be 0 since the Z flag is set.  Why would the carry flag be set on a comparison where the compared items are equal?
+*/
 #define SET_C_ADD(a,b)         (regs->cc = ((uint8_t)(b) > (uint8_t)(~(a)) ? regs->cc | FLAG_C : regs->cc & ~FLAG_C))
 #define SET_C_CMP(a,b)         (regs->cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs->cc | FLAG_C : regs->cc & ~FLAG_C))
 #define SET_ZN(r)                      SET_N(r); SET_Z(r)
@@ -55,9 +67,9 @@
 #define EA_ABS                         FetchMemW(regs->pc)
 #define EA_ABS_X                       FetchMemW(regs->pc) + regs->x
 #define EA_ABS_Y                       FetchMemW(regs->pc) + regs->y
-#define EA_IND_ZP_X                    RdMemW((regs->RdMem(regs->pc++) + regs->x) & 0xFF)
-#define EA_IND_ZP_Y                    RdMemW(regs->RdMem(regs->pc++)) + regs->y
-#define EA_IND_ZP                      RdMemW(regs->RdMem(regs->pc++))
+#define EA_IND_ZP_X                    RdMemWZP((regs->RdMem(regs->pc++) + regs->x) & 0xFF)
+#define EA_IND_ZP_Y                    RdMemWZP(regs->RdMem(regs->pc++)) + regs->y
+#define EA_IND_ZP                      RdMemWZP(regs->RdMem(regs->pc++))
 
 #define READ_IMM                       regs->RdMem(EA_IMM)
 #define READ_ZP                                regs->RdMem(EA_ZP)
 
 static V65C02REGS * regs;
 
-
-//This is probably incorrect, at least WRT to the $x7 and $xF opcodes... !!! FIX !!!
-//Also this doesn't take into account the extra cycle it takes when an indirect
-//fetch (ABS, ABS X/Y, ZP) crosses a page boundary, or extra cycle for BCD
-//add/subtract...
-#warning "Cycle counts are not 100% accurate--!!! FIX !!!"
+// Cycle counts should be correct for the the Rockwell version of the 65C02.
+// Extra cycles for page crossing or BCD mode are accounted for in their
+// respective opcode handlers.
 static uint8_t CPUCycles[256] = {
-#if 0
-       7, 6, 1, 1, 5, 3, 5, 1, 3, 2, 2, 1, 6, 4, 6, 1,
-       2, 5, 5, 1, 5, 4, 6, 1, 2, 4, 2, 1, 6, 4, 6, 1,
-       6, 6, 1, 1, 3, 3, 5, 1, 4, 2, 2, 1, 4, 4, 6, 1,
-       2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 2, 1, 4, 4, 6, 1,
-       6, 6, 1, 1, 1, 3, 5, 1, 3, 2, 2, 1, 3, 4, 6, 1,
-       2, 5, 5, 1, 1, 4, 6, 1, 2, 4, 3, 1, 1, 4, 6, 1,
-       6, 6, 1, 1, 3, 3, 5, 1, 4, 2, 2, 1, 6, 4, 6, 1,
-       2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 4, 1, 6, 4, 6, 1,
-       2, 6, 1, 1, 3, 3, 3, 1, 2, 2, 2, 1, 4, 4, 4, 1,
-       2, 6, 5, 1, 4, 4, 4, 1, 2, 5, 2, 1, 4, 5, 5, 1,
-       2, 6, 2, 1, 3, 3, 3, 1, 2, 2, 2, 1, 4, 4, 4, 1,
-       2, 5, 5, 1, 4, 4, 4, 1, 2, 4, 2, 1, 4, 4, 4, 1,
-       2, 6, 1, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 6, 1,
-       2, 5, 5, 1, 1, 4, 6, 1, 2, 4, 3, 1, 1, 4, 6, 1,
-       2, 6, 1, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 6, 1,
-       2, 5, 5, 1, 1, 4, 6, 1, 2, 4, 4, 1, 1, 4, 6, 1 };
-#else
-       7, 6, 2, 2, 5, 3, 5, 2, 3, 2, 2, 2, 6, 4, 6, 2,
-       2, 5, 5, 2, 5, 4, 6, 2, 2, 4, 2, 2, 6, 4, 6, 2,
-       6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 4, 2, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 6, 2,
-       6, 6, 2, 2, 3, 3, 5, 2, 3, 2, 2, 2, 3, 4, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 8, 4, 6, 2,
-       6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 6, 4, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 6, 4, 6, 2,
-       2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2,
-       2, 6, 5, 2, 4, 4, 4, 2, 2, 5, 2, 2, 4, 5, 5, 2,
-       2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2,
-       2, 5, 5, 2, 4, 4, 4, 2, 2, 4, 2, 2, 4, 4, 4, 2,
-       2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 5, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 4, 4, 6, 2,
-       2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 4, 4, 6, 2 };
-#endif
-
-#if 0
-static uint8_t _6502Cycles[256] = {
-       7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6,
-       2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7,
-       6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 2, 6, 6,
-       2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7,
-       6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6,
-       2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7,
-       6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 6, 4, 6, 6,
-       2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7,
-       2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
-       2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5,
-       2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4,
-       2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4,
-       2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 5, 6,
-       2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7,
-       2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6,
-       2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 6, 7 };
-
-static uint8_t _65C02Cycles[256] = {
-       7, 6, 2, 2, 5, 3, 5, 2, 3, 2, 2, 2, 6, 4, 6, 2,
-       2, 5, 5, 2, 5, 4, 6, 2, 2, 4, 2, 2, 6, 4, 6, 2,
-       6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 4, 2, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 6, 2,
-       6, 6, 2, 2, 3, 3, 5, 2, 3, 2, 2, 2, 3, 4, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 8, 4, 6, 2,
-       6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 6, 4, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 6, 4, 6, 2,
-       2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2,
-       2, 6, 5, 2, 4, 4, 4, 2, 2, 5, 2, 2, 4, 5, 5, 2,
-       2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2,
-       2, 5, 5, 2, 4, 4, 4, 2, 2, 4, 2, 2, 4, 4, 4, 2,
-       2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 5, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 3, 2, 4, 4, 6, 2,
-       2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2,
-       2, 5, 5, 2, 4, 4, 6, 2, 2, 4, 4, 2, 4, 4, 6, 2 };
-#endif
-
-
-/*
-6502 cycles (includes illegal opcodes):
-
-               case 0x00:       BRK         CYC(7)  break;
-               case 0x01:       INDX ORA            CYC(6)  break;
-               case 0x02:   INV HLT         CYC(2)  break;
-               case 0x03:   INV INDX ASO            CYC(8)  break;
-               case 0x04:   INV ZPG NOP             CYC(3)  break;
-               case 0x05:       ZPG ORA             CYC(3)  break;
-               case 0x06:       ZPG ASL_NMOS  CYC(5)  break;
-               case 0x07:   INV ZPG ASO             CYC(5)  break;
-               case 0x08:       PHP         CYC(3)  break;
-               case 0x09:       IMM ORA             CYC(2)  break;
-               case 0x0A:       ASLA        CYC(2)  break;
-               case 0x0B:   INV IMM ANC             CYC(2)  break;
-               case 0x0C:   INV ABSX NOP            CYC(4)  break;
-               case 0x0D:       ABS ORA             CYC(4)  break;
-               case 0x0E:       ABS ASL_NMOS  CYC(6)  break;
-               case 0x0F:   INV ABS ASO             CYC(6)  break;
-               case 0x10:       REL BPL             CYC(2)  break;
-               case 0x11:       INDY ORA            CYC(5)  break;
-               case 0x12:   INV HLT         CYC(2)  break;
-               case 0x13:   INV INDY ASO            CYC(8)  break;
-               case 0x14:   INV ZPGX NOP            CYC(4)  break;
-               case 0x15:       ZPGX ORA            CYC(4)  break;
-               case 0x16:       ZPGX ASL_NMOS CYC(6)  break;
-               case 0x17:   INV ZPGX ASO            CYC(6)  break;
-               case 0x18:       CLC         CYC(2)  break;
-               case 0x19:       ABSY ORA            CYC(4)  break;
-               case 0x1A:   INV NOP         CYC(2)  break;
-               case 0x1B:   INV ABSY ASO            CYC(7)  break;
-               case 0x1C:   INV ABSX NOP            CYC(4)  break;
-               case 0x1D:       ABSX ORA            CYC(4)  break;
-               case 0x1E:       ABSX ASL_NMOS CYC(6)  break;
-               case 0x1F:   INV ABSX ASO            CYC(7)  break;
-               case 0x20:       ABS JSR             CYC(6)  break;
-               case 0x21:       INDX AND            CYC(6)  break;
-               case 0x22:   INV HLT         CYC(2)  break;
-               case 0x23:   INV INDX RLA            CYC(8)  break;
-               case 0x24:       ZPG BIT             CYC(3)  break;
-               case 0x25:       ZPG AND             CYC(3)  break;
-               case 0x26:       ZPG ROL_NMOS  CYC(5)  break;
-               case 0x27:   INV ZPG RLA             CYC(5)  break;
-               case 0x28:       PLP         CYC(4)  break;
-               case 0x29:       IMM AND             CYC(2)  break;
-               case 0x2A:       ROLA        CYC(2)  break;
-               case 0x2B:   INV IMM ANC             CYC(2)  break;
-               case 0x2C:       ABS BIT             CYC(4)  break;
-               case 0x2D:       ABS AND             CYC(2)  break;
-               case 0x2E:       ABS ROL_NMOS  CYC(6)  break;
-               case 0x2F:   INV ABS RLA             CYC(6)  break;
-               case 0x30:       REL BMI             CYC(2)  break;
-               case 0x31:       INDY AND            CYC(5)  break;
-               case 0x32:   INV HLT         CYC(2)  break;
-               case 0x33:   INV INDY RLA            CYC(8)  break;
-               case 0x34:   INV ZPGX NOP            CYC(4)  break;
-               case 0x35:       ZPGX AND            CYC(4)  break;
-               case 0x36:       ZPGX ROL_NMOS CYC(6)  break;
-               case 0x37:   INV ZPGX RLA            CYC(6)  break;
-               case 0x38:       SEC         CYC(2)  break;
-               case 0x39:       ABSY AND            CYC(4)  break;
-               case 0x3A:   INV NOP         CYC(2)  break;
-               case 0x3B:   INV ABSY RLA            CYC(7)  break;
-               case 0x3C:   INV ABSX NOP            CYC(4)  break;
-               case 0x3D:       ABSX AND            CYC(4)  break;
-               case 0x3E:       ABSX ROL_NMOS CYC(6)  break;
-               case 0x3F:   INV ABSX RLA            CYC(7)  break;
-               case 0x40:       RTI         CYC(6)  DoIrqProfiling(uExecutedCycles); break;
-               case 0x41:       INDX EOR            CYC(6)  break;
-               case 0x42:   INV HLT         CYC(2)  break;
-               case 0x43:   INV INDX LSE            CYC(8)  break;
-               case 0x44:   INV ZPG NOP             CYC(3)  break;
-               case 0x45:       ZPG EOR             CYC(3)  break;
-               case 0x46:       ZPG LSR_NMOS  CYC(5)  break;
-               case 0x47:   INV ZPG LSE             CYC(5)  break;
-               case 0x48:       PHA         CYC(3)  break;
-               case 0x49:       IMM EOR             CYC(2)  break;
-               case 0x4A:       LSRA        CYC(2)  break;
-               case 0x4B:   INV IMM ALR             CYC(2)  break;
-               case 0x4C:       ABS JMP             CYC(3)  break;
-               case 0x4D:       ABS EOR             CYC(4)  break;
-               case 0x4E:       ABS LSR_NMOS  CYC(6)  break;
-               case 0x4F:   INV ABS LSE             CYC(6)  break;
-               case 0x50:       REL BVC             CYC(2)  break;
-               case 0x51:       INDY EOR            CYC(5)  break;
-               case 0x52:   INV HLT         CYC(2)  break;
-               case 0x53:   INV INDY LSE            CYC(8)  break;
-               case 0x54:   INV ZPGX NOP            CYC(4)  break;
-               case 0x55:       ZPGX EOR            CYC(4)  break;
-               case 0x56:       ZPGX LSR_NMOS CYC(6)  break;
-               case 0x57:   INV ZPGX LSE            CYC(6)  break;
-               case 0x58:       CLI         CYC(2)  break;
-               case 0x59:       ABSY EOR            CYC(4)  break;
-               case 0x5A:   INV NOP         CYC(2)  break;
-               case 0x5B:   INV ABSY LSE            CYC(7)  break;
-               case 0x5C:   INV ABSX NOP            CYC(4)  break;
-               case 0x5D:       ABSX EOR            CYC(4)  break;
-               case 0x5E:       ABSX LSR_NMOS CYC(6)  break;
-               case 0x5F:   INV ABSX LSE            CYC(7)  break;
-               case 0x60:       RTS         CYC(6)  break;
-               case 0x61:       INDX ADC_NMOS CYC(6)  break;
-               case 0x62:   INV HLT         CYC(2)  break;
-               case 0x63:   INV INDX RRA            CYC(8)  break;
-               case 0x64:   INV ZPG NOP             CYC(3)  break;
-               case 0x65:       ZPG ADC_NMOS  CYC(3)  break;
-               case 0x66:       ZPG ROR_NMOS  CYC(5)  break;
-               case 0x67:   INV ZPG RRA             CYC(5)  break;
-               case 0x68:       PLA         CYC(4)  break;
-               case 0x69:       IMM ADC_NMOS  CYC(2)  break;
-               case 0x6A:       RORA        CYC(2)  break;
-               case 0x6B:   INV IMM ARR             CYC(2)  break;
-               case 0x6C:       IABSNMOS JMP  CYC(6)  break;
-               case 0x6D:       ABS ADC_NMOS  CYC(4)  break;
-               case 0x6E:       ABS ROR_NMOS  CYC(6)  break;
-               case 0x6F:   INV ABS RRA             CYC(6)  break;
-               case 0x70:       REL BVS             CYC(2)  break;
-               case 0x71:       INDY ADC_NMOS CYC(5)  break;
-               case 0x72:   INV HLT         CYC(2)  break;
-               case 0x73:   INV INDY RRA            CYC(8)  break;
-               case 0x74:   INV ZPGX NOP            CYC(4)  break;
-               case 0x75:       ZPGX ADC_NMOS CYC(4)  break;
-               case 0x76:       ZPGX ROR_NMOS CYC(6)  break;
-               case 0x77:   INV ZPGX RRA            CYC(6)  break;
-               case 0x78:       SEI         CYC(2)  break;
-               case 0x79:       ABSY ADC_NMOS CYC(4)  break;
-               case 0x7A:   INV NOP         CYC(2)  break;
-               case 0x7B:   INV ABSY RRA            CYC(7)  break;
-               case 0x7C:   INV ABSX NOP            CYC(4)  break;
-               case 0x7D:       ABSX ADC_NMOS CYC(4)  break;
-               case 0x7E:       ABSX ROR_NMOS CYC(6)  break;
-               case 0x7F:   INV ABSX RRA            CYC(7)  break;
-               case 0x80:   INV IMM NOP             CYC(2)  break;
-               case 0x81:       INDX STA            CYC(6)  break;
-               case 0x82:   INV IMM NOP             CYC(2)  break;
-               case 0x83:   INV INDX AXS            CYC(6)  break;
-               case 0x84:       ZPG STY             CYC(3)  break;
-               case 0x85:       ZPG STA             CYC(3)  break;
-               case 0x86:       ZPG STX             CYC(3)  break;
-               case 0x87:   INV ZPG AXS             CYC(3)  break;
-               case 0x88:       DEY         CYC(2)  break;
-               case 0x89:   INV IMM NOP             CYC(2)  break;
-               case 0x8A:       TXA         CYC(2)  break;
-               case 0x8B:   INV IMM XAA             CYC(2)  break;
-               case 0x8C:       ABS STY             CYC(4)  break;
-               case 0x8D:       ABS STA             CYC(4)  break;
-               case 0x8E:       ABS STX             CYC(4)  break;
-               case 0x8F:   INV ABS AXS             CYC(4)  break;
-               case 0x90:       REL BCC             CYC(2)  break;
-               case 0x91:       INDY STA            CYC(6)  break;
-               case 0x92:   INV HLT         CYC(2)  break;
-               case 0x93:   INV INDY AXA            CYC(6)  break;
-               case 0x94:       ZPGX STY            CYC(4)  break;
-               case 0x95:       ZPGX STA            CYC(4)  break;
-               case 0x96:       ZPGY STX            CYC(4)  break;
-               case 0x97:   INV ZPGY AXS            CYC(4)  break;
-               case 0x98:       TYA         CYC(2)  break;
-               case 0x99:       ABSY STA            CYC(5)  break;
-               case 0x9A:       TXS         CYC(2)  break;
-               case 0x9B:   INV ABSY TAS            CYC(5)  break;
-               case 0x9C:   INV ABSX SAY            CYC(5)  break;
-               case 0x9D:       ABSX STA            CYC(5)  break;
-               case 0x9E:   INV ABSY XAS            CYC(5)  break;
-               case 0x9F:   INV ABSY AXA            CYC(5)  break;
-               case 0xA0:       IMM LDY             CYC(2)  break;
-               case 0xA1:       INDX LDA            CYC(6)  break;
-               case 0xA2:       IMM LDX             CYC(2)  break;
-               case 0xA3:   INV INDX LAX            CYC(6)  break;
-               case 0xA4:       ZPG LDY             CYC(3)  break;
-               case 0xA5:       ZPG LDA             CYC(3)  break;
-               case 0xA6:       ZPG LDX             CYC(3)  break;
-               case 0xA7:   INV ZPG LAX             CYC(3)  break;
-               case 0xA8:       TAY         CYC(2)  break;
-               case 0xA9:       IMM LDA             CYC(2)  break;
-               case 0xAA:       TAX         CYC(2)  break;
-               case 0xAB:   INV IMM OAL             CYC(2)  break;
-               case 0xAC:       ABS LDY             CYC(4)  break;
-               case 0xAD:       ABS LDA             CYC(4)  break;
-               case 0xAE:       ABS LDX             CYC(4)  break;
-               case 0xAF:   INV ABS LAX             CYC(4)  break;
-               case 0xB0:       REL BCS             CYC(2)  break;
-               case 0xB1:       INDY LDA            CYC(5)  break;
-               case 0xB2:   INV HLT         CYC(2)  break;
-               case 0xB3:   INV INDY LAX            CYC(5)  break;
-               case 0xB4:       ZPGX LDY            CYC(4)  break;
-               case 0xB5:       ZPGX LDA            CYC(4)  break;
-               case 0xB6:       ZPGY LDX            CYC(4)  break;
-               case 0xB7:   INV ZPGY LAX            CYC(4)  break;
-               case 0xB8:       CLV         CYC(2)  break;
-               case 0xB9:       ABSY LDA            CYC(4)  break;
-               case 0xBA:       TSX         CYC(2)  break;
-               case 0xBB:   INV ABSY LAS            CYC(4)  break;
-               case 0xBC:       ABSX LDY            CYC(4)  break;
-               case 0xBD:       ABSX LDA            CYC(4)  break;
-               case 0xBE:       ABSY LDX            CYC(4)  break;
-               case 0xBF:   INV ABSY LAX            CYC(4)  break;
-               case 0xC0:       IMM CPY             CYC(2)  break;
-               case 0xC1:       INDX CMP            CYC(6)  break;
-               case 0xC2:   INV IMM NOP             CYC(2)  break;
-               case 0xC3:   INV INDX DCM            CYC(8)  break;
-               case 0xC4:       ZPG CPY             CYC(3)  break;
-               case 0xC5:       ZPG CMP             CYC(3)  break;
-               case 0xC6:       ZPG DEC_NMOS  CYC(5)  break;
-               case 0xC7:   INV ZPG DCM             CYC(5)  break;
-               case 0xC8:       INY         CYC(2)  break;
-               case 0xC9:       IMM CMP             CYC(2)  break;
-               case 0xCA:       DEX         CYC(2)  break;
-               case 0xCB:   INV IMM SAX             CYC(2)  break;
-               case 0xCC:       ABS CPY             CYC(4)  break;
-               case 0xCD:       ABS CMP             CYC(4)  break;
-               case 0xCE:       ABS DEC_NMOS  CYC(5)  break;
-               case 0xCF:   INV ABS DCM             CYC(6)  break;
-               case 0xD0:       REL BNE             CYC(2)  break;
-               case 0xD1:       INDY CMP            CYC(5)  break;
-               case 0xD2:   INV HLT         CYC(2)  break;
-               case 0xD3:   INV INDY DCM            CYC(8)  break;
-               case 0xD4:   INV ZPGX NOP            CYC(4)  break;
-               case 0xD5:       ZPGX CMP            CYC(4)  break;
-               case 0xD6:       ZPGX DEC_NMOS CYC(6)  break;
-               case 0xD7:   INV ZPGX DCM            CYC(6)  break;
-               case 0xD8:       CLD         CYC(2)  break;
-               case 0xD9:       ABSY CMP            CYC(4)  break;
-               case 0xDA:   INV NOP         CYC(2)  break;
-               case 0xDB:   INV ABSY DCM            CYC(7)  break;
-               case 0xDC:   INV ABSX NOP            CYC(4)  break;
-               case 0xDD:       ABSX CMP            CYC(4)  break;
-               case 0xDE:       ABSX DEC_NMOS CYC(6)  break;
-               case 0xDF:   INV ABSX DCM            CYC(7)  break;
-               case 0xE0:       IMM CPX             CYC(2)  break;
-               case 0xE1:       INDX SBC_NMOS CYC(6)  break;
-               case 0xE2:   INV IMM NOP             CYC(2)  break;
-               case 0xE3:   INV INDX INS            CYC(8)  break;
-               case 0xE4:       ZPG CPX             CYC(3)  break;
-               case 0xE5:       ZPG SBC_NMOS  CYC(3)  break;
-               case 0xE6:       ZPG INC_NMOS  CYC(5)  break;
-               case 0xE7:   INV ZPG INS             CYC(5)  break;
-               case 0xE8:       INX         CYC(2)  break;
-               case 0xE9:       IMM SBC_NMOS  CYC(2)  break;
-               case 0xEA:       NOP         CYC(2)  break;
-               case 0xEB:   INV IMM SBC_NMOS  CYC(2)  break;
-               case 0xEC:       ABS CPX             CYC(4)  break;
-               case 0xED:       ABS SBC_NMOS  CYC(4)  break;
-               case 0xEE:       ABS INC_NMOS  CYC(6)  break;
-               case 0xEF:   INV ABS INS             CYC(6)  break;
-               case 0xF0:       REL BEQ             CYC(2)  break;
-               case 0xF1:       INDY SBC_NMOS CYC(5)  break;
-               case 0xF2:   INV HLT         CYC(2)  break;
-               case 0xF3:   INV INDY INS            CYC(8)  break;
-               case 0xF4:   INV ZPGX NOP            CYC(4)  break;
-               case 0xF5:       ZPGX SBC_NMOS CYC(4)  break;
-               case 0xF6:       ZPGX INC_NMOS CYC(6)  break;
-               case 0xF7:   INV ZPGX INS            CYC(6)  break;
-               case 0xF8:       SED         CYC(2)  break;
-               case 0xF9:       ABSY SBC_NMOS CYC(4)  break;
-               case 0xFA:   INV NOP         CYC(2)  break;
-               case 0xFB:   INV ABSY INS            CYC(7)  break;
-               case 0xFC:   INV ABSX NOP            CYC(4)  break;
-               case 0xFD:       ABSX SBC_NMOS CYC(4)  break;
-               case 0xFE:       ABSX INC_NMOS CYC(6)  break;
-               case 0xFF:   INV ABSX INS            CYC(7)  break;
-
-
-65C02 opcodes: (all illegal are NOP, but have cycle counts)
-
-               case 0x00:       BRK         CYC(7)  break;
-               case 0x01:       INDX ORA            CYC(6)  break;
-               case 0x02:   INV IMM NOP             CYC(2)  break;
-               case 0x03:   INV NOP         CYC(2)  break;
-               case 0x04:       ZPG TSB             CYC(5)  break;
-               case 0x05:       ZPG ORA             CYC(3)  break;
-               case 0x06:       ZPG ASL_CMOS  CYC(5)  break;
-               case 0x07:   INV NOP         CYC(2)  break;
-               case 0x08:       PHP         CYC(3)  break;
-               case 0x09:       IMM ORA             CYC(2)  break;
-               case 0x0A:       ASLA        CYC(2)  break;
-               case 0x0B:   INV NOP         CYC(2)  break;
-               case 0x0C:       ABS TSB             CYC(6)  break;
-               case 0x0D:       ABS ORA             CYC(4)  break;
-               case 0x0E:       ABS ASL_CMOS  CYC(6)  break;
-               case 0x0F:   INV NOP         CYC(2)  break;
-               case 0x10:       REL BPL             CYC(2)  break;
-               case 0x11:       INDY ORA            CYC(5)  break;
-               case 0x12:       IZPG ORA            CYC(5)  break;
-               case 0x13:   INV NOP         CYC(2)  break;
-               case 0x14:       ZPG TRB             CYC(5)  break;
-               case 0x15:       ZPGX ORA            CYC(4)  break;
-               case 0x16:       ZPGX ASL_CMOS CYC(6)  break;
-               case 0x17:   INV NOP         CYC(2)  break;
-               case 0x18:       CLC         CYC(2)  break;
-               case 0x19:       ABSY ORA            CYC(4)  break;
-               case 0x1A:       INA         CYC(2)  break;
-               case 0x1B:   INV NOP         CYC(2)  break;
-               case 0x1C:       ABS TRB             CYC(6)  break;
-               case 0x1D:       ABSX ORA            CYC(4)  break;
-               case 0x1E:       ABSX ASL_CMOS CYC(6)  break;
-               case 0x1F:   INV NOP         CYC(2)  break;
-               case 0x20:       ABS JSR             CYC(6)  break;
-               case 0x21:       INDX AND            CYC(6)  break;
-               case 0x22:   INV IMM NOP             CYC(2)  break;
-               case 0x23:   INV NOP         CYC(2)  break;
-               case 0x24:       ZPG BIT             CYC(3)  break;
-               case 0x25:       ZPG AND             CYC(3)  break;
-               case 0x26:       ZPG ROL_CMOS  CYC(5)  break;
-               case 0x27:   INV NOP         CYC(2)  break;
-               case 0x28:       PLP         CYC(4)  break;
-               case 0x29:       IMM AND             CYC(2)  break;
-               case 0x2A:       ROLA        CYC(2)  break;
-               case 0x2B:   INV NOP         CYC(2)  break;
-               case 0x2C:       ABS BIT             CYC(4)  break;
-               case 0x2D:       ABS AND             CYC(2)  break;
-               case 0x2E:       ABS ROL_CMOS  CYC(6)  break;
-               case 0x2F:   INV NOP         CYC(2)  break;
-               case 0x30:       REL BMI             CYC(2)  break;
-               case 0x31:       INDY AND            CYC(5)  break;
-               case 0x32:       IZPG AND            CYC(5)  break;
-               case 0x33:   INV NOP         CYC(2)  break;
-               case 0x34:       ZPGX BIT            CYC(4)  break;
-               case 0x35:       ZPGX AND            CYC(4)  break;
-               case 0x36:       ZPGX ROL_CMOS CYC(6)  break;
-               case 0x37:   INV NOP         CYC(2)  break;
-               case 0x38:       SEC         CYC(2)  break;
-               case 0x39:       ABSY AND            CYC(4)  break;
-               case 0x3A:       DEA         CYC(2)  break;
-               case 0x3B:   INV NOP         CYC(2)  break;
-               case 0x3C:       ABSX BIT            CYC(4)  break;
-               case 0x3D:       ABSX AND            CYC(4)  break;
-               case 0x3E:       ABSX ROL_CMOS CYC(6)  break;
-               case 0x3F:   INV NOP         CYC(2)  break;
-               case 0x40:       RTI         CYC(6)  DoIrqProfiling(uExecutedCycles); break;
-               case 0x41:       INDX EOR            CYC(6)  break;
-               case 0x42:   INV IMM NOP             CYC(2)  break;
-               case 0x43:   INV NOP         CYC(2)  break;
-               case 0x44:   INV ZPG NOP             CYC(3)  break;
-               case 0x45:       ZPG EOR             CYC(3)  break;
-               case 0x46:       ZPG LSR_CMOS  CYC(5)  break;
-               case 0x47:   INV NOP         CYC(2)  break;
-               case 0x48:       PHA         CYC(3)  break;
-               case 0x49:       IMM EOR             CYC(2)  break;
-               case 0x4A:       LSRA        CYC(2)  break;
-               case 0x4B:   INV NOP         CYC(2)  break;
-               case 0x4C:       ABS JMP             CYC(3)  break;
-               case 0x4D:       ABS EOR             CYC(4)  break;
-               case 0x4E:       ABS LSR_CMOS  CYC(6)  break;
-               case 0x4F:   INV NOP         CYC(2)  break;
-               case 0x50:       REL BVC             CYC(2)  break;
-               case 0x51:       INDY EOR            CYC(5)  break;
-               case 0x52:       IZPG EOR            CYC(5)  break;
-               case 0x53:   INV NOP         CYC(2)  break;
-               case 0x54:   INV ZPGX NOP            CYC(4)  break;
-               case 0x55:       ZPGX EOR            CYC(4)  break;
-               case 0x56:       ZPGX LSR_CMOS CYC(6)  break;
-               case 0x57:   INV NOP         CYC(2)  break;
-               case 0x58:       CLI         CYC(2)  break;
-               case 0x59:       ABSY EOR            CYC(4)  break;
-               case 0x5A:       PHY         CYC(3)  break;
-               case 0x5B:   INV NOP         CYC(2)  break;
-               case 0x5C:   INV ABSX NOP            CYC(8)  break;
-               case 0x5D:       ABSX EOR            CYC(4)  break;
-               case 0x5E:       ABSX LSR_CMOS CYC(6)  break;
-               case 0x5F:   INV NOP         CYC(2)  break;
-               case 0x60:       RTS         CYC(6)  break;
-               case 0x61:       INDX ADC_CMOS CYC(6)  break;
-               case 0x62:   INV IMM NOP             CYC(2)  break;
-               case 0x63:   INV NOP         CYC(2)  break;
-               case 0x64:       ZPG STZ             CYC(3)  break;
-               case 0x65:       ZPG ADC_CMOS  CYC(3)  break;
-               case 0x66:       ZPG ROR_CMOS  CYC(5)  break;
-               case 0x67:   INV NOP         CYC(2)  break;
-               case 0x68:       PLA         CYC(4)  break;
-               case 0x69:       IMM ADC_CMOS  CYC(2)  break;
-               case 0x6A:       RORA        CYC(2)  break;
-               case 0x6B:   INV NOP         CYC(2)  break;
-               case 0x6C:       IABSCMOS JMP  CYC(6)  break;
-               case 0x6D:       ABS ADC_CMOS  CYC(4)  break;
-               case 0x6E:       ABS ROR_CMOS  CYC(6)  break;
-               case 0x6F:   INV NOP         CYC(2)  break;
-               case 0x70:       REL BVS             CYC(2)  break;
-               case 0x71:       INDY ADC_CMOS CYC(5)  break;
-               case 0x72:       IZPG ADC_CMOS CYC(5)  break;
-               case 0x73:   INV NOP         CYC(2)  break;
-               case 0x74:       ZPGX STZ            CYC(4)  break;
-               case 0x75:       ZPGX ADC_CMOS CYC(4)  break;
-               case 0x76:       ZPGX ROR_CMOS CYC(6)  break;
-               case 0x77:   INV NOP         CYC(2)  break;
-               case 0x78:       SEI         CYC(2)  break;
-               case 0x79:       ABSY ADC_CMOS CYC(4)  break;
-               case 0x7A:       PLY         CYC(4)  break;
-               case 0x7B:   INV NOP         CYC(2)  break;
-               case 0x7C:       IABSX JMP     CYC(6)  break;
-               case 0x7D:       ABSX ADC_CMOS CYC(4)  break;
-               case 0x7E:       ABSX ROR_CMOS CYC(6)  break;
-               case 0x7F:   INV NOP         CYC(2)  break;
-               case 0x80:       REL BRA             CYC(2)  break;
-               case 0x81:       INDX STA            CYC(6)  break;
-               case 0x82:   INV IMM NOP             CYC(2)  break;
-               case 0x83:   INV NOP         CYC(2)  break;
-               case 0x84:       ZPG STY             CYC(3)  break;
-               case 0x85:       ZPG STA             CYC(3)  break;
-               case 0x86:       ZPG STX             CYC(3)  break;
-               case 0x87:   INV NOP         CYC(2)  break;
-               case 0x88:       DEY         CYC(2)  break;
-               case 0x89:       IMM BITI            CYC(2)  break;
-               case 0x8A:       TXA         CYC(2)  break;
-               case 0x8B:   INV NOP         CYC(2)  break;
-               case 0x8C:       ABS STY             CYC(4)  break;
-               case 0x8D:       ABS STA             CYC(4)  break;
-               case 0x8E:       ABS STX             CYC(4)  break;
-               case 0x8F:   INV NOP         CYC(2)  break;
-               case 0x90:       REL BCC             CYC(2)  break;
-               case 0x91:       INDY STA            CYC(6)  break;
-               case 0x92:       IZPG STA            CYC(5)  break;
-               case 0x93:   INV NOP         CYC(2)  break;
-               case 0x94:       ZPGX STY            CYC(4)  break;
-               case 0x95:       ZPGX STA            CYC(4)  break;
-               case 0x96:       ZPGY STX            CYC(4)  break;
-               case 0x97:   INV NOP         CYC(2)  break;
-               case 0x98:       TYA         CYC(2)  break;
-               case 0x99:       ABSY STA            CYC(5)  break;
-               case 0x9A:       TXS         CYC(2)  break;
-               case 0x9B:   INV NOP         CYC(2)  break;
-               case 0x9C:       ABS STZ             CYC(4)  break;
-               case 0x9D:       ABSX STA            CYC(5)  break;
-               case 0x9E:       ABSX STZ            CYC(5)  break;
-               case 0x9F:   INV NOP         CYC(2)  break;
-               case 0xA0:       IMM LDY             CYC(2)  break;
-               case 0xA1:       INDX LDA            CYC(6)  break;
-               case 0xA2:       IMM LDX             CYC(2)  break;
-               case 0xA3:   INV NOP         CYC(2)  break;
-               case 0xA4:       ZPG LDY             CYC(3)  break;
-               case 0xA5:       ZPG LDA             CYC(3)  break;
-               case 0xA6:       ZPG LDX             CYC(3)  break;
-               case 0xA7:   INV NOP         CYC(2)  break;
-               case 0xA8:       TAY         CYC(2)  break;
-               case 0xA9:       IMM LDA             CYC(2)  break;
-               case 0xAA:       TAX         CYC(2)  break;
-               case 0xAB:   INV NOP         CYC(2)  break;
-               case 0xAC:       ABS LDY             CYC(4)  break;
-               case 0xAD:       ABS LDA             CYC(4)  break;
-               case 0xAE:       ABS LDX             CYC(4)  break;
-               case 0xAF:   INV NOP         CYC(2)  break;
-               case 0xB0:       REL BCS             CYC(2)  break;
-               case 0xB1:       INDY LDA            CYC(5)  break;
-               case 0xB2:       IZPG LDA            CYC(5)  break;
-               case 0xB3:   INV NOP         CYC(2)  break;
-               case 0xB4:       ZPGX LDY            CYC(4)  break;
-               case 0xB5:       ZPGX LDA            CYC(4)  break;
-               case 0xB6:       ZPGY LDX            CYC(4)  break;
-               case 0xB7:   INV NOP         CYC(2)  break;
-               case 0xB8:       CLV         CYC(2)  break;
-               case 0xB9:       ABSY LDA            CYC(4)  break;
-               case 0xBA:       TSX         CYC(2)  break;
-               case 0xBB:   INV NOP         CYC(2)  break;
-               case 0xBC:       ABSX LDY            CYC(4)  break;
-               case 0xBD:       ABSX LDA            CYC(4)  break;
-               case 0xBE:       ABSY LDX            CYC(4)  break;
-               case 0xBF:   INV NOP         CYC(2)  break;
-               case 0xC0:       IMM CPY             CYC(2)  break;
-               case 0xC1:       INDX CMP            CYC(6)  break;
-               case 0xC2:   INV IMM NOP             CYC(2)  break;
-               case 0xC3:   INV NOP         CYC(2)  break;
-               case 0xC4:       ZPG CPY             CYC(3)  break;
-               case 0xC5:       ZPG CMP             CYC(3)  break;
-               case 0xC6:       ZPG DEC_CMOS  CYC(5)  break;
-               case 0xC7:   INV NOP         CYC(2)  break;
-               case 0xC8:       INY         CYC(2)  break;
-               case 0xC9:       IMM CMP             CYC(2)  break;
-               case 0xCA:       DEX         CYC(2)  break;
-               case 0xCB:   INV NOP         CYC(2)  break;
-               case 0xCC:       ABS CPY             CYC(4)  break;
-               case 0xCD:       ABS CMP             CYC(4)  break;
-               case 0xCE:       ABS DEC_CMOS  CYC(5)  break;
-               case 0xCF:   INV NOP         CYC(2)  break;
-               case 0xD0:       REL BNE             CYC(2)  break;
-               case 0xD1:       INDY CMP            CYC(5)  break;
-               case 0xD2:       IZPG CMP            CYC(5)  break;
-               case 0xD3:   INV NOP         CYC(2)  break;
-               case 0xD4:   INV ZPGX NOP            CYC(4)  break;
-               case 0xD5:       ZPGX CMP            CYC(4)  break;
-               case 0xD6:       ZPGX DEC_CMOS CYC(6)  break;
-               case 0xD7:   INV NOP         CYC(2)  break;
-               case 0xD8:       CLD         CYC(2)  break;
-               case 0xD9:       ABSY CMP            CYC(4)  break;
-               case 0xDA:       PHX         CYC(3)  break;
-               case 0xDB:   INV NOP         CYC(2)  break;
-               case 0xDC:   INV ABSX NOP            CYC(4)  break;
-               case 0xDD:       ABSX CMP            CYC(4)  break;
-               case 0xDE:       ABSX DEC_CMOS CYC(6)  break;
-               case 0xDF:   INV NOP         CYC(2)  break;
-               case 0xE0:       IMM CPX             CYC(2)  break;
-               case 0xE1:       INDX SBC_CMOS CYC(6)  break;
-               case 0xE2:   INV IMM NOP             CYC(2)  break;
-               case 0xE3:   INV NOP         CYC(2)  break;
-               case 0xE4:       ZPG CPX             CYC(3)  break;
-               case 0xE5:       ZPG SBC_CMOS  CYC(3)  break;
-               case 0xE6:       ZPG INC_CMOS  CYC(5)  break;
-               case 0xE7:   INV NOP         CYC(2)  break;
-               case 0xE8:       INX         CYC(2)  break;
-               case 0xE9:       IMM SBC_CMOS  CYC(2)  break;
-               case 0xEA:       NOP         CYC(2)  break;
-               case 0xEB:   INV NOP         CYC(2)  break;
-               case 0xEC:       ABS CPX             CYC(4)  break;
-               case 0xED:       ABS SBC_CMOS  CYC(4)  break;
-               case 0xEE:       ABS INC_CMOS  CYC(6)  break;
-               case 0xEF:   INV NOP         CYC(2)  break;
-               case 0xF0:       REL BEQ             CYC(2)  break;
-               case 0xF1:       INDY SBC_CMOS CYC(5)  break;
-               case 0xF2:       IZPG SBC_CMOS CYC(5)  break;
-               case 0xF3:   INV NOP         CYC(2)  break;
-               case 0xF4:   INV ZPGX NOP            CYC(4)  break;
-               case 0xF5:       ZPGX SBC_CMOS CYC(4)  break;
-               case 0xF6:       ZPGX INC_CMOS CYC(6)  break;
-               case 0xF7:   INV NOP         CYC(2)  break;
-               case 0xF8:       SED         CYC(2)  break;
-               case 0xF9:       ABSY SBC_CMOS CYC(4)  break;
-               case 0xFA:       PLX         CYC(4)  break;
-               case 0xFB:   INV NOP         CYC(2)  break;
-               case 0xFC:   INV ABSX NOP            CYC(4)  break;
-               case 0xFD:       ABSX SBC_CMOS CYC(4)  break;
-               case 0xFE:       ABSX INC_CMOS CYC(6)  break;
-               case 0xFF:   INV NOP         CYC(2)  break;
-*/
+       7, 6, 2, 2, 5, 3, 5, 5, 3, 2, 2, 2, 6, 4, 6, 5,
+       2, 5, 5, 2, 5, 4, 6, 5, 2, 4, 2, 2, 6, 4, 6, 5,
+       6, 6, 2, 2, 3, 3, 5, 5, 4, 2, 2, 2, 4, 2, 6, 5,
+       2, 5, 5, 2, 4, 4, 6, 5, 2, 4, 2, 2, 4, 4, 6, 5,
+       6, 6, 2, 2, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 5,
+       2, 5, 5, 2, 4, 4, 6, 5, 2, 4, 3, 2, 8, 4, 6, 5,
+       6, 6, 2, 2, 3, 3, 5, 5, 4, 2, 2, 2, 6, 4, 6, 5,
+       2, 5, 5, 2, 4, 4, 6, 5, 2, 4, 4, 2, 6, 4, 6, 5,
+       2, 6, 2, 2, 3, 3, 3, 5, 2, 2, 2, 2, 4, 4, 4, 5,
+       2, 6, 5, 2, 4, 4, 4, 5, 2, 5, 2, 2, 4, 5, 5, 5,
+       2, 6, 2, 2, 3, 3, 3, 5, 2, 2, 2, 2, 4, 4, 4, 5,
+       2, 5, 5, 2, 4, 4, 4, 5, 2, 4, 2, 2, 4, 4, 4, 5,
+       2, 6, 2, 2, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 5, 5,
+       2, 5, 5, 2, 4, 4, 6, 5, 2, 4, 3, 2, 4, 4, 6, 5,
+       2, 6, 2, 2, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 5,
+       2, 5, 5, 2, 4, 4, 6, 5, 2, 4, 4, 2, 4, 4, 6, 5 };
 
 
 //
@@ -696,7 +126,18 @@ static uint8_t _65C02Cycles[256] = {
 //
 static inline uint16_t RdMemW(uint16_t address)
 {
-       return (uint16_t)(regs->RdMem(address + 1) << 8) | regs->RdMem(address + 0);
+       return (uint16_t)(regs->RdMem(address + 1) << 8)
+               | regs->RdMem(address + 0);
+}
+
+
+//
+// Read a uint16_t out of 65C02 memory (big endian format), wrapping on page 0
+//
+static inline uint16_t RdMemWZP(uint16_t address)
+{
+       return (uint16_t)(regs->RdMem((address + 1) & 0xFF) << 8)
+               | regs->RdMem(address + 0);
 }
 
 
@@ -706,19 +147,53 @@ static inline uint16_t RdMemW(uint16_t address)
 static inline uint16_t FetchMemW(uint16_t address)
 {
        regs->pc += 2;
-       return (uint16_t)(regs->RdMem(address + 1) << 8) | regs->RdMem(address + 0);
+       return (uint16_t)(regs->RdMem(address + 1) << 8)
+               | regs->RdMem(address + 0);
 }
 
 
 //
 // 65C02 OPCODE IMPLEMENTATION
 //
-// NOTE: Lots of macros are used here to save a LOT of typing. Also
-//       helps speed the debugging process. :-) Because of this, combining
+// NOTE: Lots of macros are used here to save a LOT of typing.  Also
+//       helps speed the debugging process.  :-)  Because of this, combining
 //       certain lines may look like a good idea but would end in disaster.
-//       You have been warned! ;-)
+//       You have been warned!  ;-)
 //
 
+// Page crossing macros.  These catch the cases where access of a certain type
+// will incur a one cycle penalty when crossing a page boundary.
+
+#define HANDLE_PAGE_CROSSING_IND_Y \
+       uint16_t addressLo = regs->RdMem(regs->RdMem(regs->pc)); \
+\
+       if ((addressLo + regs->y) > 0xFF) \
+               regs->clock++;
+
+#define HANDLE_PAGE_CROSSING_ABS_X \
+       uint16_t addressLo = regs->RdMem(regs->pc); \
+\
+       if ((addressLo + regs->x) > 0xFF) \
+               regs->clock++;
+
+#define HANDLE_PAGE_CROSSING_ABS_Y \
+       uint16_t addressLo = regs->RdMem(regs->pc); \
+\
+       if ((addressLo + regs->y) > 0xFF) \
+               regs->clock++;
+
+// Branch taken adds a cycle, crossing page adds one more
+
+#define HANDLE_BRANCH_TAKEN(m)       \
+{                                    \
+       uint16_t oldpc = regs->pc;       \
+       regs->pc += m;                   \
+       regs->clock++;                   \
+                                     \
+       if ((oldpc ^ regs->pc) & 0xFF00) \
+               regs->clock++;               \
+}
+
 /*
 Mnemonic       Addressing mode Form            Opcode  Size    Timing
 
@@ -736,16 +211,24 @@ ADC                       Immediate               ADC #Oper       69              2               2
 // ADC opcodes
 
 //This is non-optimal, but it works--optimize later. :-)
+//N.B.: We have to pull the low nybble from each part of the sum in order to
+//      check BCD addition of the low nybble correctly.  It doesn't work to
+//      look at the sum after summing the bytes.  Also, Decimal mode incurs a
+//      one cycle penalty (for the decimal correction).
 #define OP_ADC_HANDLER(m) \
        uint16_t sum = (uint16_t)regs->a + (m) + (uint16_t)(regs->cc & FLAG_C); \
 \
        if (regs->cc & FLAG_D) \
        { \
-               if ((sum & 0x0F) > 0x09) \
+               uint8_t an = regs->a & 0x0F, mn = (m) & 0x0F, cn = (uint8_t)(regs->cc & FLAG_C); \
+\
+               if ((an + mn + cn) > 9) \
                        sum += 0x06; \
 \
-               if ((sum & 0xF0) > 0x90) \
+               if ((sum & 0x1F0) > 0x90) \
                        sum += 0x60; \
+\
+               regs->clock++;\
        } \
 \
        regs->cc = (regs->cc & ~FLAG_C) | (sum >> 8); \
@@ -779,12 +262,14 @@ static void Op6D(void)                                                    // ADC ABS
 
 static void Op7D(void)                                                 // ADC ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint16_t m = READ_ABS_X;
        OP_ADC_HANDLER(m);
 }
 
 static void Op79(void)                                                 // ADC ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint16_t m = READ_ABS_Y;
        OP_ADC_HANDLER(m);
 }
@@ -797,6 +282,7 @@ static void Op61(void)                                                      // ADC (ZP, X)
 
 static void Op71(void)                                                 // ADC (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint16_t m = READ_IND_ZP_Y;
        OP_ADC_HANDLER(m);
 }
@@ -851,12 +337,14 @@ static void Op2D(void)                                                    // AND ABS
 
 static void Op3D(void)                                                 // AND ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_AND_HANDLER(m);
 }
 
 static void Op39(void)                                                 // AND ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint8_t m = READ_ABS_Y;
        OP_AND_HANDLER(m);
 }
@@ -869,6 +357,7 @@ static void Op21(void)                                                      // AND (ZP, X)
 
 static void Op31(void)                                                 // AND (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint8_t m = READ_IND_ZP_Y;
        OP_AND_HANDLER(m);
 }
@@ -925,6 +414,7 @@ static void Op0E(void)                                                      // ASL ABS
 
 static void Op1E(void)                                                 // ASL ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m;
        READ_ABS_X_WB(m);
        OP_ASL_HANDLER(m);
@@ -932,152 +422,168 @@ static void Op1E(void)                                                  // ASL ABS, X
 }
 
 /*
-BBR0   Relative        BBR0 Oper       0F      2       2
-BBR1   Relative        BBR1 Oper       1F      2       2
-BBR2   Relative        BBR2 Oper       2F      2       2
-BBR3   Relative        BBR3 Oper       3F      2       2
-BBR4   Relative        BBR4 Oper       4F      2       2
-BBR5   Relative        BBR5 Oper       5F      2       2
-BBR6   Relative        BBR6 Oper       6F      2       2
-BBR7   Relative        BBR7 Oper       7F      2       2
-BBS0   Relative        BBS0 Oper       8F      2       2
-BBS1   Relative        BBS1 Oper       9F      2       2
-BBS2   Relative        BBS2 Oper       AF      2       2
-BBS3   Relative        BBS3 Oper       BF      2       2
-BBS4   Relative        BBS4 Oper       CF      2       2
-BBS5   Relative        BBS5 Oper       DF      2       2
-BBS6   Relative        BBS6 Oper       EF      2       2
-BBS7   Relative        BBS7 Oper       FF      2       2
+BBR0   ZP, Relative    BBR0 Oper       0F      3       5
+BBR1   ZP, Relative    BBR1 Oper       1F      3       5
+BBR2   ZP, Relative    BBR2 Oper       2F      3       5
+BBR3   ZP, Relative    BBR3 Oper       3F      3       5
+BBR4   ZP, Relative    BBR4 Oper       4F      3       5
+BBR5   ZP, Relative    BBR5 Oper       5F      3       5
+BBR6   ZP, Relative    BBR6 Oper       6F      3       5
+BBR7   ZP, Relative    BBR7 Oper       7F      3       5
+BBS0   ZP, Relative    BBS0 Oper       8F      3       5
+BBS1   ZP, Relative    BBS1 Oper       9F      3       5
+BBS2   ZP, Relative    BBS2 Oper       AF      3       5
+BBS3   ZP, Relative    BBS3 Oper       BF      3       5
+BBS4   ZP, Relative    BBS4 Oper       CF      3       5
+BBS5   ZP, Relative    BBS5 Oper       DF      3       5
+BBS6   ZP, Relative    BBS6 Oper       EF      3       5
+BBS7   ZP, Relative    BBS7 Oper       FF      3       5
 */
 
 // BBR/Sn opcodes
 
 static void Op0F(void)                                                 // BBR0
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x01))
-               regs->pc += m;
+       if (!(b & 0x01))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op1F(void)                                                 // BBR1
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x02))
-               regs->pc += m;
+       if (!(b & 0x02))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op2F(void)                                                 // BBR2
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x04))
-               regs->pc += m;
+       if (!(b & 0x04))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op3F(void)                                                 // BBR3
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x08))
-               regs->pc += m;
+       if (!(b & 0x08))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op4F(void)                                                 // BBR4
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x10))
-               regs->pc += m;
+       if (!(b & 0x10))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op5F(void)                                                 // BBR5
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x20))
-               regs->pc += m;
+       if (!(b & 0x20))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op6F(void)                                                 // BBR6
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x40))
-               regs->pc += m;
+       if (!(b & 0x40))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op7F(void)                                                 // BBR7
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (!(regs->a & 0x80))
-               regs->pc += m;
+       if (!(b & 0x80))
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op8F(void)                                                 // BBS0
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x01)
-               regs->pc += m;
+       if (b & 0x01)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void Op9F(void)                                                 // BBS1
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x02)
-               regs->pc += m;
+       if (b & 0x02)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void OpAF(void)                                                 // BBS2
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x04)
-               regs->pc += m;
+       if (b & 0x04)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void OpBF(void)                                                 // BBS3
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x08)
-               regs->pc += m;
+       if (b & 0x08)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void OpCF(void)                                                 // BBS4
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x10)
-               regs->pc += m;
+       if (b & 0x10)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void OpDF(void)                                                 // BBS5
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x20)
-               regs->pc += m;
+       if (b & 0x20)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void OpEF(void)                                                 // BBS6
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x40)
-               regs->pc += m;
+       if (b & 0x40)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 static void OpFF(void)                                                 // BBS7
 {
+       uint8_t b = READ_ZP;
        int16_t m = (int16_t)(int8_t)READ_IMM;
 
-       if (regs->a & 0x80)
-               regs->pc += m;
+       if (b & 0x80)
+               HANDLE_BRANCH_TAKEN(m);
 }
 
 /*
@@ -1086,18 +592,6 @@ BCS       Relative        BCS Oper        B0      2       2
 BEQ    Relative        BEQ Oper        F0      2       2
 */
 
-// Branch taken adds a cycle, crossing page adds one more
-
-#define HANDLE_BRANCH_TAKEN(m)      \
-{                                   \
-       uint16_t oldpc = regs->pc;       \
-       regs->pc += m;                   \
-       regs->clock++;                   \
-\
-       if ((oldpc ^ regs->pc) & 0xFF00) \
-               regs->clock++;               \
-}
-
 // Branch opcodes
 
 static void Op90(void)                                                 // BCC
@@ -1172,6 +666,7 @@ static void Op2C(void)                                                     // BIT ABS
 
 static void Op3C(void)                                                 // BIT ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_BIT_HANDLER(m);
 }
@@ -1344,12 +839,14 @@ static void OpCD(void)                                                   // CMP ABS
 
 static void OpDD(void)                                                 // CMP ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_CMP_HANDLER(m);
 }
 
 static void OpD9(void)                                                 // CMP ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint8_t m = READ_ABS_Y;
        OP_CMP_HANDLER(m);
 }
@@ -1362,6 +859,7 @@ static void OpC1(void)                                                     // CMP (ZP, X)
 
 static void OpD1(void)                                                 // CMP (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint8_t m = READ_IND_ZP_Y;
        OP_CMP_HANDLER(m);
 }
@@ -1481,6 +979,7 @@ static void OpCE(void)                                                     // DEC ABS
 
 static void OpDE(void)                                                 // DEC ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m;
        READ_ABS_X_WB(m);
        OP_DEC_HANDLER(m);
@@ -1551,12 +1050,14 @@ static void Op4D(void)                                                  // EOR ABS
 
 static void Op5D(void)                                                 // EOR ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_EOR_HANDLER(m);
 }
 
 static void Op59(void)                                                 // EOR ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint8_t m = READ_ABS_Y;
        OP_EOR_HANDLER(m);
 }
@@ -1569,6 +1070,7 @@ static void Op41(void)                                                    // EOR (ZP, X)
 
 static void Op51(void)                                                 // EOR (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint8_t m = READ_IND_ZP_Y;
        OP_EOR_HANDLER(m);
 }
@@ -1628,6 +1130,7 @@ static void OpEE(void)                                                    // INC ABS
 
 static void OpFE(void)                                                 // INC ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m;
        READ_ABS_X_WB(m);
        OP_INC_HANDLER(m);
@@ -1669,6 +1172,12 @@ static void Op4C(void)                                                   // JMP ABS
 
 static void Op6C(void)                                                 // JMP (ABS)
 {
+       // Check for page crossing
+       uint16_t addressLo = regs->RdMem(regs->pc);
+
+       if (addressLo == 0xFF)
+               regs->clock++;
+
        regs->pc = RdMemW(RdMemW(regs->pc));
 }
 
@@ -1734,12 +1243,14 @@ static void OpAD(void)                                                  // LDA ABS
 
 static void OpBD(void)                                                 // LDA ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_LDA_HANDLER(m);
 }
 
 static void OpB9(void)                                                 // LDA ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint8_t m = READ_ABS_Y;
        OP_LDA_HANDLER(m);
 }
@@ -1752,6 +1263,7 @@ static void OpA1(void)                                                    // LDA (ZP, X)
 
 static void OpB1(void)                                                 // LDA (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint8_t m = READ_IND_ZP_Y;
        OP_LDA_HANDLER(m);
 }
@@ -1802,6 +1314,7 @@ static void OpAE(void)                                                    // LDX ABS
 
 static void OpBE(void)                                                 // LDX ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint8_t m = READ_ABS_Y;
        OP_LDX_HANDLER(m);
 }
@@ -1809,9 +1322,9 @@ static void OpBE(void)                                                    // LDX ABS, Y
 /*
 LDY    Immediate       LDY #Oper       A0      2       2
 Zero Page              LDY Zpg         A4      2       3
-Zero Page,Y            LDY Zpg,X       B4      2       4
+Zero Page,X            LDY Zpg,X       B4      2       4
 Absolute               LDY Abs         AC      3       4
-Absolute,Y             LDY Abs,X       BC      3       4
+Absolute,X             LDY Abs,X       BC      3       4
 */
 
 // LDY opcodes
@@ -1846,6 +1359,7 @@ static void OpAC(void)                                                    // LDY ABS
 
 static void OpBC(void)                                                 // LDY ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_LDY_HANDLER(m);
 }
@@ -1896,6 +1410,7 @@ static void Op4E(void)                                                    // LSR ABS
 
 static void Op5E(void)                                                 // LSR ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m;
        READ_ABS_X_WB(m);
        OP_LSR_HANDLER(m);
@@ -1954,12 +1469,14 @@ static void Op0D(void)                                                  // ORA ABS
 
 static void Op1D(void)                                                 // ORA ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m = READ_ABS_X;
        OP_ORA_HANDLER(m);
 }
 
 static void Op19(void)                                                 // ORA ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint8_t m = READ_ABS_Y;
        OP_ORA_HANDLER(m);
 }
@@ -1972,6 +1489,7 @@ static void Op01(void)                                                    // ORA (ZP, X)
 
 static void Op11(void)                                                 // ORA (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint8_t m = READ_IND_ZP_Y;
        OP_ORA_HANDLER(m);
 }
@@ -2171,6 +1689,7 @@ static void Op2E(void)                                                    // ROL ABS
 
 static void Op3E(void)                                                 // ROL ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m;
        READ_ABS_X_WB(m);
        OP_ROL_HANDLER(m);
@@ -2224,6 +1743,7 @@ static void Op6E(void)                                                    // ROR ABS
 
 static void Op7E(void)                                                 // ROR ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint8_t m;
        READ_ABS_X_WB(m);
        OP_ROR_HANDLER(m);
@@ -2267,17 +1787,27 @@ Absolute,Y              SBC Abs,Y       F9      3       4
 // SBC opcodes
 
 //This is non-optimal, but it works--optimize later. :-)
-//This is correct except for the BCD handling... !!! FIX !!! [Possibly DONE]
+// We do the BCD subtraction one nybble at a time to ensure a correct result.
+// 9 - m is a "Nine's Complement".  We do the BCD subtraction as a 9s
+// complement addition because it's easier and it works.  :-)  Also, Decimal
+// mode incurs a once cycle penalty (for the decimal correction).
 #define OP_SBC_HANDLER(m) \
        uint16_t sum = (uint16_t)regs->a - (m) - (uint16_t)((regs->cc & FLAG_C) ^ 0x01); \
 \
        if (regs->cc & FLAG_D) \
        { \
-               if ((sum & 0x0F) > 0x09) \
-                       sum -= 0x06; \
+               sum = (regs->a & 0x0F) + (9 - ((m) & 0x0F)) + (uint16_t)(regs->cc & FLAG_C); \
+\
+               if (sum > 0x09) \
+                       sum += 0x06; \
 \
-               if ((sum & 0xF0) > 0x90) \
-                       sum -= 0x60; \
+               sum += (regs->a & 0xF0) + (0x90 - ((m) & 0xF0)); \
+\
+               if (sum > 0x99) \
+                       sum += 0x60; \
+\
+               sum ^= 0x100; /* Invert carry, for active low borrow */ \
+               regs->clock++;\
        } \
 \
        regs->cc = (regs->cc & ~FLAG_C) | (((sum >> 8) ^ 0x01) & FLAG_C); \
@@ -2311,12 +1841,14 @@ static void OpED(void)                                                  // SBC ABS
 
 static void OpFD(void)                                                 // SBC ABS, X
 {
+       HANDLE_PAGE_CROSSING_ABS_X;
        uint16_t m = READ_ABS_X;
        OP_SBC_HANDLER(m);
 }
 
 static void OpF9(void)                                                 // SBC ABS, Y
 {
+       HANDLE_PAGE_CROSSING_ABS_Y;
        uint16_t m = READ_ABS_Y;
        OP_SBC_HANDLER(m);
 }
@@ -2329,6 +1861,7 @@ static void OpE1(void)                                                    // SBC (ZP, X)
 
 static void OpF1(void)                                                 // SBC (ZP), Y
 {
+       HANDLE_PAGE_CROSSING_IND_Y;
        uint16_t m = READ_IND_ZP_Y;
        OP_SBC_HANDLER(m);
 }
@@ -2764,6 +2297,196 @@ void Execute65C02(V65C02REGS * context, uint32_t cycles)
        while (regs->clock < endCycles)
        {
 #if 0
+//Epoch
+if (regs->pc == 0x0518)
+{
+       dumpDis = true;
+}
+else if (regs->pc == 0x051E)
+{
+       uint16_t c1 = regs->RdMem(0xFF);
+       uint16_t c2 = regs->RdMem(0x00);
+       WriteLog("$FF/$00 = $%02X $%02X\n", c1, c2);
+       WriteLog("--> $%02X\n", regs->RdMem((c2 << 8) | c1));
+}
+else if (regs->pc == 0x0522)
+{
+       uint16_t c1 = regs->RdMem(0xFF);
+       uint16_t c2 = regs->RdMem(0x00);
+       WriteLog("$FF/$00 = $%02X $%02X\n", c1, c2);
+       WriteLog("--> $%02X\n", regs->RdMem(((c2 << 8) | c1) + 1));
+}
+#endif
+#if 0
+// Up N Down testing
+// Now Ankh testing...
+static bool inDelay = false;
+static bool inBell = false;
+static bool inReadSector = false;
+if (regs->pc == 0xFCA8 && !inBell && !inReadSector)
+{
+       dumpDis = false;
+       inDelay = true;
+       WriteLog("*** DELAY\n");
+}
+else if (regs->pc == 0xFCB3 && inDelay && !inBell && !inReadSector)
+{
+       dumpDis = true;
+       inDelay = false;
+}
+if (regs->pc == 0xFBD9)
+{
+       dumpDis = false;
+       inBell = true;
+       WriteLog("*** BELL1\n");
+}
+else if (regs->pc == 0xFBEF && inBell)
+{
+       dumpDis = true;
+       inBell = false;
+}
+else if (regs->pc == 0xC600)
+{
+       dumpDis = false;
+       WriteLog("*** DISK @ $C600\n");
+}
+else if (regs->pc == 0x801)
+{
+       WriteLog("*** DISK @ $801\n");
+       dumpDis = true;
+}
+else if (regs->pc == 0xC119)
+{
+       dumpDis = false;
+       WriteLog("*** BIOS @ $C119\n");
+}
+else if (regs->pc == 0xC117)
+{
+       dumpDis = true;
+}
+else if (regs->pc == 0x843)
+{
+       dumpDis = false;
+       inReadSector = true;
+       uint16_t lo = regs->RdMem(0x26);
+       uint16_t hi = regs->RdMem(0x27);
+       WriteLog("\n*** DISK Read sector ($26=$%04X)...\n\n", (hi << 8) | lo);
+}
+else if (regs->pc == 0x8FC)
+{
+       dumpDis = true;
+       inReadSector = false;
+}
+else if (regs->pc == 0xA8A8 || regs->pc == 0xC100)
+{
+       dumpDis = false;
+}
+else if (regs->pc == 0x8FD)
+{
+//     regs->WrMem(0x827, 3);
+//     regs->WrMem(0x82A, 0);
+//1 doesn't work, but 2 does (only with WOZ, not with DSK; DSK needs 4)...
+//     regs->WrMem(0x0D, 4);
+}
+
+#endif
+#if 0
+static bool inDelay = false;
+static bool inMLI = false;
+static uint16_t mliReturnAddr = 0;
+static uint8_t mliCmd = 0;
+if (regs->pc == 0x160B && dumpDis)
+{
+       inDelay = true;
+       dumpDis = false;
+       WriteLog("*** DELAY\n");
+}
+else if (regs->pc == 0x1616 && inDelay)
+{
+       inDelay = false;
+       dumpDis = true;
+}
+else if (regs->pc == 0xD385 && dumpDis)
+{
+       inDelay = true;
+       dumpDis = false;
+       WriteLog("*** DELAY\n");
+}
+else if (regs->pc == 0xD397 && inDelay)
+{
+       inDelay = false;
+       dumpDis = true;
+}
+else if (regs->pc == 0xBF00 && dumpDis)
+{
+       uint16_t lo = regs->RdMem(regs->sp + 0x101);
+       uint16_t hi = regs->RdMem(regs->sp + 0x102);
+       mliReturnAddr = ((hi << 8) | lo) + 1;
+       mliCmd = regs->RdMem(mliReturnAddr);
+       WriteLog("*** Calling ProDOS MLI with params: %02X %04X\n", mliCmd, RdMemW(mliReturnAddr + 1));
+       mliReturnAddr += 3;
+       inMLI = true;
+
+       // We want to see what's going on in the WRITE BLOCK command... :-P
+//     if (mliCmd != 0x81)
+//             dumpDis = false;
+}
+else if (regs->pc == mliReturnAddr && inMLI)
+{
+//extern bool stopWriting;
+//Stop writing to disk after the first block is done
+//     if (mliCmd == 0x81)
+//             stopWriting = true;
+
+       inMLI = false;
+       dumpDis = true;
+}
+else if (regs->pc == 0xAB3A && dumpDis && !inDelay)
+{
+       dumpDis = false;
+       inDelay = true;
+       WriteLog("\n*** DELAY (A=$%02X)\n\n", regs->a);
+}
+else if (regs->pc == 0xAB4A && inDelay)
+{
+       dumpDis = true;
+       inDelay = false;
+}
+
+if (regs->pc == 0xA80B)
+       dumpDis = true;
+
+#endif
+#if 0
+static bool weGo = false;
+static bool inDelay = false;
+if (regs->pc == 0x92BA)
+{
+       dumpDis = true;
+       weGo = true;
+}
+else if (regs->pc == 0xAB3A && weGo && !inDelay)
+{
+       dumpDis = false;
+       inDelay = true;
+       WriteLog("\n*** DELAY (A=$%02X)\n\n", regs->a);
+}
+else if (regs->pc == 0xAB4A && weGo)
+{
+       dumpDis = true;
+       inDelay = false;
+}
+else if (regs->pc == 0xA8B5 && weGo)
+{
+       WriteLog("\n$D4=%02X, $AC1F=%02X, $AC20=%02X\n\n", regs->RdMem(0xD4), regs->RdMem(0xAC1F), regs->RdMem(0xAC20));
+}
+/*else if (regs->pc == 0xA8C4 && weGo)
+{
+       WriteLog("Cheating... (clearing Carry flag)\n");
+       regs->cc &= ~FLAG_C;
+}*/
+#endif
+#if 0
 static bool weGo = false;
 if (regs->pc == 0x80AE)
 {
@@ -2892,6 +2615,15 @@ if (regs->pc == 0x2000)
        dumpDis = true;
 #endif
 
+#ifdef __DEBUG__
+#ifdef DO_BACKTRACE
+//uint32_t btQueuePtr = 0;
+//V65C02REGS btQueue[BACKTRACE_SIZE];
+//uint8_t btQueueInst[BACKTRACE_SIZE][4];
+memcpy(&btQueue[btQueuePtr], regs, sizeof(V65C02REGS));
+btQueuePtr = (btQueuePtr + 1) % BACKTRACE_SIZE;
+#endif
+#endif
 #ifdef __DEBUG__
 static char disbuf[80];
 if (dumpDis)
@@ -2902,6 +2634,19 @@ if (dumpDis)
 #endif
                uint8_t opcode = regs->RdMem(regs->pc++);
 
+#if 0
+if (opcode == 0)
+{
+       static char disbuf[80];
+       uint32_t btStart = btQueuePtr - 12 + (btQueuePtr < 12 ? BACKTRACE_SIZE : 0);
+
+       for(uint32_t i=btStart; i<btQueuePtr; i++)
+       {
+               Decode65C02(regs, disbuf, btQueue[i].pc);
+               WriteLog("%s\n", disbuf);
+       }
+}
+#endif
 //if (!(regs->cpuFlags & V65C02_STATE_ILLEGAL_INST))
 //instCount[opcode]++;
 
@@ -2919,12 +2664,12 @@ if (dumpDis)
 
 #ifdef __DEBUG__
 if (dumpDis)
-       WriteLog(" [SP=01%02X, CC=%s%s.%s%s%s%s%s, A=%02X, X=%02X, Y=%02X]\n",
+       WriteLog(" [SP=01%02X, CC=%s%s.%s%s%s%s%s, A=%02X, X=%02X, Y=%02X](%d)\n",
                regs->sp,
                (regs->cc & FLAG_N ? "N" : "-"), (regs->cc & FLAG_V ? "V" : "-"),
                (regs->cc & FLAG_B ? "B" : "-"), (regs->cc & FLAG_D ? "D" : "-"),
                (regs->cc & FLAG_I ? "I" : "-"), (regs->cc & FLAG_Z ? "Z" : "-"),
-               (regs->cc & FLAG_C ? "C" : "-"), regs->a, regs->x, regs->y);
+               (regs->cc & FLAG_C ? "C" : "-"), regs->a, regs->x, regs->y, regs->clock - clockSave);
 #endif
 
 #ifdef __DEBUGMON__
diff --git a/src/vay8910.cpp b/src/vay8910.cpp
new file mode 100644 (file)
index 0000000..e0fcc11
--- /dev/null
@@ -0,0 +1,360 @@
+//
+// Virtual AY-3-8910 Emulator
+//
+// by James Hammons
+// (C) 2018 Underground Software
+//
+// This was written mainly from the General Instruments datasheet for the 8910
+// part.  I would have used the one from MAME, but it was so poorly written and
+// so utterly incomprehensible that I decided to start from scratch to see if I
+// could do any better; and so here we are.  I *did* use a bit of code from
+// MAME's AY-3-8910 RNG, as it was just too neat not to use.  :-)
+//
+
+#include "vay8910.h"
+
+#include <string.h>                    // for memset()
+#include "log.h"
+#include "sound.h"
+
+
+// AY-3-8910 register IDs
+enum { AY_AFINE = 0, AY_ACOARSE, AY_BFINE, AY_BCOARSE, AY_CFINE, AY_CCOARSE,
+       AY_NOISEPER, AY_ENABLE, AY_AVOL, AY_BVOL, AY_CVOL, AY_EFINE, AY_ECOARSE,
+       AY_ESHAPE, AY_PORTA, AY_PORTB };
+
+// Class variable instantiation/initialization
+float VAY_3_8910::maxVolume = 8192.0f;
+float VAY_3_8910::normalizedVolume[16];// = {};
+
+
+VAY_3_8910::VAY_3_8910()
+{
+       // Our normalized volume levels are from 0 to -48 dB, in 3 dB steps.
+       // N.B.: It's 3dB steps because those sound the best.  Dunno what it really
+       //       is, as nothing in the documentation tells you (it only says that
+       //       each channel's volume is normalized from 0 to 1.0V).
+       float level = 1.0f;
+
+       for(int i=15; i>=0; i--)
+       {
+               normalizedVolume[i] = level;
+               level /= 1.4125375446228;       // 10.0 ^ (3.0 / 20.0) = 3 dB
+       }
+
+       // In order to get a scale that goes from 0 to 1 smoothly, we renormalize
+       // our volumes so that volume[0] is actually 0, and volume[15] is 1.
+       // Basically, we're sliding the curve down the Y-axis so that volume[0]
+       // touches the X-axis, then stretching the result so that it fits into the
+       // interval (0, 1).
+       float vol0 = normalizedVolume[0];
+       float vol15 = normalizedVolume[15] - vol0;
+
+       for(int i=0; i<16; i++)
+               normalizedVolume[i] = (normalizedVolume[i] - vol0) / vol15;
+
+#if 0
+       WriteLog("\nRenormalized volume, level (max=%d):\n", (int)maxVolume);
+       for(int i=0; i<16; i++)
+               WriteLog("%lf, %d\n", normalizedVolume[i], (int)(normalizedVolume[i] * maxVolume));
+       WriteLog("\n");
+#endif
+}
+
+
+void VAY_3_8910::Reset(void)
+{
+       memset(this, 0, sizeof(struct VAY_3_8910));
+       prng = 1;       // Set correct PRNG seed
+}
+
+
+void VAY_3_8910::WriteControl(uint8_t value)
+{
+       if ((value & 0x04) == 0)
+               Reset();
+       else if ((value & 0x03) == 0x03)
+               regLatch = data;
+       else if ((value & 0x03) == 0x02)
+               SetRegister();
+}
+
+
+void VAY_3_8910::WriteData(uint8_t value)
+{
+       data = value;
+}
+
+
+void VAY_3_8910::SetRegister(void)
+{
+#if 0
+static char regname[16][32] = {
+       "AY_AFINE   ",
+       "AY_ACOARSE ",
+       "AY_BFINE   ",
+       "AY_BCOARSE ",
+       "AY_CFINE   ",
+       "AY_CCOARSE ",
+       "AY_NOISEPER",
+       "AY_ENABLE  ",
+       "AY_AVOL    ",
+       "AY_BVOL    ",
+       "AY_CVOL    ",
+       "AY_EFINE   ",
+       "AY_ECOARSE ",
+       "AY_ESHAPE  ",
+       "AY_PORTA   ",
+       "AY_PORTB   "
+};
+WriteLog("*** AY(%d) Reg: %s = $%02X\n", chipNum, regname[reg], value);
+#endif
+       uint16_t value = (uint16_t)data;
+
+       switch (regLatch)
+       {
+       case AY_AFINE:
+               // The square wave period is the passed in value times 16, so we handle
+               // that here.
+               period[0] = (period[0] & 0xF000) | (value << 4);
+               break;
+       case AY_ACOARSE:
+               period[0] = ((value & 0x0F) << 12) | (period[0] & 0xFF0);
+               break;
+       case AY_BFINE:
+               period[1] = (period[1] & 0xF000) | (value << 4);
+               break;
+       case AY_BCOARSE:
+               period[1] = ((value & 0x0F) << 12) | (period[1] & 0xFF0);
+               break;
+       case AY_CFINE:
+               period[2] = (period[2] & 0xF000) | (value << 4);
+               break;
+       case AY_CCOARSE:
+               period[2] = ((value & 0x0F) << 12) | (period[2] & 0xFF0);
+               break;
+       case AY_NOISEPER:
+               // Like the square wave period, the value is the what's passed * 16.
+               noisePeriod = (value & 0x1F) << 4;
+               break;
+       case AY_ENABLE:
+               toneEnable[0] = (value & 0x01 ? false : true);
+               toneEnable[1] = (value & 0x02 ? false : true);
+               toneEnable[2] = (value & 0x04 ? false : true);
+               noiseEnable[0] = (value & 0x08 ? false : true);
+               noiseEnable[1] = (value & 0x10 ? false : true);
+               noiseEnable[2] = (value & 0x20 ? false : true);
+               break;
+       case AY_AVOL:
+               volume[0]    = value & 0x0F;
+               envEnable[0] = (value & 0x10 ? true : false);
+
+               if (envEnable[0])
+               {
+                       envCount[0]     = 0;
+                       volume[0]       = (envAttack ? 0 : 15);
+                       envDirection[0] = (envAttack ? 1 : -1);
+               }
+               break;
+       case AY_BVOL:
+               volume[1]    = value & 0x0F;
+               envEnable[1] = (value & 0x10 ? true : false);
+
+               if (envEnable[1])
+               {
+                       envCount[1]     = 0;
+                       volume[1]       = (envAttack ? 0 : 15);
+                       envDirection[1] = (envAttack ? 1 : -1);
+               }
+               break;
+       case AY_CVOL:
+               volume[2]    = value & 0x0F;
+               envEnable[2] = (value & 0x10 ? true : false);
+
+               if (envEnable[2])
+               {
+                       envCount[2]     = 0;
+                       volume[2]       = (envAttack ? 0 : 15);
+                       envDirection[2] = (envAttack ? 1 : -1);
+               }
+               break;
+       case AY_EFINE:
+               // The envelope period is 256 times the passed in value
+               envPeriod = (envPeriod & 0xFF0000) | (value << 8);
+               break;
+       case AY_ECOARSE:
+               envPeriod = (value << 16) | (envPeriod & 0xFF00);
+               break;
+       case AY_ESHAPE:
+               envAttack    = (value & 0x04 ? true : false);
+               envAlternate = (value & 0x02 ? true : false);
+               envHold      = (value & 0x01 ? true : false);
+
+               // If the Continue bit is *not* set, the Alternate bit is forced to the
+               // Attack bit, and Hold is forced on.
+               if (!(value & 0x08))
+               {
+                       envAlternate = envAttack;
+                       envHold = true;
+               }
+
+               // Reset all voice envelope counts...
+               for(int i=0; i<3; i++)
+               {
+                       envCount[i]     = 0;
+                       envDirection[i] = (envAttack ? 1 : -1);
+
+                       // Only reset the volume if the envelope is enabled!
+                       if (envEnable[i])
+                               volume[i] = (envAttack ? 0 : 15);
+               }
+               break;
+       }
+}
+
+
+//
+// Generate one sample and quit
+//
+bool logAYInternal = false;
+uint16_t VAY_3_8910::GetSample(void)
+{
+       uint16_t sample = 0;
+
+       // Number of cycles per second to run the PSG is the 6502 clock rate
+       // divided by the host sample rate
+       const static double exactCycles = 1020484.32 / (double)SAMPLE_RATE;
+       static double overflow = 0;
+
+       int fullCycles = (int)exactCycles;
+       overflow += exactCycles - (double)fullCycles;
+
+       if (overflow >= 1.0)
+       {
+               fullCycles++;
+               overflow -= 1.0;
+       }
+
+       for(int i=0; i<fullCycles; i++)
+       {
+               for(int j=0; j<3; j++)
+               {
+                       // Tone generators only run if the corresponding voice is enabled.
+                       // N.B.: We also reject any period set that is less than 2.
+                       if (toneEnable[j] && (period[j] > 16))
+                       {
+                               count[j]++;
+
+                               // It's (period / 2) because one full period of a square wave
+                               // is zero for half of its period and one for the other half!
+                               if (count[j] > (period[j] / 2))
+                               {
+                                       count[j] = 0;
+                                       state[j] = !state[j];
+                               }
+                       }
+
+                       // Envelope generator only runs if the corresponding voice flag is
+                       // enabled.
+                       if (envEnable[j])
+                       {
+                               envCount[j]++;
+
+                               // It's (EP / 16) because there are 16 volume steps in each EP.
+                               if (envCount[j] > (envPeriod / 16))
+                               {
+                                       // Attack 0 = \, 1 = / (attack lasts one EP)
+                                       // Alternate = mirror envelope's last attack
+                                       // Hold = run 1 EP, hold at level (Alternate XOR Attack)
+                                       envCount[j] = 0;
+
+                                       // We've hit a point where we need to make a change to the
+                                       // envelope's volume, so do it:
+                                       volume[j] += envDirection[j];
+
+                                       // If we hit the end of the EP, change the state of the
+                                       // envelope according to the envelope's variables.
+                                       if ((volume[j] > 15) || (volume[j] < 0))
+                                       {
+                                               // Hold means we set the volume to (Alternate XOR
+                                               // Attack) and stay there after the Attack EP.
+                                               if (envHold)
+                                               {
+                                                       volume[j] = (envAttack != envAlternate ? 15: 0);
+                                                       envDirection[j] = 0;
+                                               }
+                                               else
+                                               {
+                                                       // If the Alternate bit is set, we mirror the
+                                                       // Attack pattern; otherwise we reset it to the
+                                                       // whatever level was set by the Attack bit.
+                                                       if (envAlternate)
+                                                       {
+                                                               envDirection[j] = -envDirection[j];
+                                                               volume[j] += envDirection[j];
+                                                       }
+                                                       else
+                                                               volume[j] = (envAttack ? 0 : 15);
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Noise generator (the PRNG) runs all the time:
+               noiseCount++;
+
+               if (noiseCount > noisePeriod)
+               {
+                       noiseCount = 0;
+
+                       // The following is from MAME's AY-3-8910 code:
+                       // The Pseudo Random Number Generator of the 8910 is a 17-bit shift
+                       // register. The input to the shift register is bit0 XOR bit3 (bit0
+                       // is the output). This was verified on AY-3-8910 and YM2149 chips.
+
+                       // The following is a fast way to compute bit17 = bit0 ^ bit3.
+                       // Instead of doing all the logic operations, we only check bit0,
+                       // relying on the fact that after three shifts of the register,
+                       // what now is bit3 will become bit0, and will invert, if
+                       // necessary, bit14, which previously was bit17.
+                       if (prng & 0x00001)
+                       {
+                               // This version is called the "Galois configuration".
+                               prng ^= 0x24000;
+                               // The noise wave *toggles* when a one shows up in bit0...
+                               noiseState = !noiseState;
+                       }
+
+                       prng >>= 1;
+               }
+       }
+
+       // We mix channels A-C here into one sample, because the Mockingboard just
+       // sums the output of the AY-3-8910 by tying their lines together.
+       // We also handle the various cases (of which there are four) of mixing
+       // pure tones and "noise" tones together.
+       for(int i=0; i<3; i++)
+       {
+               // Set the volume level scaled by the maximum volume (which can be
+               // altered outside of this module).
+               int level = (int)(normalizedVolume[volume[i]] * maxVolume);
+
+               if (toneEnable[i] && !noiseEnable[i])
+                       sample += (state[i] ? level : 0);
+               else if (!toneEnable[i] && noiseEnable[i])
+                       sample += (noiseState ? level : 0);
+               else if (toneEnable[i] && noiseEnable[i])
+                       sample += (state[i] & noiseState ? level : 0);
+               else if (!toneEnable[i] && !noiseEnable[i])
+                       sample += level;
+       }
+
+       if (logAYInternal)
+       {
+               WriteLog("    (%d) State A,B,C: %s %s %s, Sample: $%04X, P: $%X, $%X, $%X\n", id, (state[0] ? "1" : "0"), (state[1] ? "1" : "0"), (state[2] ? "1" : "0"), sample, period[0], period[1], period[2]);
+       }
+
+       return sample;
+}
+
diff --git a/src/vay8910.h b/src/vay8910.h
new file mode 100644 (file)
index 0000000..4eb0fe9
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// Virtual AY-3-8910 Emulator
+//
+// by James Hammons
+// (C) 2018 Underground Software
+//
+
+#ifndef VAY8910_H
+#define VAY8910_H
+
+#include <stdint.h>
+
+struct VAY_3_8910
+{
+       // User visible registers
+       uint16_t period[3];             // Channel A-C period
+       int16_t volume[3];              // Channel A-C volume (non-envelope mode)
+       bool envEnable[3];              // Channel A-C envelope enable
+       bool toneEnable[3];             // Channel A-C tone enable
+       bool noiseEnable[3];    // Channel A-C noise enable
+       uint16_t noisePeriod;   // Noise period (5 bits * 16)
+       uint32_t envPeriod;             // Envelope period (16 bits * 256)
+       bool envAttack;                 // Envelope Attack bit
+       bool envAlternate;              // Envelope Alternate bit
+       bool envHold;                   // Envelope Hold bit
+       // Internal registers
+       uint16_t count[3];              // Channel A-C current count
+       bool state[3];                  // Channel A-C current state
+       uint16_t noiseCount;    // Noise current count
+       bool noiseState;                // Noise state
+       uint32_t envCount[3];   // Envelope current count
+       int16_t envDirection[3];// Envelope direction (rising, 0, or falling)
+       uint32_t prng;                  // Psuedo RNG (17 bits)
+       uint8_t regLatch;               // Register latch (written by 6522VIA)
+       uint8_t data;                   // Data lines (written by 6522VIA)
+       uint8_t id;                             // Chip ID (optional)
+
+       VAY_3_8910();
+       void Reset(void);
+       void WriteControl(uint8_t);
+       void WriteData(uint8_t);
+       void SetRegister(void);
+       uint16_t GetSample(void);
+
+       // Class variables
+
+       // Maximum volume that can be generated by one voice
+       static float maxVolume;
+       // Normalized volumes (zero to one) for AY-3-8910 output, in 16 steps
+       static float normalizedVolume[16];
+};
+
+// Exported variables
+extern bool logAYInternal;
+
+#endif // VAY8910_H
+
index 5bc12e0b6bcaf3107d5662646cd4abaf710df1b9..e027dfa1485d0fb964114d45a5f23e07524270cb 100644 (file)
@@ -251,6 +251,7 @@ static void Render80ColumnTextLine(uint8_t line);
 static void Render40ColumnText(void);
 static void Render80ColumnText(void);
 static void RenderLoRes(uint16_t toLine = 24);
+static void RenderDLoRes(uint16_t toLine = 24);
 static void RenderHiRes(uint16_t toLine = 192);
 static void RenderDHiRes(uint16_t toLine = 192);
 static void RenderVideoFrame(/*uint32_t *, int*/);
@@ -342,6 +343,7 @@ void SpawnMessage(const char * text, ...)
        va_end(arg);
 
        msgTicks = 120;
+//WriteLog("\n%s\n", message);
 }
 
 
@@ -493,19 +495,24 @@ static void Render40ColumnTextLine(uint8_t line)
 
                                if (alternateCharset)
                                {
-                                       if (textChar[((chr & 0x3F) * 56) + cx + (cy * 7)])
+                                       if (textChar2e[(chr * 56) + cx + (cy * 7)])
                                                pixel = pixelOn;
-
-                                       if (chr < 0x80)
-                                               pixel = pixel ^ (screenType == ST_GREEN_MONO ? 0x0061FF61 : 0x00FFFFFF);
-
-                                       if ((chr & 0xC0) == 0x40 && flash)
-                                               pixel = 0xFF000000;
                                }
                                else
                                {
-                                       if (textChar2e[(chr * 56) + cx + (cy * 7)])
-                                               pixel = pixelOn;
+                                       if ((chr & 0xC0) == 0x40)
+                                       {
+                                               if (textChar2e[((chr & 0x3F) * 56) + cx + (cy * 7)])
+                                                       pixel = pixelOn;
+
+                                               if (flash)
+                                                       pixel = pixel ^ (screenType == ST_GREEN_MONO ? 0x0061FF61 : 0x00FFFFFF);
+                                       }
+                                       else
+                                       {
+                                               if (textChar2e[(chr * 56) + cx + (cy * 7)])
+                                                       pixel = pixelOn;
+                                       }
                                }
 
                                scrBuffer[(x * 7 * 2) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + (cx * 2) + 0 + (cy * VIRTUAL_SCREEN_WIDTH * 2)] = pixel;
@@ -548,19 +555,24 @@ static void Render80ColumnTextLine(uint8_t line)
 
                                if (alternateCharset)
                                {
-                                       if (textChar[((chr & 0x3F) * 56) + cx + (cy * 7)])
+                                       if (textChar2e[(chr * 56) + cx + (cy * 7)])
                                                pixel = pixelOn;
-
-                                       if (chr < 0x80)
-                                               pixel = pixel ^ (screenType == ST_GREEN_MONO ? 0x0061FF61 : 0x00FFFFFF);
-
-                                       if ((chr & 0xC0) == 0x40 && flash)
-                                               pixel = 0xFF000000;
                                }
                                else
                                {
-                                       if (textChar2e[(chr * 56) + cx + (cy * 7)])
-                                               pixel = pixelOn;
+                                       if ((chr & 0xC0) == 0x40)
+                                       {
+                                               if (textChar2e[((chr & 0x3F) * 56) + cx + (cy * 7)])
+                                                       pixel = pixelOn;
+
+                                               if (flash)
+                                                       pixel = pixel ^ (screenType == ST_GREEN_MONO ? 0x0061FF61 : 0x00FFFFFF);
+                                       }
+                                       else
+                                       {
+                                               if (textChar2e[(chr * 56) + cx + (cy * 7)])
+                                                       pixel = pixelOn;
+                                       }
                                }
 
                                scrBuffer[(x * 7) + (line * VIRTUAL_SCREEN_WIDTH * 8 * 2) + cx + (cy * 2 * VIRTUAL_SCREEN_WIDTH)] = pixel;
@@ -764,7 +776,7 @@ fb fb fb -> 15 [1111] -> 15         WHITE
 //
 // Render the Double Lo Res screen (HIRES off, DHIRES on)
 //
-static void RenderDLoRes(void)
+static void RenderDLoRes(uint16_t toLine/*= 24*/)
 {
 // NOTE: The green mono rendering doesn't skip every other line... !!! FIX !!!
 //       Also, we could set up three different Render functions depending on
@@ -799,7 +811,7 @@ FB FB FB -> 15 [1111] -> 15         WHITE
        uint8_t mirrorNybble2[16] = { 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15 };
        uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61);
 
-       for(uint16_t y=0; y<24; y++)
+       for(uint16_t y=0; y<toLine; y++)
        {
                // Do top half of double lores screen bytes...
 
@@ -1084,22 +1096,22 @@ void RenderVideoFrame(void)
                {
                        if (mixedMode)
                        {
-                               if (hiRes)
+                               if (dhires)
                                {
-                                       RenderHiRes(160);
-                                       Render40ColumnTextLine(20);
-                                       Render40ColumnTextLine(21);
-                                       Render40ColumnTextLine(22);
-                                       Render40ColumnTextLine(23);
+                                       if (hiRes)
+                                               RenderDHiRes(160);
+                                       else
+                                               RenderDLoRes(20);
                                }
+                               else if (hiRes)
+                                       RenderHiRes(160);
                                else
-                               {
                                        RenderLoRes(20);
-                                       Render40ColumnTextLine(20);
-                                       Render40ColumnTextLine(21);
-                                       Render40ColumnTextLine(22);
-                                       Render40ColumnTextLine(23);
-                               }
+
+                               Render40ColumnTextLine(20);
+                               Render40ColumnTextLine(21);
+                               Render40ColumnTextLine(22);
+                               Render40ColumnTextLine(23);
                        }
                        else
                        {
index e858b099bab64d7797b86723f07d69b9c1c28e45..99c736259f94fc005c77a71c484c5e4ff30a8c3c 100644 (file)
@@ -9,11 +9,63 @@ body, table
        color: #FFFFFF;
        text-align: center;     /* Crappy IE kludge */
        font: 14.0pt Arial, Verdana, sans-serif;
+       padding-left: 10%;
+       padding-right: 10%
 }
 
-#title img
+/*#title img
 {
        margin-top: 22px;
+}*/
+
+h1.title
+{
+       width: 263px;
+       height: 79px;
+       background: url("img/a2-logo.png");
+       text-indent: -9999px;
+       display: block;
+       margin: 0 auto;
+       margin-top: 45px;
+}
+
+img.flt-l
+{
+       float: left;
+       margin-right: 8px;
+}
+
+img.flt-r
+{
+       float: right;
+       margin-left: 8px;
+}
+
+figure.flt-r
+{
+       float: right;
+       margin-top: 0;
+       margin-left: 8px;
+       margin-right: 0;
+       font-style: italic;
+       font-size: 90%;
+}
+
+figure.small33
+{
+       width: 33%;
+}
+
+img.small50
+{
+       width: 50%;
+       height: 50%;
+}
+
+img.small33
+{
+       width: 33%;
+       height: 33%;
 }
 
 #title
@@ -70,6 +122,12 @@ p
        text-align: left;
        margin-top: 0;
        margin-bottom: 1em;
+       line-height: 140%;
+}
+
+li
+{
+       line-height: 140%;
 }
 
 /*h1
@@ -82,7 +140,7 @@ p
 h2
 {
        font-size: 200%;
-       margin-top: 1.25em;
+       margin-top: 0.75em;
        margin-bottom: 0.75em;
        color: #FFB000;
        font-style: italic;
@@ -90,9 +148,9 @@ h2
 
 h3
 {
-       font-size: 120%;
-       margin-top: 0;
-       margin-bottom: 0;
+       font-size: 140%;
+       margin-top: 1.2em;
+/*     margin-bottom: 0;*/
 }
 
 tt
@@ -108,6 +166,7 @@ p#footer
 }
 
 a:link    { color: #0090FF; text-decoration: underline; }
-a:visited { color: #6F006F; text-decoration: underline; }
+a:visited { color: #FF6F00; text-decoration: underline; }
 a:hover   { color: #20B0FF; text-decoration: none; }
 a:active  { color: #FFFFFF; text-decoration: underline; }
+
diff --git a/web/img/a2-icon-64x64.png b/web/img/a2-icon-64x64.png
new file mode 100644 (file)
index 0000000..cc7ade3
Binary files /dev/null and b/web/img/a2-icon-64x64.png differ
diff --git a/web/img/a2-logo.png b/web/img/a2-logo.png
new file mode 100644 (file)
index 0000000..208e001
Binary files /dev/null and b/web/img/a2-logo.png differ
diff --git a/web/img/ss-01.png b/web/img/ss-01.png
new file mode 100644 (file)
index 0000000..2939cd6
Binary files /dev/null and b/web/img/ss-01.png differ
diff --git a/web/img/ss-01s.png b/web/img/ss-01s.png
new file mode 100644 (file)
index 0000000..b05e38e
Binary files /dev/null and b/web/img/ss-01s.png differ
diff --git a/web/img/ss-02.png b/web/img/ss-02.png
new file mode 100644 (file)
index 0000000..006cc92
Binary files /dev/null and b/web/img/ss-02.png differ
diff --git a/web/img/ss-02s.png b/web/img/ss-02s.png
new file mode 100644 (file)
index 0000000..4078a3a
Binary files /dev/null and b/web/img/ss-02s.png differ
diff --git a/web/img/ss-03.png b/web/img/ss-03.png
new file mode 100644 (file)
index 0000000..5c18182
Binary files /dev/null and b/web/img/ss-03.png differ
diff --git a/web/img/ss-03s.png b/web/img/ss-03s.png
new file mode 100644 (file)
index 0000000..3703aef
Binary files /dev/null and b/web/img/ss-03s.png differ
diff --git a/web/img/ss-04.png b/web/img/ss-04.png
new file mode 100644 (file)
index 0000000..638832c
Binary files /dev/null and b/web/img/ss-04.png differ
diff --git a/web/img/ss-04s.png b/web/img/ss-04s.png
new file mode 100644 (file)
index 0000000..9801ac8
Binary files /dev/null and b/web/img/ss-04s.png differ
index 4fe4614bd66dc003dd2884abfce336751bbfcf76..5ebe534ce49434942b5b302b727a6128d518420e 100644 (file)
@@ -6,28 +6,87 @@
 <meta name="description" content="Apple2 homepage" />
 <meta name="keywords" content="apple, emulator, SDL, cross-platform, GPL" />
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="GENERATOR" content="Kate" />
+<meta name="generator" content="Kate" />
 
 <link rel="stylesheet" href="apple2.css" type="text/css" />
 </head>
 
 <body class="mainpage">
 
-<h1 id="title">Apple2</h1>
+<h1 class="title">Apple2</h1>
 <h2>A portable Apple //e emulator</h2>
 
 <hr>
 
-<p>This is the home of the Apple2 portable Apple //e emulator. It&rsquo;s based on GCC and SDL2, and runs on Linux, Windows, and MacOS X. It&rsquo;s powered by Virtual 65C02&trade;, and sports an easy to use yet powerful interface. The source is licensed under the GPL version 3.</p>
+<p><img class="flt-l" src="img/a2-icon-64x64.png">This is the home of the Apple2 portable Apple //e emulator.&ensp;It&rsquo;s based on GCC and SDL2, and runs on Linux, Windows, and MacOS X.&ensp;It&rsquo;s powered by Virtual 65C02&trade;, and sports an easy to use yet powerful interface.&ensp;It also has WOZ support!&ensp;The source is licensed under the GPL version 3.</p>
 
-<p>This emulator came about because of ApplePC. It was a DOS only application with a horrible interface, and you had to tune it to get it work at the correct speed for your machine. But it had absolutely the most accurate looking screen that I have even seen on an Apple emulator at that time or ever since. Current emulators <i>still</i> to this day can&rsquo;t match the fidelity of what that old DOS program could do.</p>
+<figure class="flt-r">
+<img src="img/ss-04s.png">
+<figcaption>Apple2 running &ldquo;The Bard&rsquo;s Tale&rdquo;</figcaption>
+</figure>
 
-<p>So, to make a long story even longer, ApplePC disappeared off the face of the earth and I thought it was a shame that the screen rendering of that emulator should disappear with it. Also, there are, for some reason, absolutely no Apple II emulators for Linux! A deplorable situation! And so I resolved to fix that by figuring out how ApplePC did its video tricks and by writing an emulator for Linux. At the same time, since I write pretty much all my software cross-platform, Windows and MacOS X ports come along for free!</p>
+<p>This emulator came about because of ApplePC.&ensp;It was a DOS only application with a horrible user interface (I wouldn't go so far as to call it user hostile, but it was close) that you had to tune by feeding it the correct numbers for your machine to get it to run at the correct speed.&ensp;But it had absolutely the most accurate looking screen that I have even seen on an Apple emulator at that time or ever since&mdash;current emulators <i>still</i> to this day can&rsquo;t match the fidelity of what that old DOS program could do.</p>
 
-<p>Currently, only a source code archive is available. More will be coming in the near future... You can get a copy of the source code like so:</p>
+<p>So, to make a long story even longer, ApplePC disappeared off the face of the earth and I thought it was a shame that the screen rendering of that emulator should disappear with it.&ensp;Also, there are, for some reason, absolutely no Apple II emulators for Linux!&ensp;A deplorable situation!&ensp;<i>[This was true at the time of this writing, but now there are at least two others (<b>LinApple</b> and <b>microM8</b>) out there.&ensp;&mdash;Ed.]</i>&ensp;And so I resolved to fix that by figuring out how ApplePC did its video tricks and by writing an emulator for Linux.&ensp;At the same time, since I write pretty much all my software cross-platform, Windows and MacOS X ports come along for free!</p>
+
+<p>Currently, only a source code archive is available.&ensp;More will be coming in the near future&hellip;&ensp;You can get a copy of the source code with the following incantation:</p>
 
 <p><tt>git clone http://shamusworld.gotdns.org/git/apple2</tt></p>
 
+<h3>Features</h3>
+
+<p>Apple2 emulates an enhanced Apple //e with the following features:</p>
+
+<ul>
+<li>128K RAM</li>
+<li>Two Disk II floppy disk drives in slot 6</li>
+<li>One Mockingboard A (also known as Sound II) in slot 4</li>
+<li>80-column card in slot 3</li>
+<li>Double Hi-res</li>
+<li>Double Lo-res</li>
+<li>Accurate color TV emulation</li>
+<!--  Warning! abbr tag abuse! -->
+<li>Supports virtual disks types of DSK (read) and WOZ (read/write)&mdash;<abbr title="While Apple2 supported NIB files in the past, they have been superceded by WOZ files and are no longer compatible with the new disk emulatiion. While they served their purpose when we had nothing better, they've now worn out their welcome. :-P Click the link if you're curious to know why."><a href="nib.html">NIB is <b>no longer</b> supported</a></abbr></li>
+</ul>
+
+<h3>How to Use It</h3>
+
+<figure class="flt-r small33">
+<img src="img/ss-01s.png" width="100%">
+<figcaption>Apple2&rsquo;s Control Bar</figcaption>
+</figure>
+
+<p>By mousing over the right side of the screen, the emulator control bar will appear; moving the mouse off of the bar will cause it to disappear.&ensp;On the bar are seven icons, labeled (from top to bottom): power, disk one, disk two, swap disks, save state, load state, and configure.&ensp;Here&rsquo;s what they do:</p>
+
+<ul>
+<li>Power: turn the virtual Apple //e on and off</li>
+<li>Disk One: put a virtual disk into virtual disk drive #1 (or eject from same)</li>
+<li>Disk Two: put a virtual disk into virtual disk drive #2 (or eject from same)</li>
+<li>Swap Disks: take the virtual disk out of virtual drive #1 and put it into virtual drive #2 and take the virtual disk out of virtual drive #2 and put it into virtual drive #1 (it takes a lot of words to describe this simple action)</li>
+<li>Save State: save the state of the Apple2 emulator to a file for later recall</li>
+<li>Load State: load the state of the Apple2 emulator from a file</li>
+<li>Configure: configure various behaviors of the Apple2 emulator</li>
+</ul>
+
+<img class="flt-l small33" src="img/ss-02s.png">
+
+<img class="flt-l small33" src="img/ss-03s.png">
+
+<p>In addition to the aforementioned control bar, Apple2 also supports the following function keys:</p>
+
+<ul>
+<li>F2: Toggle color TV emulation palette</li>
+<li>F3: Toggle between color TV, white monochrome, and green monochrome modes</li>
+<li>F5/F6: Turn the emulated speaker volume up or down</li>
+<li>F7/F8: Turn the emulated Mockingboard volume up or down</li>
+<li>F12: Toggle full screen on/off</li>
+<li>Pause: Pause/unpause the emulation</li>
+<li>Ctrl-Shift-Q: Quit Apple2</li>
+<li>Ctrl-~: Ctrl-RESET</li>
+<li>Left Alt: Open apple key</li>
+<li>Right Alt: Closed apple key</li>
+</ul>
+
 </body>
 </html>
 
diff --git a/web/nib.html b/web/nib.html
new file mode 100644 (file)
index 0000000..5038f6e
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<title>Apple2: An Apple //e Emulator for Linux, Windows, and MacOS</title>
+
+<meta name="description" content="Apple2 homepage" />
+<meta name="keywords" content="apple, emulator, SDL, cross-platform, GPL" />
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Kate" />
+
+<link rel="stylesheet" href="apple2.css" type="text/css" />
+</head>
+
+<body class="mainpage">
+<h1 class="title">Apple2</h1>
+<h2>A portable Apple //e emulator</h2>
+
+<hr>
+
+<h3>NIB Format No Longer Supported</h3>
+
+<p>Why did Apple2 drop support for NIB files, when they were arguably superior to disk images in DSK format?&ensp;While it&rsquo;s true that the NIB format was superior to the DSK format, that was before we had the WOZ format.&ensp;So what?&ensp;What makes the WOZ format better?&ensp;To answer to that seemingly innocuous question will require taking a look at various things that make up proper disk emulation, not the least of which includes various emulator disk file containers.</p>
+
+<p>The DSK format is a byte-for-byte image of a 16-sector Apple II floppy disk: 35 tracks of 16 sectors of 256 bytes each, making 143,360 bytes in total.&ensp;The PO format is exactly the same size as DSK and is also organized as 35 sequential tracks, but the sectors within each track are in a different sequence.&ensp;The NIB format is a nybblized format: a more direct representation of the disk&rsquo;s data as encoded by the Apple II floppy drive hardware.&ensp;NIB contains 35 tracks of 6656 bytes each, for a total size of 232,960 bytes.&ensp;Although this format is much larger, it is also more versatile and can represent the older 13-sector disks, some copy-protected disks, and other unusual encodings.</p>
+
+<p>However, even though the NIB format is closer to what was actually stored on a floppy disk, it has serious shortcomings&mdash;the biggest of these is the lack of so-called &ldquo;extra&rdquo; zero bits (also sometimes called &ldquo;timing&rdquo; bits).&ensp;These timing bits are used by the floppy disk controller to synchronize the reading of the bitstream on the disk; without these you could never be sure exactly what you were reading as reads to the disk are truly random as far as exactly <i>where</i> in the bitstream you will end up reading; since the disk spins independently of the Apple&rsquo;s CPU.</p>
+
+<p>Since that was clear as mud, here&rsquo;s an example.&ensp;Say you have a bitstream on the disk that looks something like this:</p>
+
+<p><tt>10110010010111101011001</tt></p>
+
+<p>When you start reading from the disk, the bytes you end up with can look very different depending on where you caught the bitstream.&ensp;For example, say you caught the bitstream on the first bit.&ensp;The bytes you would end up with would look like (periods represent trailing zero bits):</p>
+
+<p><tt>101100100 101111010 11001 --> B2. BD. C8</tt></p>
+
+<p>However, if you caught the bitstream on the third bit, you would end up with a different interpretation:</p>
+
+<p><tt>[10] 110010010 11110101 1001 --> C9. F5 9x</tt></p>
+
+<p>At this point, the reader is heard to say, &ldquo;So what?&ensp;Why should anyone care about those zero bits?&rdquo;&ensp;</p>
+
+<p>The short answer is because without them, you could never be sure that what you were reading was what was intended to be read.&ensp;Basically, the disk drive mechanism needs a way to let the bitstream &ldquo;slip&rdquo; in a controlled way, and the timing bits are the way that the drive does it.</p>
+
+<p>The usual method that the drive mechanism uses to send data to the CPU is by streaming them eight bits at a time; it also only starts the process of reading an eight bit stream by reading a one bit.&ensp;As a consequence of this, if there are any extraneous zero bits at the start of the next eight bit chunk, it will skip over those until it reads another one bit.&ensp;Thus, to synchronize data on the disk, one method to synchronize very quickly is to have a sequence of ten bits where the first eight bits are ones and the last two are zeroes.&ensp;If the sequence is long enough, it will automatically put the data being read from the disk that follows it in sync, and thus reliable reads are possible.</p>
+
+<p>And since <i>that</i> was also as clear as mud, here&rsquo;s another example.&ensp;Here is a bitstream composed of five ten-bit sequences as described above:</p>
+
+<p><tt>11111111001111111100111111110011111111001111111100</tt></p>
+
+<p>Let&rsquo;s say when reading this sequence, we caught the sixth bit.&ensp;We would end up seeing this:</p>
+
+<p><tt>[11111] 11100111 11111001 111111100 1111111100 1111111100 --> E7 F9 FF.. FF.. FF..</tt></p>
+
+<p>As you can see, even though we missed badly by starting in the stream at bit six, by the time we had read the third byte in the sequence we were already in sync, thanks to those trailing zero bits.&ensp;Thus the importance of the timing bits.</p>
+
+<p>But that still doesn&rsquo;t answer the question of why dropping NIB support is now necessary.&ensp;The short answer is that because the WOZ format is capable of representing what the NIB format could and much more since the WOZ format is a bitstream based format where the NIB format was a byte based format; by virtue of this, the two formats are hopelessly incompatible.</p>
+
+<p>Why are they incompatible?&ensp;The answer is that because the bitstream based format (WOZ) requires the emulation of the floppy disk controller&rsquo;s Logic State Sequencer (or LSS for short), and because of this, it requires timing bits to properly decode the bitstream.&ensp;Since the byte based format (NIB) lacks these, the LSS emulation can and will misinterpret the data from these kinds of images.</p>
+
+<p>So the ironic consequence of this is that NIB format can no longer be properly supported.&ensp;The irony comes from the fact that before there was a need for LSS emulation, NIB was the most accurate format you could get to represent the low level format of a disk, but now, with proper LSS emulation, it&rsquo;s the <i>worst</i> format for representing a floppy disk.&ensp;And the main reason for this is that NIB doesn&rsquo;t contain timing bits, and has no mechanism to represent them&mdash;so when feeding them to the new LSS emulation, they will fail horribly for the aforementioned reasons.&ensp;And since there is now a format that properly represents the bitstream on a floppy disk (WOZ), there&rsquo;s absolutely no reason to keep NIB around or support it anymore.&ensp;While it was a nice interim format to have around (when the emulation of the disk was &ldquo;imperfectly perfect&rdquo;), it now no longer has a place in disk preservation and/or emulation.</p>
+
+</body>
+</html>
+