diff --git a/.gitignore b/.gitignore index 539de20..efe1d56 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ ROMs/bin2c ROMs/from-applewin/ res/ docs/ +wozmaker/ diff --git a/Makefile b/Makefile index 449664c..f0a599b 100644 --- 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) diff --git a/apple2.cfg b/apple2.cfg index 61e176b..b4cac17 100644 --- a/apple2.cfg +++ b/apple2.cfg @@ -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 diff --git a/cross-compile b/cross-compile index f0b73fa..2598b84 100755 --- a/cross-compile +++ b/cross-compile @@ -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..." diff --git a/src/apple2.cpp b/src/apple2.cpp index b9bd4ff..33b9e22 100644 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -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. // @@ -45,12 +45,11 @@ #include #include #include -#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); diff --git a/src/apple2.h b/src/apple2.h index 3e8559e..0bbf6d0 100644 --- a/src/apple2.h +++ b/src/apple2.h @@ -3,7 +3,7 @@ // #include -#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 index 50862ed..0000000 --- a/src/ay8910.cpp +++ /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 // 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; itoneEnable[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 - -#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 - diff --git a/src/charset.cpp b/src/charset.cpp index 6e59b6a..478f00c 100644 --- a/src/charset.cpp +++ b/src/charset.cpp @@ -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 diff --git a/src/crc32.cpp b/src/crc32.cpp index 8c26370..0e8cb89 100644 --- a/src/crc32.cpp +++ b/src/crc32.cpp @@ -1,14 +1,10 @@ // // CRC32 support // -// by David Raingeard & James Hammons +// by James Hammons // (C) 2010-2018 Underground Software // -// JLH = James Hammons -// -// 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> 8); - return crc ^ 0xFFFFFFFF; + return ~crc; } diff --git a/src/crc32.h b/src/crc32.h index 1821847..f390ee9 100644 --- a/src/crc32.h +++ b/src/crc32.h @@ -7,7 +7,7 @@ #include -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 index 859db6d..0000000 --- a/src/floppy.cpp +++ /dev/null @@ -1,872 +0,0 @@ -// -// Apple 2 floppy disk support -// -// by James Hammons -// (c) 2005 Underground Software -// -// JLH = James Hammons -// -// 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 -#include -#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 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 index 0438d65..0000000 --- a/src/floppy.h +++ /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 -#define MAX_PATH _POSIX_PATH_MAX -#else -#include // for MAX_PATH on MinGW/Darwin -// Kludge for Win64 -#ifndef MAX_PATH -#define MAX_PATH _MAX_PATH -#endif -#endif -#include -#include - -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 index 0000000..056ca2b --- /dev/null +++ b/src/floppydrive.cpp @@ -0,0 +1,1500 @@ +// +// Apple 2 floppy disk support +// +// by James Hammons +// (c) 2005-2018 Underground Software +// +// JLH = James Hammons +// +// 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 +#include +#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; itmap, 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 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> 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 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 index 0000000..a98415c --- /dev/null +++ b/src/floppydrive.h @@ -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 +#define MAX_PATH _POSIX_PATH_MAX +#else +#include // for MAX_PATH on MinGW/Darwin +// Kludge for Win64 +#ifndef MAX_PATH +#define MAX_PATH _MAX_PATH +#endif +#endif + +#include +#include + +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__ + diff --git a/src/gui/diskselector.cpp b/src/gui/diskselector.cpp index d13d9bb..80595ee 100644 --- a/src/gui/diskselector.cpp +++ b/src/gui/diskselector.cpp @@ -3,7 +3,7 @@ // // Floppy disk selector GUI // by James Hammons -// © 2014 Underground Software +// © 2014-2018 Underground Software // // JLH = James Hammons // @@ -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 #include #include -#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; iname = 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; inum; 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; - } - } - else - { - if (x >= (DS_XPOS + SCROLL_HOT_WIDTH)) - { - diskSelectorState = DSS_LSB_HIDING; - dxLeft = -8; - } + diskSelectorState = DSS_LSB_SHOWING; + dxLeft = 8; } } - - if (entered && ((colStart + 3) < numColumns)) + else if (x > (DS_XPOS + DS_WIDTH - SCROLL_HOT_WIDTH)) { - if (diskSelectorState != DSS_RSB_SHOWN) + if (((colStart + 3) < numColumns) && (diskSelectorState == DSS_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_RSB_SHOWING; + dxRight = -8; } - else + } + else + { + // 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_HIDING; - dxRight = 8; - } + diskSelectorState = DSS_LSB_HIDING; + dxLeft = -8; + } + else if ((diskSelectorState == DSS_RSB_SHOWING) + || (diskSelectorState == DSS_RSB_SHOWN)) + { + diskSelectorState = DSS_RSB_HIDING; + dxRight = 8; } } diff --git a/src/gui/diskselector.h b/src/gui/diskselector.h index 961e99a..9889172 100644 --- a/src/gui/diskselector.h +++ b/src/gui/diskselector.h @@ -4,6 +4,9 @@ #include #include +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); diff --git a/src/gui/font10pt.cpp b/src/gui/font10pt.cpp index 1ce4121..8a4f38d 100644 --- a/src/gui/font10pt.cpp +++ b/src/gui/font10pt.cpp @@ -6,1156 +6,1172 @@ #include 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, }; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 78d4a74..022c2fd 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -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) diff --git a/src/log.cpp b/src/log.cpp index fb05d36..0c20bf4 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -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; diff --git a/src/mmu.cpp b/src/mmu.cpp index 653eac9..d0f6b5d 100644 --- a/src/mmu.cpp +++ b/src/mmu.cpp @@ -13,10 +13,9 @@ #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" @@ -27,10 +26,6 @@ // 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; diff --git a/src/mmu.h b/src/mmu.h index aed258b..8427e76 100644 --- a/src/mmu.h +++ b/src/mmu.h @@ -3,11 +3,27 @@ #include +// 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 index 0000000..c32e5e3 --- /dev/null +++ b/src/mockingboard.cpp @@ -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 index 0000000..f0b99f8 --- /dev/null +++ b/src/mockingboard.h @@ -0,0 +1,35 @@ +// +// Mockingboard support +// +// by James Hammons +// (C) 2018 Underground Software +// + +#ifndef __MOCKINGBOARD_H__ +#define __MOCKINGBOARD_H__ + +#include +#include +#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 index 6632691..0000000 --- a/src/mos6522via.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Mockingboard support (6522 interface) -// -// by James Hammons -// (C) 2018 Underground Software -// - -#include "mos6522via.h" - -#include // for memset() - - -MOS6522VIA mbvia[4]; - - -void ResetMBVIAs(void) -{ - for(int i=0; i<4; i++) - memset(&mbvia[i], 0, sizeof(MOS6522VIA)); -} - diff --git a/src/sound.cpp b/src/sound.cpp index 67b3090..04b2670 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -24,8 +24,9 @@ #include // For memset, memcpy #include -#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= (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 index 0000000..f43a267 --- /dev/null +++ b/src/v6522via.cpp @@ -0,0 +1,198 @@ +// +// Virtual 6522 Versatile Interface Adapter +// +// by James Hammons +// (C) 2018 Underground Software +// + +#include "v6522via.h" + +#include // 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; +} + diff --git a/src/mos6522via.h b/src/v6522via.h similarity index 61% rename from src/mos6522via.h rename to src/v6522via.h index 4d494a9..6e52022 100644 --- a/src/mos6522via.h +++ b/src/v6522via.h @@ -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 -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) + + V6522VIA(); + void Reset(void); + uint8_t Read(uint8_t); + void Write(uint8_t, uint8_t); + bool Run(uint16_t); }; - -extern MOS6522VIA mbvia[]; - - -void ResetMBVIAs(void); - -#endif // __MOS6522VIA_H__ +#endif // __V6522VIA_H__ diff --git a/src/v65c02.cpp b/src/v65c02.cpp index 02dd846..6a525b7 100644 --- a/src/v65c02.cpp +++ b/src/v65c02.cpp @@ -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 #include "dis65c02.h" #include "log.h" #endif @@ -42,6 +45,15 @@ #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) @@ -87,608 +99,26 @@ 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 & 0xF0) > 0x90) \ - sum -= 0x60; \ + if (sum > 0x09) \ + sum += 0x06; \ +\ + 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; icpuFlags & 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 index 0000000..e0fcc11 --- /dev/null +++ b/src/vay8910.cpp @@ -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 // 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 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 index 0000000..4eb0fe9 --- /dev/null +++ b/src/vay8910.h @@ -0,0 +1,57 @@ +// +// Virtual AY-3-8910 Emulator +// +// by James Hammons +// (C) 2018 Underground Software +// + +#ifndef VAY8910_H +#define VAY8910_H + +#include + +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 + diff --git a/src/video.cpp b/src/video.cpp index 5bc12e0..e027dfa 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -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 - + -

Apple2

+

Apple2

A portable Apple //e emulator


-

This is the home of the Apple2 portable Apple //e emulator. It’s based on GCC and SDL2, and runs on Linux, Windows, and MacOS X. It’s powered by Virtual 65C02™, and sports an easy to use yet powerful interface. The source is licensed under the GPL version 3.

+

This is the home of the Apple2 portable Apple //e emulator. It’s based on GCC and SDL2, and runs on Linux, Windows, and MacOS X. It’s powered by Virtual 65C02™, and sports an easy to use yet powerful interface. It also has WOZ support! The source is licensed under the GPL version 3.

-

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 still to this day can’t match the fidelity of what that old DOS program could do.

+
+ +
Apple2 running “The Bard’s Tale”
+
-

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!

+

This emulator came about because of ApplePC. 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. 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 still to this day can’t match the fidelity of what that old DOS program could do.

-

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:

+

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! [This was true at the time of this writing, but now there are at least two others (LinApple and microM8) out there. —Ed.] 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!

+ +

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 with the following incantation:

git clone http://shamusworld.gotdns.org/git/apple2

+

Features

+ +

Apple2 emulates an enhanced Apple //e with the following features:

+ +
    +
  • 128K RAM
  • +
  • Two Disk II floppy disk drives in slot 6
  • +
  • One Mockingboard A (also known as Sound II) in slot 4
  • +
  • 80-column card in slot 3
  • +
  • Double Hi-res
  • +
  • Double Lo-res
  • +
  • Accurate color TV emulation
  • + +
  • Supports virtual disks types of DSK (read) and WOZ (read/write)—NIB is no longer supported
  • +
+ +

How to Use It

+ +
+ +
Apple2’s Control Bar
+
+ +

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. On the bar are seven icons, labeled (from top to bottom): power, disk one, disk two, swap disks, save state, load state, and configure. Here’s what they do:

+ +
    +
  • Power: turn the virtual Apple //e on and off
  • +
  • Disk One: put a virtual disk into virtual disk drive #1 (or eject from same)
  • +
  • Disk Two: put a virtual disk into virtual disk drive #2 (or eject from same)
  • +
  • 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)
  • +
  • Save State: save the state of the Apple2 emulator to a file for later recall
  • +
  • Load State: load the state of the Apple2 emulator from a file
  • +
  • Configure: configure various behaviors of the Apple2 emulator
  • +
+ + + + + +

In addition to the aforementioned control bar, Apple2 also supports the following function keys:

+ +
    +
  • F2: Toggle color TV emulation palette
  • +
  • F3: Toggle between color TV, white monochrome, and green monochrome modes
  • +
  • F5/F6: Turn the emulated speaker volume up or down
  • +
  • F7/F8: Turn the emulated Mockingboard volume up or down
  • +
  • F12: Toggle full screen on/off
  • +
  • Pause: Pause/unpause the emulation
  • +
  • Ctrl-Shift-Q: Quit Apple2
  • +
  • Ctrl-~: Ctrl-RESET
  • +
  • Left Alt: Open apple key
  • +
  • Right Alt: Closed apple key
  • +
+ diff --git a/web/nib.html b/web/nib.html new file mode 100644 index 0000000..5038f6e --- /dev/null +++ b/web/nib.html @@ -0,0 +1,64 @@ + + + +Apple2: An Apple //e Emulator for Linux, Windows, and MacOS + + + + + + + + + + +

Apple2

+

A portable Apple //e emulator

+ +
+ +

NIB Format No Longer Supported

+ +

Why did Apple2 drop support for NIB files, when they were arguably superior to disk images in DSK format? While it’s true that the NIB format was superior to the DSK format, that was before we had the WOZ format. So what? What makes the WOZ format better? 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.

+ +

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, some copy-protected disks, and other unusual encodings.

+ +

However, even though the NIB format is closer to what was actually stored on a floppy disk, it has serious shortcomings—the biggest of these is the lack of so-called “extra” zero bits (also sometimes called “timing” bits). 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 where in the bitstream you will end up reading; since the disk spins independently of the Apple’s CPU.

+ +

Since that was clear as mud, here’s an example. Say you have a bitstream on the disk that looks something like this:

+ +

10110010010111101011001

+ +

When you start reading from the disk, the bytes you end up with can look very different depending on where you caught the bitstream. For example, say you caught the bitstream on the first bit. The bytes you would end up with would look like (periods represent trailing zero bits):

+ +

101100100 101111010 11001 --> B2. BD. C8

+ +

However, if you caught the bitstream on the third bit, you would end up with a different interpretation:

+ +

[10] 110010010 11110101 1001 --> C9. F5 9x

+ +

At this point, the reader is heard to say, “So what? Why should anyone care about those zero bits?” 

+ +

The short answer is because without them, you could never be sure that what you were reading was what was intended to be read. Basically, the disk drive mechanism needs a way to let the bitstream “slip” in a controlled way, and the timing bits are the way that the drive does it.

+ +

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. 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. 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. 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.

+ +

And since that was also as clear as mud, here’s another example. Here is a bitstream composed of five ten-bit sequences as described above:

+ +

11111111001111111100111111110011111111001111111100

+ +

Let’s say when reading this sequence, we caught the sixth bit. We would end up seeing this:

+ +

[11111] 11100111 11111001 111111100 1111111100 1111111100 --> E7 F9 FF.. FF.. FF..

+ +

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. Thus the importance of the timing bits.

+ +

But that still doesn’t answer the question of why dropping NIB support is now necessary. 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.

+ +

Why are they incompatible? The answer is that because the bitstream based format (WOZ) requires the emulation of the floppy disk controller’s Logic State Sequencer (or LSS for short), and because of this, it requires timing bits to properly decode the bitstream. Since the byte based format (NIB) lacks these, the LSS emulation can and will misinterpret the data from these kinds of images.

+ +

So the ironic consequence of this is that NIB format can no longer be properly supported. 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’s the worst format for representing a floppy disk. And the main reason for this is that NIB doesn’t contain timing bits, and has no mechanism to represent them—so when feeding them to the new LSS emulation, they will fail horribly for the aforementioned reasons. 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.

+ + + +