commit bdd3741b1090c00b8383b1cf6b203458bf6057f4 Author: David Betz Date: Sun Mar 22 13:30:10 2015 -0400 Initial push of the contents of Dave Hein's latest release. diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..fd4e825 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +TARGET = spinsim + +SOURCES = spinsim.c spininterp.c spindebug.c pasmsim.c pasmdebug.c pasmsim2.c pasmdebug2.c eeprom.c debug.c gdb.c +OBJECTS = $(SOURCES:.c=.o) + +ifneq ($(OS),msys) +SOURCES += conion.c +endif + +CC = gcc +# I'm not sure why these linker flags were being used but the break the build on Mac OS X so I've +# commented them out for the time being +#LDFLAGS = -Wl,--relax -Wl,--gc-sections +LDFLAGS = +OPT := -O3 +CFLAGS = -c -g -Wall -Wno-format $(OPT) -I/usr/include -D LINUX + +all: $(SOURCES) $(OBJECTS) Makefile + $(CC) $(LDFLAGS) $(OBJECTS) -o $(TARGET) + +# Compile .c files into objexts .o +.c.o: + $(CC) $(CFLAGS) $< -o $@ + +clean: FORCE + rm -f *.o $(TARGET) +FORCE: diff --git a/README.md b/README.md new file mode 100755 index 0000000..87cdc21 --- /dev/null +++ b/README.md @@ -0,0 +1,135 @@ +Spinsim 0.75 + +This version of spinsim supports about two-thirds of the opcodes in the P2 +instruction set. The list of implemented opcodes is shown below, along with +the list of opcodes that have not been implemented yet. Spinsim runs in the P1 +mode by default. It can be set to run in the P2 mode with the -t parameter. + +In the P2 mode, spinsim will load a P2 OBJ file into hub RAM, and start cog 0 +with the code located at $E00. A simulated serial port is supported by using +the -b option. The default baud rate is 115,200, but other rates can be used +by specifying it with -b, such as -b9600. The serial port uses pin 31 and 30, +just like with P1. + +Spinsim is built using the Makefile, and typing make. I have successfully +built and run it under Cygwin and Ubuntu Linux. + +The sample program, pfth.spin can be run by building it with the PNut P2 +assembler. PNut is contained in the Terasic_Prop2_Emulation zip file, +which can be downloaded from the first post in the "HUB EXEC Update Here" +thread in the Propeller 2 forum. + +There are two demo programs, which are the pfth Forth interpreter and the +p1spin Spin interpreter that runs P1 Spin binaries on the P2 processor. +The pfth program is run under spinsim as follows: + +./spinsim -t -b pfth.obj + +p1spin runs at a baud rate of 57600, so it is run as follows: + +./spinsim -t -b57600 p1spin.obj + +Spinsim supports execution from cog memory and hub execution, but it does not +support multi-tasking. Only the core processor is supported, and none of the +counters, video hardware or cordic hardware is simulated. Support for multi- +tasking, peripheral hardware and cordic instructions will be added later. + +Spinsim contains a simple debugger, which is enabled with the -d command-line +option. The debugger prints the prompt "DEBUG>" to indicate that it is ready +to accept a command. The "help" command will print the following: + +Debug Commands +help - Print command list +exit - Exit spinsim +step - Run one cycle +stepx - Run next executed instruction +run - Run continuously +verbose # - Set verbosity level +reboot - Reboot the Prop +setbr cog addr - Set breakpoint for cog to addr +state cog - Dump cog state + +The "step" command will run one cycle, and the "stepx" command will run any +non-executing cycles until it encounters an instruction that is executed. +The previous command can be executed again by just pushing the enter key. +This is useful for stepping where the "step" command is typed once, and +the enter key can then be used to step again. + +The "run" command will run until a breakpoint is encountered or ^] is typed. +^] is typed by holding down the control key and pressing the "]" key. +While running, spinsim will print out the results of each cycle as +controlled by the verbosity level, which is set by the "verbose" command. +The verbosity level can also be set with the command-line parameter "-v#". + +The verbosity levels are as follows: + +0 - Disable printing +1 - Print only the executed instructions +2 - Print only the executed instructions, and show the execution results +3 - Print executed and instruction not executed due to condition code +4 - Also print instructions invalidated in the pipeline due to jumps +5 - Also print instructions that include hub and hardware waits +6 - Also print instructions that include icache waits +7 - Also print instructions waiting for a pin state +8 - Print all cycles, including waitcnt waits + +The verbosity level is entered as a hexadecimal number. If the verbosity level +is entered as a single digit it will apply to all cogs. If more than one digit +is entered each digit will be used for each cog, starting with cog 0 for the +right-most digit. As an example, a value of 456 will cause 6 to be used for +cog 0, 5 for cog 1, and 4 for cog 2. All other cogs will use 0. + + +Implemented Opcodes +------------------- +abs add addabs addptra addptrb addptrx addptry adds +addsx addx and andn augd augs bingry blmask +call calla callad callb callbd calld callx callxd +cally callyd chkptrx chkptry clkset clracca clraccb clraccs +clrb clrp cmp cmpcnt cmps cmpsub cmpsx cmpx +cogid coginit cognew cogstop dcachex decd decds decmod +decod2 decod3 decod4 decod5 div32 div32u div64 div64d +div64u djnz djnzd djz djzd encod fixinda fixindb +fixindx frac getacah getacal getacbh getacbl getbyte getcnt +getdivq getdivr getmulh getmull getnib getnp getp getptra +getptrb getptrx getptry getsqrt getword icachen icachep icachex +ijnz ijnzd ijz ijzd incd incds incmod isob +jmp jmpd jmpsw jmpswd jnp jnpd jnz jnzd +jp jpd jz jzd locbase locbyte lockclr locknew +lockret lockset loclong locptra locptrb locword maca macb +max maxs mergew min mins mov mul mul32 +mul32u muxc muxnc muxnz muxz neg negc negnc +negnz negz not notb notp offp onecnt or +pop popzc push pushzc rcl rcr rdaux rdauxr +rdbyte rdbytec rdlong rdlongc rdwide rdwidec rdword rdwordc +repd reps ret reta retad retb retbd retd +retx retxd rety retyd rev rol ror sar +saracca saraccb saraccs setacca setaccb setb setbc setbnc +setbnz setbyte setbz setd seti setindb setindx setnib +setp setpc setpnc setpnz setptra setptrb setptrx setptry +setpz sets setwide setwidz setword setzc seussf seussr +shl shr splitw sqrt32 sqrt64 sub subabs subcnt +subptra subptrb subptrx subptry subr subs subsx subx +sumc sumnc sumnz sumz test testn wait waitcnt +waitpeq waitpne wraux wrauxr wrbyte wrlong wrwide wrword +xor zercnt + + +Opcodes Not Implemented +----------------------- +addphsa addphsb addphss addpix bcdbin binbcd blnpix capctra +capctrb capctrs cfgdac0 cfgdac1 cfgdac2 cfgdac3 cfgdacs cfgpins +cmpr decpat eswap4 eswap8 getcntx getcosa getcosb getlfsr +getphsa getphsb getphza getphzb getpix getqx getqy getqz +getsina getsinb grybin incpat jmplist jmptask locinst mergeb +mixpix movbyts mulpix packrgb passcnt polctra polctrb polvid +qartan qexp qlog qrotate qsincos rolbyte rolnib rolword +scl serina serinb serouta seroutb setbyts setctra setctrb +setctrs setdac0 setdac1 setdac2 setdac3 setdacs setfrqa setfrqb +setfrqs setmap setmix setphsa setphsb setphss setpix setpixa +setpixb setpixg setpixr setpixu setpixv setpixw setpixz setpora +setporb setporc setpord setqi setqz setrace setsera setserb +settask setvid setvidi setvidq setvidy setwava setwavb setwavs +setwrds setx setxch setxft splitb subphsa subphsb subphss +synctra synctrb taskid testb unpkrgb waitpf waitpr waitpx +waitvid diff --git a/conio.spin b/conio.spin new file mode 100755 index 0000000..36ff807 --- /dev/null +++ b/conio.spin @@ -0,0 +1,136 @@ +'****************************************************************************** +' Author: Dave Hein +' Version 1.0 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'****************************************************************************** +{{ + This object provides console I/O functions for SpinSim. It implements the same methods as FullDuplexSerial. +}} +con + SYS_COMMAND = $12340000 + SYS_LOCKNUM = $12340002 + SYS_PARM = $12340004 + + SYS_CON_PUTCH = 1 + SYS_CON_GETCH = 2 + +PUB start(rxpin, txpin, mode, baudrate) : okay + ifnot word[SYS_LOCKNUM] + word[SYS_LOCKNUM] := locknew + 1 + return 1 + +PUB stop + + +PUB rxflush + +'' Flush receive buffer + + repeat while rxcheck => 0 + + +PUB rxtime(ms) : rxbyte | t + +'' Wait ms milliseconds for a byte to be received +'' returns -1 if no byte received, $00..$FF if byte + + t := cnt + repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms + + +PUB rx : rxbyte + +'' Receive byte (may wait for byte) +'' returns $00..$FF + + repeat while (rxbyte := rxcheck) < 0 + +PUB rxcheck | locknum + locknum := word[SYS_LOCKNUM] - 1 + if locknum == -1 + return -1 + repeat until not lockset(locknum) + word[SYS_COMMAND] := SYS_CON_GETCH + repeat while word[SYS_COMMAND] + result := long[SYS_PARM] + lockclr(locknum) + + +PUB tx(txbyte) | locknum + +'' Send byte (may wait for room in buffer) + locknum := word[SYS_LOCKNUM] - 1 + if locknum == -1 + return + repeat until not lockset(locknum) + long[SYS_PARM] := txbyte + word[SYS_COMMAND] := SYS_CON_PUTCH + repeat while word[SYS_COMMAND] + lockclr(locknum) + + +PUB str(stringptr) + +'' Send string + + repeat strsize(stringptr) + tx(byte[stringptr++]) + + +PUB dec(value) | i, x + +'' Print a decimal number + + x := value == NEGX 'Check for max negative + if value < 0 + value := ||(value+x) 'If negative, make positive; adjust for max negative + tx("-") 'and output sign + + i := 1_000_000_000 'Initialize divisor + + repeat 10 'Loop for 10 digits + if value => i + tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative + value //= i 'and digit from value + result~~ 'flag non-zero found + elseif result or i == 1 + tx("0") 'If zero digit (or only digit) output it + i /= 10 'Update divisor + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + 'tx(hexdigit[(value <-= 4) & $F]) + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + tx((value <-= 1) & 1 + "0") + +PUB out(char) + tx(char) +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/conion.c b/conion.c new file mode 100755 index 0000000..695d41b --- /dev/null +++ b/conion.c @@ -0,0 +1,73 @@ +#ifdef LINUX +#include +#include "conion.h" + +#ifdef STD_CONSOLE_INPUT +void initialize_console_io() +{ +} + +void restore_console_io() +{ +} + +int kbhit(void) +{ + return 0; +} + +char getch(void) +{ + return getchar(); +} +#else +#include +#include +#include + +static struct termios oldt; +static int oldf; +static int lastkey = EOF; +static int initialized = 0; + +void initialize_console_io() +{ + struct termios newt; + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + oldf = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); + initialized = 1; +} + +void restore_console_io() +{ + if (initialized) + { + initialized = 0; + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + fcntl(STDIN_FILENO, F_SETFL, oldf); + } +} + +int kbhit(void) +{ + if (lastkey == EOF) + lastkey = getchar(); + + return (lastkey != EOF); +} + +char getch(void) +{ + int ch; + + while (!kbhit()); + ch = lastkey; + lastkey = EOF; + return ch; +} +#endif +#endif diff --git a/conion.h b/conion.h new file mode 100755 index 0000000..af3fde6 --- /dev/null +++ b/conion.h @@ -0,0 +1,11 @@ +#ifndef __CONION_H__ +#define __CONION_H__ + +#undef STD_CONSOLE_INPUT + +int kbhit(void); +char getch(void); +void initialize_console_io(void); +void restore_console_io(void); + +#endif diff --git a/debug.c b/debug.c new file mode 100755 index 0000000..dfe3381 --- /dev/null +++ b/debug.c @@ -0,0 +1,222 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.54 +' Copyright (c) 2012 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include +#include +#include +#ifdef LINUX +#include +#include +#include "conion.h" +#else +#include +#include +#endif +#include "interp.h" +#include "spindebug.h" +#include "eeprom.h" +#include "spinsim.h" + +extern int32_t loopcount; +extern int32_t printflag; +extern int32_t baudrate; +extern int32_t eeprom; +extern char *hubram; +extern int32_t printbreak; +extern PasmVarsT PasmVars[8]; + +void GetDebugString(char *ptr); +int32_t RunProp(int32_t maxloops); + +void Help(void) +{ + printf("Debug Commands\n"); + printf("help - Print command list\n"); + printf("exit - Exit spinsim\n"); + printf("step - Run one cycle\n"); + printf("stepx - Run next executed instruction\n"); + printf("run - Run continuously\n"); + printf("verbose # - Set verbosity level\n"); + printf("reboot - Reboot the Prop\n"); + printf("setbr cog addr - Set breakpoint for cog to addr\n"); + printf("state cog - Dump cog state\n"); +} + +char *SkipChar(char *str, int value) +{ + while (*str) + { + if (*str != value) break; + str++; + } + return str; +} + +void DumpState(PasmVarsT *pasmvars) +{ + printf("cflag = %d, zflag = %d, waitflag = %d\n", + pasmvars->cflag, pasmvars->zflag, pasmvars->waitflag); + printf("ptra = %5.5x, ptrb = %5.5x, ptrx = %2.2x, ptry = %2.2x, inda = %3.3x, indb = %3.3x\n", + pasmvars->ptra, pasmvars->ptra, pasmvars->ptrx, + pasmvars->ptry, pasmvars->inda, pasmvars->indb); + printf("pc1 = %8.8x, instruct1 = %8.8x\n", pasmvars->pc1, pasmvars->instruct1); + printf("pc2 = %8.8x, instruct2 = %8.8x\n", pasmvars->pc2, pasmvars->instruct2); + printf("pc3 = %8.8x, instruct3 = %8.8x\n", pasmvars->pc3, pasmvars->instruct3); + printf("pc4 = %8.8x, instruct4 = %8.8x\n", pasmvars->pc4, pasmvars->instruct4); +} + +void Debug(void) +{ + int runflag = 1; + char buffer[200]; + char lastcmd[200]; + int maxloops; + int stepflag = 0; + int saveprintflag = 0; + + strcpy(lastcmd, "help"); + while (runflag) + { + while (1) + { + printf("\nDEBUG> "); + fflush(stdout); + GetDebugString(buffer); + if (buffer[0] == 0) strcpy(buffer, lastcmd); + strcpy(lastcmd, buffer); + if (!strcmp(buffer, "exit")) + { + runflag = 0; + break; + } + else if (!strcmp(buffer, "step")) + { + stepflag = 1; + saveprintflag = printflag; + printflag = 0xffffffff; + LONG(SYS_DEBUG) = printflag; + maxloops = loopcount + 1; + break; + } + else if (!strcmp(buffer, "stepx")) + { + stepflag = 1; + saveprintflag = printflag; + printflag = 0x22222222; + LONG(SYS_DEBUG) = printflag; + printbreak = 1; + maxloops = -1; + break; + } + else if (!strncmp(buffer, "verbose", 7)) + { + char *ptr = SkipChar(buffer+7, ' '); + if (*ptr == 0) + printflag = 0xffffffff; + else + { + sscanf(ptr, "%x", &printflag); + if (ptr[1] == 0) + printflag *= 0x11111111; + } + LONG(SYS_DEBUG) = printflag; + } + else if (!strcmp(buffer, "help")) + { + Help(); + } + else if (!strcmp(buffer, "run")) + { + maxloops = -1; + break; + } + else if (!strncmp(buffer, "setbr ", 6)) + { + int cognum, address; + sscanf(buffer+6, "%x %x", &cognum, &address); + PasmVars[cognum&7].breakpnt = address; + LONG(SYS_DEBUG) = printflag; + } + else if (!strcmp(buffer, "reboot")) + { + RebootProp(); + } + else if (!strncmp(buffer, "state ", 6)) + { + int cognum = buffer[6] & 7; + DumpState(&PasmVars[cognum]); + } + else + printf("?\n"); + } + if (runflag) RunProp(maxloops); + if (stepflag) + { + stepflag = 0; + printbreak = 0; + printflag = saveprintflag; + LONG(SYS_DEBUG) = printflag; + } + } +} + +void GetDebugString(char *ptr) +{ + int value; + + while (1) + { +#ifndef STD_CONSOLE_INPUT + while (!kbhit()); +#endif + value = getch(); + putchx(value); + if (value == 13 || value == 10) + { + *ptr = 0; + return; + } + *ptr++ = value; + } +} + +int32_t RunProp(int32_t maxloops) +{ + int32_t runflag = 1; + + while (runflag && (maxloops < 0 || loopcount < maxloops)) + { + runflag = step_chip(); + CheckCommand(); + if (baudrate) + { + CheckSerialOut(); + if (CheckSerialIn()) return 1; + } + if (eeprom) + CheckEEProm(); + } + return 0; +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/eeprom.c b/eeprom.c new file mode 100755 index 0000000..4668bf2 --- /dev/null +++ b/eeprom.c @@ -0,0 +1,223 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.54 +' Copyright (c) 2012 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include +#include +#include "spinsim.h" + +extern int32_t pin_val; +extern int32_t eeprom; + +static int32_t scl_prev = 1; +static int32_t sda_prev = 1; +static int32_t state = 0; +static int32_t count = 0; +static int32_t value = 0; +static int32_t control = 0; +static int32_t address = 0; +static int32_t drivepin = 0; +static int32_t driveval = 0; + +static unsigned char memory[256*256]; + +void CheckEEProm() +{ + int32_t scl = (pin_val >> 28) & 1; + int32_t sda = (pin_val >> 29) & 1; + + if (!eeprom) return; + + //printf("scl = %d, sda = %d\n", scl, sda); + + if (!drivepin && scl_prev && sda_prev && scl && !sda) + { + //printf("Start\n"); + count = 0; + state = 1; + control = 0; + drivepin = 0; + } + else if (!drivepin && scl_prev && !sda_prev && scl && sda) + { + //printf("Stop\n"); + state = 0; + drivepin = 0; + } + else if (state && scl_prev && !scl) + { + drivepin = 0; + if (state == 1) + { + if (count) control = (control << 1) | sda_prev; + count++; + if (count == 9) + { + //printf("control = %2.2x\n", control); + if ((control & 0xf0) == 0xa0) + { + drivepin = 1; + driveval = 0; + count = 0; + if (control & 1) + state = 5; + else + state = 2; + } + else + { + state = 0; + } + } + } + else if (state == 2 || state == 3) + { + if (count) address = (address << 1) | sda_prev; + else if (state == 2) address = 0; + count++; + if (count == 9) + { + //if (state == 3) printf("address = %2.2x\n", address); + state++; + drivepin = 1; + driveval = 0; + count = 0; + } + } + else if (state == 4) + { + if (count) value = (value << 1) | sda_prev; + count++; + if (count == 9) + { + //printf("value = %2.2x\n", value); + memory[address] = value; + address = (address + 1) & 0xffff; + drivepin = 1; + driveval = 0; + count = 0; + eeprom = 2; + } + } + else if (state == 5) + { + if (count == 0) + { + if (sda_prev) + state = 0; + else + { + value = memory[address]; + drivepin = 1; + driveval = (value >> 7) & 1; + value <<= 1; + count++; + address = (address + 1) & 0xffff; + } + } + else if (count < 8) + { + drivepin = 1; + driveval = (value >> 7) & 1; + value <<= 1; + count++; + } + else + { + count = 0; + drivepin = 0; + } + } + } + if (drivepin) + { + pin_val = (pin_val & (~(1 << 29))) | (driveval << 29); + sda = driveval; + } + scl_prev = scl; + sda_prev = sda; +} + +static FILE *OpenFile(char *fname, char *mode) +{ + FILE *file = fopen(fname, mode); + if (!file) + { + printf("Could not open %s\n", fname); + spinsim_exit(1); + } + return file; +} + +void EEPromInit(char *fname) +{ + FILE *file; + + if (!eeprom) return; + + //printf("EEPromInit(%s)\n", fname); + + if (fname) + { + file = fopen("eeprom.dat", "r"); + if (file) + { + fread(memory, 1, 65536, file); + fclose(file); + memset(memory, 0, 32768); + } + else + memset(memory, 0, 65536); + file = OpenFile(fname, "r"); + fread(memory, 1, 65536, file); + fclose(file); + file = OpenFile("eeprom.dat", "w"); + fwrite(memory, 1, 65536, file); + fclose(file); + return; + } + file = OpenFile("eeprom.dat", "r"); + fread(memory, 1, 65536, file); + fclose(file); +} + +void EEPromClose(void) +{ + FILE *file; + + if (eeprom == 2) + { + file = OpenFile("eeprom.dat", "w"); + fwrite(memory, 1, 65536, file); + fclose(file); + } +} + +void EEPromCopy(char *mem) +{ + if (!eeprom) return; + + //printf("EEPromCopy\n"); + memcpy(mem, memory, 32768); +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/eeprom.h b/eeprom.h new file mode 100755 index 0000000..3c34320 --- /dev/null +++ b/eeprom.h @@ -0,0 +1,4 @@ +void CheckEEProm(void); +void EEPromInit(char *fname); +void EEPromCopy(char *mem); +void EEPromClose(void); diff --git a/fileio.spin b/fileio.spin new file mode 100755 index 0000000..0ebd040 --- /dev/null +++ b/fileio.spin @@ -0,0 +1,189 @@ +'****************************************************************************** +' Author: Dave Hein +' Version 1.0 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'****************************************************************************** +{{ + This object provide file I/O functions for SpinSim. It currently implements only popen, pclose and pread. + The methods a similar to the ones the FSRW object. A dummy mount routine is provide for compatibility. +}} +con + SYS_COMMAND = $12340000 + SYS_LOCKNUM = $12340002 + SYS_PARM = $12340004 + + SYS_FILE_OPEN = 3 + SYS_FILE_CLOSE = 4 + SYS_FILE_READ = 5 + SYS_FILE_WRITE = 6 + SYS_FILE_OPENDIR = 7 + SYS_FILE_CLOSEDIR = 8 + SYS_FILE_READDIR = 9 + SYS_FILE_SEEK = 10 + SYS_FILE_TELL = 11 + SYS_FILE_REMOVE = 12 + SYS_FILE_CHDIR = 13 + SYS_FILE_GETCWD = 14 + SYS_FILE_MKDIR = 15 + SYS_FILE_GETMOD = 16 + +dat + handle0 long 0 + dirhand0 long 0 + direntbuf long 0[20] + +'**************************** +' FSRW Routines +'**************************** +pub mount(pin) + ifnot word[SYS_LOCKNUM] + word[SYS_LOCKNUM] := locknew + 1 + +pub mount_explicit(DO, CLK, DI, CS) + ifnot word[SYS_LOCKNUM] + word[SYS_LOCKNUM] := locknew + 1 + +pub popen(fname, mode) + pclose + handle0 := hopen(fname, mode) + ifnot handle0 + return -1 + +pub pclose + if handle0 + hclose(handle0) + handle0~ + +pub pread(buffer, num) + return hread(handle0, buffer, num) + +pub pwrite(buffer, num) + return hwrite(handle0, buffer, num) + +pub opendir + if dirhand0 + hclosedir(dirhand0) + dirhand0 := hopendir + ifnot dirhand0 + return -1 + +pub nextfile(fbuf) + return hnextfile(dirhand0, fbuf) + +pub seek(position) + result := hseek(handle0, position) + +pub tell + result := htell(handle0) + +pub get_filesize + result := hget_filesize(handle0) + +'**************************** +' handle Routines +'**************************** +pub hopen(fname, mode) + if mode => "a" and mode =< "z" + mode -= "a" - "A" + if mode == "R" + mode := string("rb") + elseif mode == "W" + mode := string("wb") + elseif mode == "A" + mode := string("ab") + elseif mode == "D" + return SystemCall(SYS_FILE_REMOVE, fname) + else + return 0 + result := SystemCall(SYS_FILE_OPEN, @fname) + +pub hclose(handle) + result := SystemCall(SYS_FILE_CLOSE, handle) + +pub hread(handle, buffer, num) + result := SystemCall(SYS_FILE_READ, @handle) + +pub hwrite(handle, buffer, num) + result := SystemCall(SYS_FILE_WRITE, @handle) + +pub hopendir + result := SystemCall(SYS_FILE_OPENDIR, 0) + +pub hclosedir(handle) + result := SystemCall(SYS_FILE_CLOSEDIR, handle) + +pub hnextfile(handle, fbuf) | num + result := hreaddir(handle) + if result + num := strsize(@direntbuf[2]) + if num > 31 + num := 31 + bytemove(fbuf, @direntbuf[2], num) + byte[fbuf][num] := 0 + +pub hreaddir(handle) | pdirent + pdirent := @direntbuf + result := SystemCall(SYS_FILE_READDIR, @handle) + if result + result := @direntbuf + +pub hseek(handle, position) | whence + whence~ + result := SystemCall(SYS_FILE_SEEK, @handle) + +pub htell(handle) + result := SystemCall(SYS_FILE_TELL, handle) + +pub hget_filesize(handle) | offset, whence, position, filesize + position := SystemCall(SYS_FILE_TELL, handle) + offset~ + whence := 2 + SystemCall(SYS_FILE_SEEK, @handle) + filesize := SystemCall(SYS_FILE_TELL, handle) + offset := position + whence~ + SystemCall(SYS_FILE_SEEK, @handle) + return filesize + +pub chdir(path) + result := SystemCall(SYS_FILE_CHDIR, path) + +pub getcwd(str, num) + result := SystemCall(SYS_FILE_CHDIR, @str) + +pub mkdir(path) + result := SystemCall(SYS_FILE_MKDIR, path) + +pub getmod(fname) + result := SystemCall(SYS_FILE_GETMOD, fname) + +pub SystemCall(command, parm) | locknum + locknum := word[SYS_LOCKNUM] - 1 + if locknum == -1 + return -1 + + repeat until not lockset(locknum) + long[SYS_PARM] := parm + word[SYS_COMMAND] := command + repeat while word[SYS_COMMAND] + result := long[SYS_PARM] + lockclr(locknum) +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + diff --git a/gdb.c b/gdb.c new file mode 100755 index 0000000..4872bc1 --- /dev/null +++ b/gdb.c @@ -0,0 +1,418 @@ +/******************************************************************************* +' Version 0.54 +' Copyright (c) 2010, 2011, 2012 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include +#include +#include +#ifdef LINUX +#include +#include +#include "conion.h" +#else +#include +#include +#endif +#include "interp.h" +#include "spinsim.h" + +#define GCC_REG_BASE 0 + +extern FILE *logfile; +extern FILE *tracefile; +extern FILE *cmdfile; +extern PasmVarsT PasmVars[8]; +extern char *hubram; +char cmd[1028]; +extern int32_t proptwo; +extern int32_t profile; +extern int32_t loopcount; + +void reply(char *ptr, int len){ + unsigned char cksum = 0; + int i; + + putc('$', stdout); + if(logfile) fprintf(logfile, "sim>$"); + for(i = 0; i < len; i++){ + putc(ptr[i], stdout); + if(logfile) putc(ptr[i], logfile); + cksum += ptr[i]; + } + fprintf(stdout, "#%02x", cksum); + if(logfile) fprintf(logfile, "#%02x", cksum); + if(logfile) putc('\n', logfile); + fflush(stdout); + if(logfile) fflush(logfile); +} + +char parse_byte(char *ch){ + char s[3]; + char val; + s[0] = ch[0]; + s[1] = ch[1]; + s[2] = 0; + val = 0xff & strtol(s, NULL, 16); + return val; +} + +char get_byte(uint32_t addr){ + if(addr & 0x80000000){ + int cog = (addr >> 28) - 8; + uint32_t tmp; + tmp = PasmVars[cog].mem[(addr & 0x000007ff) >> 2]; + return (tmp >> 8*(addr & 0x3)) & 0xff; + } else { + return BYTE(addr); + } +} + +void put_byte(uint32_t addr, unsigned char val){ + if(addr & 0x80000000){ + int cog = (addr >> 28) - 8; + uint32_t tmp; + tmp = PasmVars[cog].mem[(addr & 0x000007ff) >> 2]; + switch(addr & 3){ + case 0: + tmp &= 0xffffff00; + tmp |= val; + break; + case 1: + tmp &= 0xffff00ff; + tmp |= val << 8; + break; + case 2: + tmp &= 0xff00ffff; + tmp |= val << 16; + break; + case 3: + tmp &= 0x00ffffff; + tmp |= val << 24; + break; + } + PasmVars[cog].mem[(addr & 0x000007ff) >> 2] = tmp; + return; + } else { + BYTE(addr) = val; + return; + } +} + +void get_cmd(){ + int i = 0; + int ch; + + do{ + ch = getc(cmdfile); + } while(ch != '$'); + + if(logfile) fprintf(logfile, "gdb>"); + if(logfile) putc(ch, logfile); + + for(i = 0; i < sizeof(cmd); i++){ + ch = getc(cmdfile); + if(logfile) putc(ch, logfile); + if(ch == '#') break; + cmd[i] = ch; + } + cmd[i] = 0; + // eat the checksum + ch = getc(cmdfile); + if(logfile) putc(ch, logfile); + ch = getc(cmdfile); + if(logfile) putc(ch, logfile); + if(logfile) putc('\n', logfile); + // send an ACK + putchar('+'); + fflush(stdout); + if(logfile) fflush(logfile); +} + +int tohex(char x){ + if(x >= '0' && x <= '9') return x - '0'; + if(x >= 'a' && x <= 'f') return 10 + x - 'a'; + if(x >= 'A' && x <= 'F') return 10 + x - 'A'; + return 0; +} + +int32_t get_addr(int *i){ + int32_t reg; + reg = tohex(cmd[(*i)++]) << 4; + reg |= tohex(cmd[(*i)++]) << 0; + reg |= tohex(cmd[(*i)++]) << 12; + reg |= tohex(cmd[(*i)++]) << 8; + reg |= tohex(cmd[(*i)++]) << 20; + reg |= tohex(cmd[(*i)++]) << 16; + reg |= tohex(cmd[(*i)++]) << 28; + reg |= tohex(cmd[(*i)++]) << 24; + return reg; +} + +struct bkpt { + struct bkpt *next; + uint32_t addr; + uint32_t len; +}; + +struct bkpt *bkpt = 0; + +// Check the cog's PC to see if the LMM microcode is at an appropriate place +// for a breakpoint to occur. We don't want to break on LMM administrative +// instructions. +// FIXME we need a more general way to do this. This is too dependent on special knowledge. +int breakable_point(int i){ + int32_t pc = PasmVars[i].pc; + if ((pc == 0x0000004c/4) + || (pc == 0x00000058/4) + || (pc == 0x00000064/4) + || (pc == 0x00000070/4) + || (pc == 0x0000007c/4) + || (pc == 0x00000088/4) + || (pc == 0x00000094/4) + || (pc == 0x000000a0/4)) + return 1; + else + return 0; +} + +void gdb(void) +{ + int i; + int j; + char response[1024]; + unsigned int addr; + int len; + char *end; + char val; + int32_t reg; + int cog = 0; + char *halt_code = "S05"; + + if(logfile) fprintf(logfile, "\n\nStarting log:\n"); + + RebootProp(); + + for(;;){ + get_cmd(); + i = 0; + switch(cmd[i++]){ + case 'g': + for(i = 0; i < 18; i++){ + reg = PasmVars[cog].mem[GCC_REG_BASE + i]; + sprintf(response+8*i, + "%02x%02x%02x%02x", + (unsigned char)(reg & 0xff), + (unsigned char)((reg>>8) & 0xff), + (unsigned char)((reg>>16) & 0xff), + (unsigned char)((reg>>24) & 0xff)); + } + reg = PasmVars[cog].pc * 4 + 0x80000000 + cog * 0x10000000; + sprintf(response+8*i, + "%02x%02x%02x%02x", + (unsigned char)(reg & 0xff), + (unsigned char)((reg>>8) & 0xff), + (unsigned char)((reg>>16) & 0xff), + (unsigned char)((reg>>24) & 0xff)); + reply(response, 8*18+8); + break; + + case 'G': + for(j = 0; j < 18; j++){ + PasmVars[cog].mem[GCC_REG_BASE + j] = get_addr(&i); + } + // Ignore writes to cog pc. Instead, reset it to be + // ready for a fresh instruction. + // This is too magical. How do we fix it? + PasmVars[cog].pc = 0x12; + reply("OK",2); + break; + + case 'm': + addr = strtol(&cmd[i], &end, 16); + i = (size_t)end - (size_t)cmd; + i++; + len = strtol(&cmd[i], NULL, 16); + if(len > 512) len = 512; + j = 0; + while(len--){ + val = get_byte(addr); + addr++; + sprintf(&response[j], "%02x", (unsigned char)val); + j += 2; + } + reply(response, j); + break; + + case 'M': + addr = strtol(&cmd[i], &end, 16); + i = (size_t)end - (size_t)cmd; + i++; + len = strtol(&cmd[i], &end, 16); + i = (size_t)end - (size_t)cmd; + i++; + while(len--){ + val = parse_byte(&cmd[i]); + i += 2; + put_byte(addr, val & 0xff); + addr++; + } + reply("OK",2); + break; + + case 's': + if(cmd[i]){ + // Get the new LMM PC, reset the microcode + PasmVars[cog].mem[GCC_REG_BASE + 17] = get_addr(&i); + PasmVars[cog].pc = 0x12; + } + { + int brk = 0; + do { + int i; + // Step through a full LMM instruction + step_chip(); + for(i = 0; i < 8; i++){ + if(breakable_point(i)) brk = 1; + } + } while (!brk); + } + halt_code = "S05"; + reply(halt_code, 3); + break; + + case 'c': + if(cmd[i]){ + PasmVars[cog].mem[GCC_REG_BASE + 17] = get_addr(&i); + PasmVars[cog].pc = 0x12; + } + halt_code = "S02"; + do { + int brk = 0; + struct bkpt *b; + + for (i = 0; i < 8; i++) { + if(breakable_point(i)){ + // Look to see if the cog's LMM PC is at a breakpoint + for(b = (struct bkpt *)&bkpt; b->next; b = b->next){ + if((PasmVars[i].mem[GCC_REG_BASE + 17] >= b->next->addr) + && (PasmVars[i].mem[GCC_REG_BASE + 17] <= b->next->addr + b->next->len)){ + brk = 1; + } + } + } + } + if(brk){ + halt_code = "S05"; + break; + } else { + step_chip(); + } + } while(getch() != 0x03); // look for a CTRL-C + reply(halt_code, 3); + break; + + case 'H': + if((cmd[i] == 'g') && (cmd[i+1] == '0')){ + reply("OK", 2); + } else { + reply("", 0); + } + break; + + case 'k': + reply("OK", 2); + goto out; + + case 'z': + /* Remove breakpoint */ + if(cmd[i++] == '0'){ + long addr; + long len; + struct bkpt *b; + char *p = &cmd[i]; + + p++; /* Skip the comma */ + addr = strtol(p, &p, 16); + p++; /* Skip the other comma */ + len = strtol(p, NULL, 16); + for(b = (struct bkpt *)&bkpt; b && b->next; b = b->next){ + if((b->next->addr == addr) && (b->next->len == len)){ + struct bkpt *t = b->next; + b->next = t->next; + free(t); + } + } + reply("OK", 2); + } else { + reply("", 0); + } + break; + + case 'Z': + /* Set breakpoint */ + if(cmd[i++] == '0'){ + long addr; + long len; + struct bkpt *b; + char *p = &cmd[i]; + p++; /* Skip the comma */ + addr = strtol(p, &p, 16); + p++; /* Skip the other comma */ + len = strtol(p, NULL, 16); + for(b = (struct bkpt *)&bkpt; b->next; b = b->next){ + if((b->addr == addr) && (b->len == len)){ + /* Duplicate; bail out */ + break; + } + } + if(b->next){ + /* Was a duplicate, do nothing */ + } else { + struct bkpt *t = (struct bkpt *)malloc(sizeof(struct bkpt)); + if(!t){ + fprintf(stderr, "Failed to allocate a breakpoint structure\n"); + spinsim_exit(1); + } + t->addr = addr; + t->len = len; + t->next = bkpt; + bkpt = t; + } + reply("OK", 2); + } else { + reply("", 0); + } + break; + + case '?': + reply(halt_code, 3); + break; + + default: + reply("", 0); + break; + } + } + out: + ; +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/interp.h b/interp.h new file mode 100755 index 0000000..09d8a25 --- /dev/null +++ b/interp.h @@ -0,0 +1,151 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +//#include +#include + +#define BYTE(addr) (((uint8_t *)hubram)[MAP_ADDR(addr)]) +#define WORD(addr) (((uint16_t *)hubram)[MAP_ADDR(addr) >> 1]) +#define LONG(addr) (((int32_t *)hubram)[MAP_ADDR(addr) >> 2]) + +// Define system I/O addresses and commands +#define SYS_COMMAND 0x12340000 +#define SYS_LOCKNUM 0x12340002 +#define SYS_PARM 0x12340004 +#define SYS_DEBUG 0x12340008 + +#define INVALIDATE_INSTR 0x80000000 + +// This struct is used by the PASM simulator +typedef struct PasmVarsS { + int32_t mem[512]; + int32_t state; + int32_t pc; + int32_t cflag; + int32_t zflag; + int32_t cogid; + int32_t waitflag; + int32_t waitmode; + int32_t breakpnt; + // P2 variables + int32_t instruct1; + int32_t instruct2; + int32_t instruct3; + int32_t instruct4; + int32_t pc1; + int32_t pc2; + int32_t pc3; + int32_t pc4; + int32_t dcachehubaddr; + int32_t dcachecogaddr; + int32_t icachehubaddr[4]; + int32_t icachenotused[4]; + int32_t ptra; + int32_t ptra0; + int32_t ptrb; + int32_t ptrb0; + int32_t ptrx; + int32_t ptry; + int32_t inda; + int32_t inda0; + int32_t indabot; + int32_t indatop; + int32_t indb; + int32_t indb0; + int32_t indbbot; + int32_t indbtop; + int32_t repcnt; + int32_t repbot; + int32_t reptop; + int32_t repforever; + int32_t dcache[8]; + int32_t icache[4][8]; + int32_t retstack[4]; + int32_t auxram[256]; + int32_t printflag; + int32_t retptr; + int32_t divq; + int32_t divr; + int32_t divisor; + int32_t mulcount; + int32_t augsvalue; + int32_t augsflag; + int32_t augdvalue; + int32_t augdflag; + int32_t prefetch; + int32_t sqrt; + int32_t lastd; + int64_t acca; + int64_t accb; + int64_t mul; +} PasmVarsT; + +// This struct is used by the Spin simulator +// It is a subset of PasmVarsT starting at mem[0x1e0] +typedef struct SpinVarsS { + int32_t x1e0; // $1e0 + int32_t x1e1; // $1e1 + int32_t x1e2; // $1e2 + int32_t x1e3; // $1e3 + int32_t x1e4; // $1e4 + int32_t masklong; // $1e5 + int32_t masktop; // $1e6 + int32_t maskwr; // $1e7 + int32_t lsb; // $1e8 + int32_t id; // $1e9 + int32_t dcall; // $1ea + int32_t pbase; // $1eb + int32_t vbase; // $1ec + int32_t dbase; // $1ed + int32_t pcurr; // $1ee + int32_t dcurr; // $1ef + int32_t par; // $1f0 + int32_t cnt; // $1f1 + int32_t ina; // $1f2 + int32_t inb; // $1f3 + int32_t outa; // $1f4 + int32_t outb; // $1f5 + int32_t dira; // $1f6 + int32_t dirb; // $1f7 + int32_t ctra; // $1f8 + int32_t ctrb; // $1f9 + int32_t frqa; // $1fa + int32_t frqb; // $1fb + int32_t phsa; // $1fc + int32_t phsb; // $1fd + int32_t vcfg; // $1fe + int32_t vscl; // $1ff + int32_t state; +} SpinVarsT; + +void RebootProp(void); +int32_t GetCnt(void); +void UpdatePins(void); +int32_t MAP_ADDR(int32_t addr); +void DebugPasmInstruction(PasmVarsT *pasmvars); +int ExecutePasmInstruction(PasmVarsT *pasmvars); +void DebugPasmInstruction2(PasmVarsT *pasmvars); +int ExecutePasmInstruction2(PasmVarsT *pasmvars); +void StartCog(SpinVarsT *spinvars, int par, int cogid); +void StartPasmCog(PasmVarsT *pasmvars, int par, int addr, int cogid); +void StartPasmCog2(PasmVarsT *pasmvars, int par, int addr, int cogid); +/* ++ -----------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/opcodes.h b/opcodes.h new file mode 100755 index 0000000..9b5461c --- /dev/null +++ b/opcodes.h @@ -0,0 +1,250 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +typedef struct OpCodeS { + unsigned char opform; + unsigned char opcode; + char *opname; +} OpCodeT; + +static OpCodeT optable[] = { + {0x00, 0x00, "ldfrmr"}, + {0x00, 0x01, "ldfrm"}, + {0x00, 0x02, "ldfrmar"}, + {0x00, 0x03, "ldfrma"}, + {0x05, 0x04, "jmp"}, + {0x0a, 0x05, "call"}, + {0x07, 0x06, "callobj"}, + {0x07, 0x07, "callobjx"}, + {0x05, 0x08, "tjz"}, + {0x05, 0x09, "djnz"}, + {0x05, 0x0a, "jz"}, + {0x05, 0x0b, "jnz"}, + {0x00, 0x0c, "casedone"}, + {0x08, 0x0d, "casevalue"}, + {0x08, 0x0e, "caserange"}, + {0x00, 0x0f, "lookdone"}, + {0x00, 0x10, "lookupval"}, + {0x00, 0x11, "lookdnval"}, + {0x00, 0x12, "lookuprng"}, + {0x00, 0x13, "lookdnrng"}, + {0x00, 0x14, "pop"}, + {0x00, 0x15, "run"}, + {0x00, 0x16, "strsize"}, + {0x00, 0x17, "strcomp"}, + {0x00, 0x18, "bytefill"}, + {0x00, 0x19, "wordfill"}, + {0x00, 0x1a, "longfill"}, + {0x00, 0x1b, "waitpeq"}, + {0x00, 0x1c, "bytemove"}, + {0x00, 0x1d, "wordmove"}, + {0x00, 0x1e, "longmove"}, + {0x00, 0x1f, "waitpne"}, + {0x00, 0x20, "clkset"}, + {0x00, 0x21, "cogstop"}, + {0x00, 0x22, "lockret"}, + {0x00, 0x23, "waitcnt"}, + {0x00, 0x24, "ldregx"}, + {0x00, 0x25, "stregx"}, + {0x20, 0x26, "exregx"}, + {0x00, 0x27, "waitvid"}, + {0x00, 0x28, "coginitret"}, + {0x00, 0x29, "locknewret"}, + {0x00, 0x2a, "locksetret"}, + {0x00, 0x2b, "lockclrret"}, + {0x00, 0x2c, "coginit"}, + {0x00, 0x2d, "locknew"}, + {0x00, 0x2e, "lockset"}, + {0x00, 0x2f, "lockclr"}, + {0x00, 0x30, "abort"}, + {0x00, 0x31, "abortval"}, + {0x00, 0x32, "ret"}, + {0x00, 0x33, "retval"}, + {0x00, 0x34, "ldlim1"}, + {0x00, 0x35, "ldli0"}, + {0x00, 0x36, "ldli1"}, + {0x09, 0x37, "ldlip"}, + {0x0a, 0x38, "ldbi"}, + {0x0b, 0x39, "ldwi"}, + {0x0c, 0x3a, "ldmi"}, + {0x0d, 0x3b, "ldli"}, + {0x00, 0x3c, "lmm"}, + {0x0f, 0x3d, "ldregbit"}, + {0x0e, 0x3d, "stregbit"}, + {0x0e, 0x3d, "exregbit"}, + {0x0f, 0x3e, "ldregbits"}, + {0x0e, 0x3e, "stregbits"}, + {0x0e, 0x3e, "exregbits"}, + {0x0f, 0x3f, "ldreg"}, + {0x06, 0x3f, "streg"}, + {0x0e, 0x3f, "exreg"}, + {0x10, 0x40, "ldlvc"}, + {0x10, 0x41, "stlvc"}, + {0x30, 0x42, "exlvc"}, + {0x10, 0x43, "lalvc"}, + {0x11, 0x60, "ldllc"}, + {0x11, 0x61, "stllc"}, + {0x31, 0x62, "exllc"}, + {0x11, 0x63, "lallc"}, + {0x00, 0x80, "ldba"}, + {0x00, 0x81, "stba"}, + {0x20, 0x82, "exba"}, + {0x00, 0x83, "laba"}, + {0x01, 0x84, "ldbo"}, + {0x01, 0x85, "stbo"}, + {0x21, 0x86, "exbo"}, + {0x01, 0x87, "labo"}, + {0x02, 0x88, "ldbv"}, + {0x02, 0x89, "stbv"}, + {0x22, 0x8a, "exbv"}, + {0x02, 0x8b, "labv"}, + {0x03, 0x8c, "ldbl"}, + {0x03, 0x8d, "stbl"}, + {0x23, 0x8e, "exbl"}, + {0x03, 0x8f, "labl"}, + {0x00, 0x90, "ldbax"}, + {0x00, 0x91, "stbax"}, + {0x20, 0x92, "exbax"}, + {0x00, 0x93, "labax"}, + {0x01, 0x94, "ldbox"}, + {0x01, 0x95, "stbox"}, + {0x21, 0x96, "exbox"}, + {0x01, 0x97, "labox"}, + {0x02, 0x98, "ldbvx"}, + {0x02, 0x99, "stbvx"}, + {0x22, 0x9a, "exbvx"}, + {0x02, 0x9b, "labvx"}, + {0x03, 0x9c, "ldblx"}, + {0x03, 0x9d, "stblx"}, + {0x23, 0x9e, "exblx"}, + {0x03, 0x9f, "lablx"}, + {0x00, 0xa0, "ldwa"}, + {0x00, 0xa1, "stwa"}, + {0x20, 0xa2, "exwa"}, + {0x00, 0xa3, "lawa"}, + {0x01, 0xa4, "ldwo"}, + {0x01, 0xa5, "stwo"}, + {0x21, 0xa6, "exwo"}, + {0x01, 0xa7, "lawo"}, + {0x02, 0xa8, "ldwv"}, + {0x02, 0xa9, "stwv"}, + {0x22, 0xaa, "exwv"}, + {0x02, 0xab, "lawv"}, + {0x03, 0xac, "ldwl"}, + {0x03, 0xad, "stwl"}, + {0x23, 0xae, "exwl"}, + {0x03, 0xaf, "lawl"}, + {0x00, 0xb0, "ldwax"}, + {0x00, 0xb1, "stwax"}, + {0x20, 0xb2, "exwax"}, + {0x00, 0xb3, "lawax"}, + {0x01, 0xb4, "ldwox"}, + {0x01, 0xb5, "stwox"}, + {0x21, 0xb6, "exwox"}, + {0x01, 0xb7, "lawox"}, + {0x02, 0xb8, "ldwvx"}, + {0x02, 0xb9, "stwvx"}, + {0x22, 0xba, "exwvx"}, + {0x02, 0xbb, "lawvx"}, + {0x03, 0xbc, "ldwlx"}, + {0x03, 0xbd, "stwlx"}, + {0x23, 0xbe, "exwlx"}, + {0x03, 0xbf, "lawlx"}, + {0x00, 0xc0, "ldla"}, + {0x00, 0xc1, "stla"}, + {0x20, 0xc2, "exla"}, + {0x00, 0xc3, "lala"}, + {0x01, 0xc4, "ldlo"}, + {0x01, 0xc5, "stlo"}, + {0x21, 0xc6, "exlo"}, + {0x01, 0xc7, "lalo"}, + {0x02, 0xc8, "ldlv"}, + {0x02, 0xc9, "stlv"}, + {0x22, 0xca, "exlv"}, + {0x02, 0xcb, "lalv"}, + {0x03, 0xcc, "ldll"}, + {0x03, 0xcd, "stll"}, + {0x23, 0xce, "exll"}, + {0x03, 0xcf, "lall"}, + {0x00, 0xd0, "ldlax"}, + {0x00, 0xd1, "stlax"}, + {0x20, 0xd2, "exlax"}, + {0x00, 0xd3, "lalax"}, + {0x01, 0xd4, "ldlox"}, + {0x01, 0xd5, "stlox"}, + {0x21, 0xd6, "exlox"}, + {0x01, 0xd7, "lalox"}, + {0x02, 0xd8, "ldlvx"}, + {0x02, 0xd9, "stlvx"}, + {0x22, 0xda, "exlvx"}, + {0x02, 0xdb, "lalvx"}, + {0x03, 0xdc, "ldllx"}, + {0x03, 0xdd, "stllx"}, + {0x23, 0xde, "exllx"}, + {0x03, 0xdf, "lallx"}, + {0x40, 0xe0, "ror"}, + {0x40, 0xe1, "rol"}, + {0x40, 0xe2, "shr"}, + {0x40, 0xe3, "shl"}, + {0x40, 0xe4, "minlim"}, + {0x40, 0xe5, "maxlim"}, + {0x40, 0xe6, "neg"}, + {0x40, 0xe7, "com"}, + {0x40, 0xe8, "and"}, + {0x40, 0xe9, "abs"}, + {0x40, 0xea, "or"}, + {0x40, 0xeb, "xor"}, + {0x40, 0xec, "add"}, + {0x40, 0xed, "sub"}, + {0x40, 0xee, "sar"}, + {0x40, 0xef, "rev"}, + {0x40, 0xf0, "andl"}, + {0x40, 0xf1, "encode"}, + {0x40, 0xf2, "orl"}, + {0x40, 0xf3, "decode"}, + {0x40, 0xf4, "mul"}, + {0x40, 0xf5, "mulh"}, + {0x40, 0xf6, "div"}, + {0x40, 0xf7, "mod"}, + {0x40, 0xf8, "sqrt"}, + {0x40, 0xf9, "cmplt"}, + {0x40, 0xfa, "cmpgt"}, + {0x40, 0xfb, "cmpne"}, + {0x40, 0xfc, "cmpeq"}, + {0x40, 0xfd, "cmple"}, + {0x40, 0xfe, "cmpge"}, + {0x40, 0xff, "notl"}, + {0x60, 0x00, "store"}, + {0x60, 0x02, "repeat"}, + {0x60, 0x06, "repeats"}, + {0x60, 0x08, "randf"}, + {0x60, 0x0c, "randr"}, + {0x60, 0x10, "sexb"}, + {0x60, 0x14, "sexw"}, + {0x60, 0x18, "postclr"}, + {0x60, 0x1c, "postset"}, + {0x60, 0x20, "preinc"}, + {0x60, 0x28, "postinc"}, + {0x60, 0x30, "predec"}, + {0x60, 0x38, "postdec"}, + {0, 0, 0}}; +/* ++ -----------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/p1spin/Simple_Serial.spin b/p1spin/Simple_Serial.spin new file mode 100755 index 0000000..a7a8f2b Binary files /dev/null and b/p1spin/Simple_Serial.spin differ diff --git a/p1spin/dry11.spin b/p1spin/dry11.spin new file mode 100755 index 0000000..48884f7 --- /dev/null +++ b/p1spin/dry11.spin @@ -0,0 +1,243 @@ +'********************************************** +' Dhrystone 1.1 +'********************************************** + +OBJ + ser : "Simple_Serial" + +CON + _clkmode = xtal1+pll16x + _clkfreq = 80000000 + LOOPS = 500 + + Ident1 = 1 + Ident2 = 2 + Ident3 = 3 + Ident4 = 4 + Ident5 = 5 + +' typedef struct Record + PtrComp = 0 + Discr = 4 + EnumComp = 8 + IntComp = 12 + StringComp = 16 + + NULL = 0 + +DAT + Version byte "1.1", 0 + Array1Glob long 0[51] + Array2Glob long 0[51*51] + xxx long 0[12] + yyy long 0[12] + PtrGlb long 0 + PtrGlbNext long 0 + IntGlob long 0 + BoolGlob long 0 + Char1Glob long 0 + Char2Glob long 0 + String1Loc long 0[8] + String2Loc long 0[8] + starttime long 0 + benchtime long 0 + nulltime long 0 + +PUB Dhrystone11 + + PtrGlb := @xxx + PtrGlbNext := @yyy + Proc0 + +{ + * Package 1 + } +PUB Proc0 | IntLoc1, IntLoc2, IntLoc3, CharLoc, CharIndex, EnumLoc, i + starttime := time_msec + i := 0 + repeat while (i < LOOPS) + ++i + nulltime := time_msec - starttime { Computes o'head of loop } + long[PtrGlb + PtrComp] := PtrGlbNext + long[PtrGlb + Discr] := Ident1 + long[PtrGlb + EnumComp] := Ident3 + long[PtrGlb + IntComp] := 40 + strcpy((PtrGlb + StringComp), string("DHRYSTONE PROGRAM, SOME STRING")) + strcpy(@String1Loc, string("DHRYSTONE PROGRAM, 1'ST STRING")) {GOOF} + long[@Array2Glob][8 * 51 + 7] := 10 { Was missing in published program } + {**************** + -- Start Timer -- + ****************} + starttime := time_msec + i := 0 + repeat while (i < LOOPS) + Proc5 + Proc4 + IntLoc1 := 2 + IntLoc2 := 3 + strcpy(@String2Loc, string("DHRYSTONE PROGRAM, 2'ND STRING")) + EnumLoc := Ident2 + BoolGlob := not Func2(@String1Loc, @String2Loc) + repeat while (IntLoc1 < IntLoc2) + IntLoc3 := 5 * IntLoc1 - IntLoc2 + Proc7(IntLoc1, IntLoc2, @IntLoc3) + ++IntLoc1 + Proc8(@Array1Glob, @Array2Glob, IntLoc1, IntLoc3) + Proc1(PtrGlb) + byte[@CharIndex] := "A" + repeat while (byte[@CharIndex] =< Char2Glob) + if (EnumLoc == Func1(byte[@CharIndex], "C")) + Proc6(Ident1, @EnumLoc) + byte[@CharIndex] := byte[@charIndex] + 1 + IntLoc3 := IntLoc2 * IntLoc1 + IntLoc2 := IntLoc3 / IntLoc1 + IntLoc2 := 7 *(IntLoc3 - IntLoc2) - IntLoc1 + Proc2(@IntLoc1) + ++i + {**************** + -- Stop Timer -- + ****************} + benchtime := time_msec - starttime - nulltime + ser.str(string("Dhrystone(")) + ser.str(@Version) + ser.str(string(") time for ")) + ser.dec(LOOPS) + ser.str(string(" passes = ")) + ser.dec(benchtime) + ser.str(string(" msec", 13)) + ser.str(string("This machine benchmarks at ")) + ser.dec(LOOPS * 1000 / benchtime) + ser.str(string(" dhrystones/second", 13)) + +PUB Proc1(PtrParIn) + memcpy(long[PtrParIn + PtrComp], PtrGlb, 48) + long[PtrParIn + IntComp] := 5 + long[long[PtrParIn + PtrComp] + IntComp] := long[PtrParIn + IntComp] + long[long[PtrParIn + PtrComp] + PtrComp] := long[PtrParIn + PtrComp] + Proc3(long[long[PtrParIn + PtrComp] + PtrComp]) + if (long[long[PtrParIn + PtrComp] + Discr] == Ident1) + long[long[PtrParIn + PtrComp] + IntComp] := 6 + Proc6(long[PtrParIn + EnumComp], long[PtrParIn + PtrComp] + EnumComp) + long[long[PtrParIn + PtrComp] + PtrComp] := long[PtrGlb + PtrComp] + Proc7(long[long[PtrParIn + PtrComp] + IntComp], 10, long[PtrParIn + PtrComp] + IntComp) + else + memcpy(PtrParIn, long[PtrParIn + PtrComp], 48) + +PUB Proc2(IntParIO) | IntLoc, EnumLoc + IntLoc := long[IntParIO] + 10 + + repeat 'while () + if (Char1Glob == "A") + --IntLoc + long[IntParIO] := IntLoc - IntGlob + EnumLoc := Ident1 + if (EnumLoc == Ident1) + quit + +PUB Proc3(PtrParOut) + if (PtrGlb <> NULL) + PtrParOut := long[PtrGlb + PtrComp] + else + IntGlob := 100 + Proc7(10, IntGlob, PtrGlb + IntComp) + +PUB Proc4 | BoolLoc + BoolLoc := Char1Glob == "A" + BoolLoc |= BoolGlob + Char2Glob := "B" + +PUB Proc5 + Char1Glob := "A" + BoolGlob := FALSE + +PUB Proc6(EnumParIn, EnumParOut) + long[EnumParOut] := EnumParIn + ifnot Func3(EnumParIn) + long[EnumParOut] := Ident4 + if EnumParIn == Ident1 + long[EnumParOut] := Ident1 + elseif EnumParIn == Ident2 + if (IntGlob > 100) + long[EnumParOut] := Ident1 + else + long[EnumParOut] := Ident4 + elseif EnumParIn == Ident3 + long[EnumParOut] := Ident2 + elseif (EnumParIn == Ident4) or (EnumParIn == Ident5) + long[EnumParOut] := Ident3 + +PUB Proc7(IntParI1, IntParI2, IntParOut) | IntLoc + IntLoc := IntParI1 + 2 + long[IntParOut] := IntParI2 + IntLoc + +PUB Proc8(Array1Par, Array2Par, IntParI1, IntParI2) | IntLoc, IntIndex + IntLoc := IntParI1 + 5 + long[Array1Par][IntLoc] := IntParI2 + long[Array1Par][IntLoc + 1] := long[Array1Par][IntLoc] + long[Array1Par][IntLoc + 30] := IntLoc + IntIndex := IntLoc + repeat while (IntIndex =<(IntLoc + 1)) + long[Array2Par][IntLoc * 51 + IntIndex] := IntLoc + ++IntIndex + ++long[Array2Par][IntLoc * 51 + IntLoc - 1] + long[Array2Par][(IntLoc + 20) * 51 + IntLoc] := long[Array1Par][IntLoc] + IntGlob := 5 + +PUB Func1(CharPar1, CharPar2) | CharLoc1, CharLoc2 + byte[@CharLoc1] := byte[@CharPar1] + byte[@CharLoc2] := byte[@CharLoc1] + if (byte[@CharLoc2] <> byte[@CharPar2]) + return (Ident1) + else + return (Ident2) + +PUB Func2(StrParI1, StrParI2) | IntLoc, CharLoc + IntLoc := 1 + repeat while (IntLoc =< 1) + if (Func1(byte[StrParI1][IntLoc], byte[StrParI2][IntLoc + 1]) == Ident1) + byte[@CharLoc] := "A" + ++IntLoc + if (byte[@CharLoc] => "W" and byte[@CharLoc] =< "Z") + IntLoc := 7 + if (byte[@CharLoc] == "X") + return (TRUE) + else + if (strcmp(StrParI1, StrParI2) > 0) + IntLoc += 7 + return (TRUE) + else + return (FALSE) + +PUB Func3(EnumParIn) | EnumLoc + EnumLoc := EnumParIn + if (EnumLoc == Ident3) + return (TRUE) + return (FALSE) + +PUB strcpy(dst, src) + bytemove(dst, src, strsize(src) + 1) +{ + repeat strsize(src) + byte[dst++] := byte[src++] +} + +PUB memcpy(dst, src, num) + bytemove(dst, src, num) +{ + repeat num + byte[dst++] := byte[src++] +} + +PUB strcmp(str1, str2) + result := not strcomp(str1, str2) +{ + repeat while byte[str1] + if byte[str1] <> byte[str2] + quit + str1++ + str2++ + return byte[str1] - byte[str2] +} + +PUB time_msec + return cnt / (_clkfreq/1000) diff --git a/p1spin/p1spin.spin b/p1spin/p1spin.spin new file mode 100755 index 0000000..e016a3b --- /dev/null +++ b/p1spin/p1spin.spin @@ -0,0 +1,2069 @@ +'****************************************************************************** +' P1 Spin Interpreter for P2 +' +' Copyright (c) 2014, Dave Hein +' See end of file for terms of use. +'****************************************************************************** +CON + _clkmode = xtal1+pll16x + _clkfreq = 80_000_000 + +DAT + orgh $380 + org + + ' Add address offset to Spin header +startup mov temp1, ptestprog + add temp1, #6 + mov temp3, #5 +:loop rdword temp2, temp1 + add temp2, ptestprog + wrword temp2, temp1 + add temp1, #2 + djnz temp3, @:loop + + ' Clear VAR area + mov temp1, ptestprog + add temp1, #8 ' Get address of vbase + rdword temp2, temp1 ' Get vbase + add temp1, #2 ' Get address of dbase + rdword temp3, temp1 ' Get dbase + sub temp3, temp2 ' Compute number of bytes + shr temp3, #2 ' Compute number of longs + mov temp4, #0 +:loop1 wrlong temp4, temp2 + add temp2, #4 + djnz temp3, @:loop1 + + ' Initialize stack frame and result variable + mov temp1, ptestprog + add temp1, #10 ' Get address of dbase + rdword temp1, temp1 ' Get dbase + mov temp2, #0 + wrlong temp2, temp1 ' Initialize result to zero + sub temp1, #2 + wrword pexitcode, temp1 ' Set return address to exit code + sub temp1, #6 + mov temp2, #2 + wrword temp2, temp1 ' Write first word of stack frame + + ' Start the Spin interpreter + mov temp1, pinterp + mov temp2, ptestprog + add temp2, #4 + coginit temp1, temp2, #0 + +temp1 long 0 +temp2 long 0 +temp3 long 0 +temp4 long 0 +pinterp long @interp +ptestprog long @testprog +ppbase long @pbase +pexitcode long @exitcode + + orgh + +DAT + +' This table decodes the Spin bytecode. +jump_table +' 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F + word {00} ldfrmr, ldfrmr, ldfrmr, ldfrmr, _jmp, _call, callobj,callobx + word {08} _tjz, _djnz, _jz, _jnz, casedon,caseval,caseran,lookdon + word {10} lookupv,lookdnv,lookupr,lookdnr,_pop, _run, _strsiz,_strcmp + word {18} _bytefl,_wordfl,_longfl,_waitpe,_bytemv,_wordmv,_longmv,_waitpn + + word {20} _clkset,cogstp, lckret, _waitcn,rwregx, rwregx, rwregx, _waitvi + word {28} _cogini,lcknewr,lcksetr,lckclrr,_cogini,lcknew, lckset, lckclr + word {30} _abort, abrtval,_ret, retval, ldlix, ldlix, ldlix, ldlip + word {38} ldbi, ldwi, ldmi, ldli, unsupp, rwregb, rwregbs,rwreg + + word {40} ldlvc, stlvc, exlvc, lalvc, ldlvc, stlvc, exlvc, lalvc + word {48} ldlvc, stlvc, exlvc, lalvc, ldlvc, stlvc, exlvc, lalvc + word {50} ldlvc, stlvc, exlvc, lalvc, ldlvc, stlvc, exlvc, lalvc + word {58} ldlvc, stlvc, exlvc, lalvc, ldlvc, stlvc, exlvc, lalvc + + word {60} ldllc, stllc, exllc, lallc, ldllc, stllc, exllc, lallc + word {68} ldllc, stllc, exllc, lallc, ldllc, stllc, exllc, lallc + word {70} ldllc, stllc, exllc, lallc, ldllc, stllc, exllc, lallc + word {78} ldllc, stllc, exllc, lallc, ldllc, stllc, exllc, lallc + + word {80} ldba, stba, exba, la_a, ldbo, stbo, exbo, la_o + word {88} ldbv, stbv, exbv, la_v, ldbl, stbl, exwl, la_l + word {90} ldbax, stbax, exbax, labax, ldbox, stbox, exbox, labox + word {98} ldbvx, stbvx, exbvx, labvx, ldblx, stblx, exblx, lablx + + word {A0} ldwa, stwa, exwa, la_a, ldwo, stwo, exwo, la_o + word {A8} ldwv, stwv, exwv, la_v, ldwl, stwl, exwl, la_l + word {B0} ldwax, stwax, exwax, lawax, ldwox, stwox, exwox, lawox + word {B8} ldwvx, stwvx, exwvx, lawvx, ldwlx, stwlx, exwlx, lawlx + + word {C0} ldla, stla, exla, la_a, ldlo, stlo, exlo, la_o + word {C8} ldlv, stlv, exlv, la_v, ldll, stll, exll, la_l + word {D0} ldlax, stlax, exlax, lalax, ldlox, stlox, exlox, lalox + word {D8} ldlvx, stlvx, exlvx, lalvx, ldllx, stllx, exllx, lallx + + word {E0} _ror, _rol, _shr, _shl, _min, _max, _neg, _com + word {E8} _and, _abs, _or, _xor, _add, _sub, _sar, _rev + word {F0} _andl, encode, _orl, decode, _mul, _mulh, _div, _mod + word {F8} _sqrt, _cmplt, _cmpgt, _cmpne, _cmpeq, _cmple, _cmpge, _notl + +' This table decodes the extra byte that is used to perform extended operations. +jump_table_ex +' 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F + word {00} store, unsupx, repeatx,unsupx, unsupx, unsupx, repeats,unsupx + word {08} randf, unsupx, unsupx, unsupx, randr, unsupx, unsupx, unsupx + word {10} sexb, unsupx, unsupx, unsupx, sexw, unsupx, unsupx, unsupx + word {18} postclr,unsupx, unsupx, unsupx, postset,unsupx, unsupx, unsupx + + word {20} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, preinc, unsupx + word {28} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, postinc,unsupx + word {30} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, predec, unsupx + word {38} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, postdec,unsupx + + word {40} _rorx, _rolx, _shrx, _shlx, _minx, _maxx, _negx, _comx + word {48} _andx, _absx, _orx, _xorx, _addx, _subx, _sarx, _revx + word {50} _andlx, encodex,_orlx, decodex,_mulx, _mulhx, _divx, _modx + word {58} _sqrtx, _cmpltx,_cmpgtx,_cmpnex,_cmpeqx,_cmplex,_cmpgex,_notlx + + word {60} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx + word {68} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx + word {70} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx + word {78} unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx, unsupx + + ' Bytecodes for cogstop(cogid) +exitcode byte $3f, $89, $21 + + org 0 + +'*********************************************************************** +' Copy 5 Spin state variable to registers +'*********************************************************************** +interp setinda #pbase + reps #5, #1 + cogid id + rdword inda++,++ptra + jmp #loop + long 0[3] + +'*********************************************************************** +' Push x to the stack +'*********************************************************************** +pushx1 wrlong x, dcurr + add dcurr, #4 + +'*********************************************************************** +' This is the main loop that fetches bytecodes and executes them +'*********************************************************************** +loop mov t1, jumps + rdbyte op,pcurr 'get opcode + add pcurr,#1 + add t1, op + add t1, op + rdword t2, t1 + jmp t2 + +'*********************************************************************** +' This code handles extended operators, such as ++ and += +'*********************************************************************** +exoplong add adr, op2 +exoplong1 rdlong x, adr + mov savex, #exoplong2 + jmp #exop1 + +exopword add adr, op2 +exopword1 rdword x, adr + mov savex, #exopword2 + jmp #exop1 + +exopbyte add adr, op2 +exopbyte1 rdbyte x, adr + mov savex, #exopbyte2 + +exop1 rdbyte op2,pcurr + mov t1, op2 + and t1, #$7f + shl t1, #1 + add t1, jumpx + rdword t2, t1 + add pcurr,#1 + jmp t2 + +'*********************************************************************** +' This code saves the result from the extended operation +'*********************************************************************** +postsave add savex, #1 + jmp savex + +exopbyte2 mov y, x +postbyte wrbyte y, adr + and x, #$ff + jmp #exopdone + +exopword2 mov y, x +postword wrword y, adr + and x, maskword + jmp #exopdone + +exoplong2 mov y, x +postlong wrlong y, adr + +exopdone test op2, #$80 wc 'check for load bit + mov savex, #pushx1 + if_c jmp #pushx1 + if_nc jmp #loop + +'*********************************************************************** +' Load Immediate Instructions +'*********************************************************************** +' +' Load Long Immediate 1, 0 and -1 +ldlix sub op, #$35 + mov x, op + jmp #pushx1 + +' Load Long Immediate Packed +ldlip mov x, #2 + rdbyte y,pcurr 'constant mask, get data byte + add pcurr,#1 + rol x,y 'decode, x = 2 before + test y,#%001_00000 wc 'decrement? + if_c sub x,#1 + test y,#%010_00000 wc 'not? + if_c xor x,masklong + jmp #pushx1 + +' Load Byte Immediate +ldbi call #fetchbyte + jmp #pushx1 + +' Load Word Immediate +ldli call #fetchbyte + mov a, #3 + jmp #addbytes + +' Load Word Immediate +ldmi call #fetchbyte + mov a, #2 + jmp #addbytes + +' Load Word Immediate +ldwi call #fetchbyte + mov a, #1 + +addbytes shl x, #8 + rdbyte y, pcurr + add pcurr, #1 + or x, y + djnz a, @addbytes + jmp #pushx1 + +'*********************************************************************** +' Compact Local Variable Instructions +'*********************************************************************** +' Load Long Local Compact +ldllc mov op2, dbase + mov adr, op + and adr, #$1c + +ldlong add adr, op2 + rdlong x, adr + jmp #pushx1 + +' Store Long Local Compact +stllc mov adr, op + and adr, #$1c + mov op2, dbase + +stlong add adr, op2 + call #popx1 + wrlong x, adr + jmp #loop + +' Execute Long Local Compact +exllc mov adr, op + and adr, #$1c + mov op2, dbase + jmp #exoplong + +' Load Address Long Local Compact +lallc and op, #$1c + add op, dbase + mov x, op + jmp #pushx1 + +'*********************************************************************** +' DAT Variable Instructions +'*********************************************************************** + +' Load Long Object +ldlo call #getadrz + mov adr, pbase + jmp #ldlong + +' Store Long Object +stlo call #getadrz + mov adr, pbase + jmp #stlong + +' Execute Long Object +exlo call #getadrz + mov adr, pbase + jmp #exoplong + +' Load Address Object +la_o call #getadrz + mov x, op2 + add x, pbase + jmp #pushx1 + +'*********************************************************************** +' Indexed DAT Variable Instructions +'*********************************************************************** + +' Load Byte Object with Index +ldbox call #getadrz + call #pop_adr + add adr, pbase + jmp #ldbyte + +ldbyte add adr, op2 + rdbyte x, adr + jmp #pushx1 + +ldword add adr, op2 + rdword x, adr + jmp #pushx1 + +' Store Byte Object with Index +stbox call #getadrz + call #pop_adr + add adr, pbase + jmp #stbyte + +stbyte add adr, op2 + call #popx1 + wrbyte x, adr + jmp #loop + +stword add adr, op2 + call #popx1 + wrword x, adr + jmp #loop + +' Load Address Byte Object with Index +labox call #getadrz + call #popx1 + add x, op2 + add x, pbase + jmp #pushx1 + +'*********************************************************************** +' Absolute Address Instructions +'*********************************************************************** + +' Load Byte Absolute +ldba call #popy1 + jmp #ldba1 + +' Load Word Absolute +ldwa call #popy1 + jmp #ldwa1 + +' Load Long Absolute +ldla call #popy1 + if_z jmp #ldclkfreq + jmp #ldla1 + +ldbax call #popay + add y, a +ldba1 rdbyte x, y + jmp #pushx1 + +' Load Word Absolute with Index +ldwax call #popay + shl a, #1 + add y, a +ldwa1 rdword x, y + jmp #pushx1 + +' Load Long Absolute with Index +ldlax call #popay + shl a, #2 + add y, a +ldla1 rdlong x, y + jmp #pushx1 + +'*********************************************************************** +' Jump Instructions +'*********************************************************************** + +' Test and Jump on Zero +_tjz call #getadrs + call #popx1 + if_nz add dcurr, #4 + jmp #_jz1 + +' Jump on Zero +_jz call #getadrs + call #popx1 +_jz1 if_z add pcurr, op2 + jmp #loop + +' Decrement and Jump on NonZero +_djnz call #getadrs + call #popx1 + sub x, #1 wz + if_nz add pcurr, op2 + if_nz jmp #pushx1 + jmp #loop + +' Jump on NonZero +_jnz call #getadrs + call #popx1 + if_nz add pcurr, op2 + jmp #loop + +' Jump +_jmp call #getadrs + add pcurr, op2 + jmp #loop + +'*********************************************************************** +' Math Instructions +'*********************************************************************** +_shr call #popyx + shr x, y + jmp savex + +_shl call #popyx + shl x, y + jmp savex + +_ror call #popyx + rol x, y + jmp savex + +_rol call #popyx + rol x, y + jmp savex + +' Complement +_com call #popx1 + xor x, masklong + jmp savex + +_and call #popyx + and x, y + jmp savex + +' Absolute +_abs call #popx1 + abs x, x + jmp savex + +_or call #popyx + or x, y + jmp savex + +' Add +_add call #popyx + add x, y + jmp savex + +' Subtract +_sub call #popyx + sub x, y + jmp savex + +_neg call #popx1 + neg x, x + jmp savex + +_xor call #popyx + xor x, y + jmp savex + +_sar call #popyx + sar x, y + jmp savex + +' Or Logical +_orl call #popx1 + if_nz neg x, #1 + call #popy1 + if_nz neg x, #1 + jmp savex + +_andl call #popx1 + if_nz neg x, #1 + call #popy1 + if_z mov x, #0 + jmp savex + +_notl call #popx1 + muxz x, masklong + jmp savex + +_mul call #popyx + mul32 x, y + getmull x + jmp savex + +_mulh call #popyx + mul32 x, y + getmulh x + jmp savex + +_div call #popyx + div32 x, y + getdivq x + jmp savex + +_mod call #popyx + div32 x, y + getdivr x + jmp savex + +' Compare if Less Than +_cmplt call #popyx + cmps x, y wz, wc + muxc x, masklong + jmp savex + +' Compare if Greater Than +_cmpgt call #popyx + cmps x, y wz, wc + if_nz_and_nc neg x, #1 + if_z_or_c mov x, #0 + jmp savex + +' Compare if Less than or Equal +_cmple call #popyx + cmps x, y wz, wc + if_nz_and_nc mov x, #0 + if_z_or_c neg x, #1 + jmp savex + +' Compare if Not Equal +_cmpne call #popyx + sub x, y wz + if_nz neg x, #1 + jmp savex + + +' Compare if Equal +_cmpeq call #popyx + sub x, y wz + jmp #_notlx + +' Compare if Greater than or Equal +_cmpge call #popyx + cmps x, y wz, wc + muxnc x, masklong + jmp savex + +retval call #popx1 + jmp #_ret1 +_ret rdlong x,dbase +_ret1 call #return1 +pushz if_z jmp #pushx1 + if_nz jmp #loop + +'*********************************************************************** +' Calling and Return Instructions +'*********************************************************************** +return1 mov dcurr,dbase 'restore dcurr + sub dcurr,#2 'pop pcurr + rdword pcurr,dcurr + sub dcurr,#2 'pop dbase + rdword dbase,dcurr + sub dcurr,#2 'pop vbase + rdword vbase,dcurr + sub dcurr,#2 'pop pbase (and flags) + rdword pbase,dcurr + test pbase,#%01 wz 'get push flag + test pbase,#%10 wc 'get abort flag + and pbase,maskpar 'trim pbase + ret + +' Load Stack Frame +ldfrmr +ldfrm +ldfrmar +ldfrma jmp #loadframe + +callobj mov a, #0 +callobj1 call #getcallparms + add pbase, x + add vbase, y + +_call mov a, #0 + call #getcallparms + jmp #callmethod + +' Read values from the Method Table +getcallparms rdbyte y,pcurr 'get method table entry number + add pcurr,#1 + add y,a 'add index + shl y,#2 'lookup words from table + add y,pbase + rdlong y,y + mov x,y 'get low word + and x,maskword + shr y,#16 'get high word + ret + +' Call Method +callmethod mov dbase,dcall 'get new dcall + rdword dcall,dcall 'set old dcall + wrword pcurr,dbase 'set return pcurr + add dbase,#2 'set call dbase + add dcurr,y 'set call dcurr + mov pcurr,pbase 'set call pcurr + add pcurr,x + jmp #loop + +loadframe or op,pbase 'add pbase into flags + wrword op,dcurr 'push pbase plus flags + add dcurr,#2 + wrword vbase,dcurr 'push vbase + add dcurr,#2 + wrword dbase,dcurr 'push dbase + add dcurr,#2 + wrword dcall,dcurr 'push dcall + mov dcall,dcurr 'set new dcall + add dcurr,#2 + mov x, #0 'init result to 0 + jmp #pushx1 + +_cogini1 coginit y, a, #0 + jmp #pushz + +'*********************************************************************** +' Helper Functions +'*********************************************************************** +' Get Unsigned Address +getadrz rdbyte op2,pcurr + test op2,#$80 wc + and op2,#$7F + jmp #getadr2 +' Get Signed Address +getadrs rdbyte op2,pcurr + test op2,#$80 wc + shl op2,#25 + sar op2,#25 +getadr2 add pcurr,#1 + if_nc ret + rdbyte t2,pcurr + add pcurr,#1 + shl op2,#8 + or op2,t2 + ret + +' Fetch a bytecode +fetchbyte rdbyte x, pcurr + add pcurr, #1 + ret + +' Pop a from the stack +popayx sub dcurr,#4 + rdlong a,dcurr + +' Pop y from the stack +popyx sub dcurr,#4 + rdlong y,dcurr + +' Pop x from the stack +popx1 sub dcurr,#4 + rdlong x,dcurr wz + ret + +' Pop a from the stack +popay sub dcurr,#4 + rdlong a,dcurr + +' Pop y from the stack +popy1 sub dcurr, #4 + rdlong y, dcurr wz + ret + +' Pop adr from the stack +pop_adr sub dcurr,#4 + rdlong adr,dcurr + ret + +'*********************************************************************** +' Extended Instructions +'*********************************************************************** +store call #popx1 + jmp savex + +postclr mov y, #0 + jmp #postsave + +postset neg y, #1 + jmp #postsave + +postinc mov y, x + add y, #1 + jmp #postsave + +postdec mov y, x + sub y, #1 + jmp #postsave + +_rolx call #popy1 + rol x, y + jmp savex + +_shlx call #popy1 + shl x, y + jmp savex + +_divx call #popy1 + jmp #_div+1 + +_modx call #popy1 + jmp #_mod+1 + +_notlx muxz x, masklong + jmp savex + +_rorx call #popy1 + ror x, y + jmp savex + +_shrx call #popy1 + shr x, y + jmp savex + +_andx call #popy1 + and x, y + jmp savex + +_absx abs x, x + jmp savex + +_negx neg x, x + jmp savex + +_comx xor x, masklong + jmp savex + +_orx call #popy1 + or x, y + jmp savex + +'*********************************************************************** +' Read/Write Register Instructions +'*********************************************************************** +rwreg0 rdbyte op, pcurr + add pcurr, #1 + mov adr, op +rwreg1 and adr, #$1f + add adr, #$1e0 + call #mapreg + mov regrevflag, #0 + mov reglsb, t1 + mov regnbits, t2 + sub regnbits,reglsb wc + if_c neg regnbits, regnbits + if_c mov reglsb, t2 + if_c mov regrevflag, #1 + xor regnbits, #31 + neg regmask, #1 + shr regmask, regnbits + test op, #$20 wz + if_z jmp #ldreg + +streg sets streg1, adr + setd streg2, adr + call #popx1 + and x, regmask + cmp regrevflag, #0 wz + if_nz rev x, regnbits + shl regmask, reglsb +streg1 mov y, 0-0 + andn y, regmask + shl x, reglsb + or y, x +streg2 mov 0-0, y + jmp #loop + +ldreg sets ldreg1, adr + nop + cmp adr, #$1f1 wz + if_z getcnt x +ldreg1 if_nz mov x, 0-0 + mov regsave, x + shr x, reglsb + and x, regmask + cmp regrevflag, #0 wz + if_nz rev x, regnbits + test op, #$40 wz + if_z jmp #pushx1 + mov savex, #exopreg2 + jmp #exop1 + +exopreg2 mov y, x +postreg setd exopreg3, adr + and x, regmask + and y, regmask + cmp regrevflag, #0 wz + if_nz rev y, regnbits + shl y, reglsb + shl regmask, reglsb + andn regsave, regmask + or y, regsave +exopreg3 mov 0-0, y + jmp #exopdone + + ' Mapping for port A +mapreg cmp adr, #$1f2 wz 'P1 INA + if_z mov adr, #$1f4 'P2 PINA + if_z ret + cmp adr, #$1f4 wz 'P1 OUTA + if_z mov adr, #$1f8 'P2 OUTA + if_z ret + cmp adr, #$1f6 wz 'P1 DIRA + if_z mov adr, #$1fc 'P2 DIRA + ret +{ + ' Mapping for port C +mapreg cmp adr, #$1f2 wz 'P1 INA + if_z mov adr, #$1f6 'P2 PINC + if_z ret + cmp adr, #$1f4 wz 'P1 OUTA + if_z mov adr, #$1fa 'P2 OUTC + if_z ret + cmp adr, #$1f6 wz 'P1 DIRA + if_z mov adr, #$1fe 'P2 DIRC + ret +} +regrevflag long 0 +reglsb long 0 +regmask long 0 +regnbits long 0 +regsave long 0 + +'*********************************************************************** +' Constants and Variables +'*********************************************************************** +bitcycles long 80000000 / 115200 +jumps long @jump_table +jumpx long @jump_table_ex +savex long pushx1 +masklong long $FFFFFFFF +maskword long $FFFF +maskpar long $0000FFFC + fit $1E9 + + org $1E9 +id res 1 +dcall res 1 +pbase res 1 +vbase res 1 +dbase res 1 +pcurr res 1 +dcurr res 1 + + fit $1F0 + + org 0 +x res 1 +y res 1 +a res 1 +t1 res 1 +t2 res 1 +op res 1 +op2 res 1 +adr res 1 + +'*********************************************************************** +' These instructions execute from hub memory +'*********************************************************************** + orgh + +' casedone +casedon sub dcurr, #8 + rdlong pcurr, dcurr + add pcurr, pbase + jmp #loop + +' casevalue +caseval call #getadrs + call #popyx + add dcurr, #4 + cmp x, y wz + if_z add pcurr, op2 + jmp #loop + +' caserange +caseran call #getadrs + call #popayx + add dcurr, #4 + cmps a, y wz, wc + if_nz_and_nc jmp #caseran1 + cmps a, x wz, wc + if_nz_and_nc jmp #loop + cmps x, y wz, wc + if_nz_and_nc jmp #loop + add pcurr, op2 + jmp #loop +caseran1 cmps y, x wz, wc + if_nz_and_nc jmp #loop + cmps x, a wz, wc + if_nz_and_nc jmp #loop + add pcurr, op2 + jmp #loop + +' lookdone +lookdon sub dcurr, #12 + mov x, #0 + jmp #pushx1 + +' lookupval +lookupv call #pop_adr + call #popayx + add dcurr, #12 + cmps a, x wz, wc + if_c jmp #lookupv1 + if_z jmp #lookupv2 + add x, #1 + sub dcurr, #12 + wrlong x, dcurr + add dcurr, #12 + jmp #loop +lookupv1 mov pcurr, y + add pcurr, pbase + sub dcurr, #12 + mov x, #0 + jmp #pushx1 +lookupv2 mov pcurr, y + add pcurr, pbase + sub dcurr, #12 + mov x, adr + jmp #pushx1 +' lookdnval +lookdnv call #popyx + add dcurr, #4 + cmp x, y wz + if_nz jmp #lookdnv1 + sub dcurr, #8 + rdlong pcurr, dcurr + add pcurr, pbase + jmp #loop +lookdnv1 sub dcurr, #12 + rdlong x, dcurr + add x, #1 + wrlong x, dcurr + add dcurr, #12 + jmp #loop + +' lookuprange +lookupr call #popyx + mov t1, y + mov t2, x + call #popayx + add dcurr, #12 + mov adr, t1 + sub adr, t2 + abs adr, adr + sub a, x wc + if_c jmp #lookupr1 + cmp a, adr wc, wz + if_c_or_z jmp #lookupr2 + add x, adr + add x, #1 + sub dcurr, #12 + wrlong x, dcurr + add dcurr, #12 + jmp #loop +lookupr1 sub dcurr, #12 + mov pcurr, y + add pcurr, pbase + mov x, #0 + jmp #pushx1 +lookupr2 sub dcurr, #12 + mov pcurr, y + add pcurr, pbase + cmp t2, t1 wc, wz + mov x, t2 + if_c_or_z add x, a + if_nc_and_nz sub x, a + jmp #pushx1 + +' lookdnrange +lookdnr call #popayx + add dcurr, #4 + mov t1, a + mov t2, y + max t1, y ' Get minimum + min t2, a ' Get maximum + cmps x, t1 wc + if_c jmp #lookdnr1 + cmps t2, x wc + if_c jmp #lookdnr1 + sub dcurr, #8 + rdlong pcurr, dcurr + add pcurr, pbase + call #pop_adr + cmps y, a wc + sub x, y + if_nc neg x, x + add x, adr + jmp #pushx1 +lookdnr1 sub dcurr, #12 + rdlong x, dcurr + add x, #1 + add x, t2 + sub x, t1 + wrlong x, dcurr + add dcurr, #12 + jmp #loop + +_waitcn call #popx1 + waitcnt x, #0 + jmp #loop + +_waitpe call #popayx + test a, #1 wz + getcnt t1 + ' Port A and B +:loop if_nz waitpeq x, y, #1 wc + if_z waitpeq x, y, #0 wc +{ + ' Port C and D +:loop if_nz waitpeq x, y, #3 wc + if_z waitpeq x, y, #2 wc +} + if_c jmp #:loop + jmp #loop + +_waitpn call #popayx + test a, #1 wz + getcnt t1 +:loop if_z waitpne x, y, #1 wc + if_nz waitpne x, y, #0 wc + if_c jmp #:loop + jmp #loop + +cogstp call #popx1 + cogstop x + jmp #loop + +_cogini call #popayx 'coginit, pop parameters + test x, #8 wc + and x, #7 + setnib _cogini1, x, #6 + test op,#%100 wz 'push result? + if_nc jmp #_cogini1 + cognew y, a wc + if_c neg x, #1 '-1 if c, else 0..7 + if_nc mov x, y '-1 if c, else 0..7 + jmp #pushz + +callobx call #popx1 + mov a, x + jmp #callobj1 + +_pop call #popx1 + sub dcurr, x + jmp #loop + +abrtval call #popx1 + jmp #_abort1 +_abort rdlong x,dbase +_abort1 call #return1 + if_nc jmp #_abort1 + jmp #pushz + +rwreg mov t2, #31 + mov t1, #0 + jmp #rwreg0 + +rwregb call #popx1 + and x, #31 + mov t2, x + mov t1, x + jmp #rwreg0 + +rwregbs call #popyx + and x, #31 + and y, #31 + mov t2, x + mov t1, y + jmp #rwreg0 + +rwregx call #pop_adr + or adr, #$10 + shl op, #5 + jmp #rwreg1 + +'*********************************************************************** +' Prepare to start a Spin cog +'*********************************************************************** + 'run(metindex, stackaddr) +_run call #popyx + + 'stackptr := (metindex >> 8) << 2 + mov adr, x + shr adr, #8 + shl adr, #2 wz + + 'metindex := ((metindex & 255) << 2) + PBASE + and x, #255 + shl x, #2 + add x, pbase + + 'skip bytemove if no parms + if_z jmp #_run1 + + 't2 := stackaddr + 12 + mov t2, y + add t2, #12 + + 't1 := DCURR - stackptr + mov t1, dcurr + sub t1, adr + + 'a := stackptr + mov a, adr + + 'bytemove(t2, t1, a) +:loop rdbyte op2, t1 + add t1, #1 + wrbyte op2, t2 + add t2, #1 + djnz a, @:loop + + 'pop(stackptr) + sub dcurr, adr + + 'long[stackaddr] := -1 +_run1 neg t1, #1 + wrlong t1, y + add y, #4 + + 'long[stackaddr][1] := (@exitcode << 16) + mov t1, ##@exitcode + shl t1, #16 + wrlong t1, y + add y, #4 + + 'word[stackaddr][2] := 0 + mov t1, #0 + wrlong t1, y + + 'stackptr += stackaddr + 12 + add adr, y + add adr, #4 + + 'word[stackptr][1] := pbase + add adr, #2 + wrword pbase, adr + + 'word[stackptr][2] := vbase + add adr, #2 + wrword vbase, adr + + 'word[stackptr][3] := stackaddr + 8 + add adr, #2 + wrword y, adr + + 'word[stackptr][4] := word[metindex] + PBASE + add adr, #2 + rdword t1, x + add t1, pbase + wrword t1, adr + + 'word[stackptr][5] := word[metindex][1] + stackptr + add adr, #2 + add x, #2 + rdword t1, x + add t1, adr + sub t1, #10 + wrword t1, adr + sub adr, #10 + + '(-1, @interp, stackptr) + neg t1, #1 + wrlong t1, dcurr + add dcurr, #4 + mov t1, ##@interp + wrlong t1, dcurr + add dcurr, #4 + wrlong adr, dcurr + add dcurr, #4 + + jmp #loop + +'*********************************************************************** +' String, Block Move and Block Fill Instructions +'*********************************************************************** +' strsize +_strsiz call #popx1 + mov y, x +:loop rdbyte a, x wz + if_nz add x, #1 + if_nz jmp #:loop + sub x, y + jmp #pushx1 + +' strcomp +_strcmp call #popyx +:loop rdbyte t1, x wz + add x, #1 + if_z jmp #_strcmp1 + rdbyte t2, y wz + add y, #1 + if_z jmp #_strcmp2 + cmp t1, t2 wz + if_z jmp #:loop +_strcmp2 mov x, #0 + jmp #pushx1 +_strcmp1 rdbyte t2, y wz + jmp #_notlx + +' longfill +_longfl call #popayx +:loop wrlong y, x + add x, #4 + djnz a, @:loop + jmp #loop + +' wordfill +_wordfl call #popayx +:loop wrword y, x + add x, #2 + djnz a, @:loop + jmp #loop + +' bytefill +_bytefl call #popayx +:loop wrbyte y, x + add x, #1 + djnz a, @:loop + jmp #loop + +' longmove +_longmv call #popayx +:loop rdlong t1, y + add y, #4 + wrlong t1, x + add x, #4 + djnz a, @:loop + jmp #loop + +' wordmove +_wordmv call #popayx +:loop rdword t1, y + add y, #2 + wrword t1, x + add x, #2 + djnz a, @:loop + jmp #loop + +' bytemove +_bytemv call #popayx +:loop rdbyte t1, y + add y, #1 + wrbyte t1, x + add x, #1 + djnz a, @:loop + jmp #loop + +'*********************************************************************** +' Lock instructions +'*********************************************************************** +lcknewr locknew x wc + if_c neg x, #1 + jmp #pushx1 + +lcksetr call #popx1 + lockset x wc + if_c neg x, #1 + if_nc mov x, #0 + jmp #pushx1 + +lckclrr call #popx1 + lockclr x wc + if_c neg x, #1 + if_nc mov x, #0 + jmp #pushx1 + +lcknew locknew x + jmp #loop + +lckset call #popx1 + lockset x + jmp #loop + +lckclr call #popx1 + lockclr x + jmp #loop + +lckret call #popx1 + lockret x + jmp #loop + +'*********************************************************************** +' Local Variable Instructions +'*********************************************************************** + +' Load Long Var +ldll call #getadrz + mov adr, dbase + jmp #ldlong + +' Store Long Var +stll call #getadrz + mov adr, dbase + jmp #stlong + +' Execute Long Var +exll call #getadrz + mov adr, dbase + jmp #exoplong + +' Load Address Var +la_l call #getadrz + mov x, op2 + add x, dbase + jmp #pushx1 + +' Load Word Var +ldwl call #getadrz + mov adr, dbase + jmp #ldword + +' Store Word Var +stwl call #getadrz + mov adr, dbase + jmp #stword + +' Execute Word Var +exwl call #getadrz + mov adr, dbase + jmp #exopword + +' Load Byte Var +ldbl call #getadrz + mov adr, dbase + jmp #ldbyte + +' Store Byte Var +stbl call #getadrz + mov adr, dbase + jmp #stbyte + +' Execute Byte Var +exbl call #getadrz + mov adr, dbase + jmp #exopbyte + +'*********************************************************************** +' Compact VAR Variable Instructions +'*********************************************************************** +' Load Long Local Compact +ldlvc mov op2, vbase + mov adr, op + and adr, #$1c + jmp #ldlong + +' Store Long Local Compact +stlvc mov adr, op + and adr, #$1c + mov op2, vbase + jmp #stlong + +' Execute Long Local Compact +exlvc mov adr, op + and adr, #$1c + mov op2, vbase + jmp #exoplong + +' Load Address Long Local Compact +lalvc and op, #$1c + add op, vbase + mov x, op + jmp #pushx1 + +'*********************************************************************** +' VAR Variable Instructions +'*********************************************************************** + +' Load Long Var +ldlv call #getadrz + mov adr, vbase + jmp #ldlong + +' Store Long Var +stlv call #getadrz + mov adr, vbase + jmp #stlong + +' Load Word Var +ldwv call #getadrz + mov adr, vbase + jmp #ldword + +' Store Word Var +stwv call #getadrz + mov adr, vbase + jmp #stword + +' Load Byte Var +ldbv call #getadrz + mov adr, vbase + jmp #ldbyte + +' Store Byte Var +stbv call #getadrz + mov adr, vbase + jmp #stbyte + +' Execute Long Var +exlv call #getadrz + mov adr, vbase + jmp #exoplong + +' Execute Word Var +exwv call #getadrz + mov adr, vbase + jmp #exopword + +' Execute Byte Var +exbv call #getadrz + mov adr, vbase + jmp #exopbyte + +' Load Address Var +la_v call #getadrz + mov x, op2 + add x, vbase + jmp #pushx1 + +'*********************************************************************** +' Indexed Local Variable Instructions +'*********************************************************************** + +' Load Long Local with Index +ldllx call #getadrz + call #pop_adr + shl adr, #2 + add adr, dbase + jmp #ldlong + +' Store Long Local with Index +stllx call #getadrz + call #pop_adr + shl adr, #2 + add adr, dbase + jmp #stlong + +' Execute Long Local with Index +exllx call #getadrz + call #pop_adr + shl adr, #2 + add adr, dbase + jmp #exoplong + +' Load Address Long Local with Index +lallx call #getadrz + call #popx1 + shl x, #2 + add x, op2 + add x, dbase + jmp #pushx1 + +' Load Word Local with Index +ldwlx call #getadrz + call #pop_adr + shl adr, #1 + add adr, dbase + jmp #ldword + +' Store Word Local with Index +stwlx call #getadrz + call #pop_adr + shl adr, #1 + add adr, dbase + jmp #stword + +' Execute Word Local with Index +exwlx call #getadrz + call #pop_adr + shl adr, #1 + add adr, dbase + jmp #exopword + +' Load Address Word Local with Index +lawlx call #getadrz + call #popx1 + shl x, #1 + add x, op2 + add x, dbase + jmp #pushx1 + +' Load Byte Local with Index +ldblx call #getadrz + call #pop_adr + add adr, dbase + jmp #ldbyte + +' Store Byte Local with Index +stblx call #getadrz + call #pop_adr + add adr, dbase + jmp #stbyte + +' Execute Byte Local with Index +exblx call #getadrz + call #pop_adr + add adr, dbase + jmp #exopbyte + +' Load Address Byte Local with Index +lablx call #getadrz + call #popx1 + add x, op2 + add x, dbase + jmp #pushx1 + +'*********************************************************************** +' Indexed VAR Variable Instructions +'*********************************************************************** + +' Load Long VAR with Index +ldlvx call #getadrz + call #pop_adr + shl adr, #2 + add adr, vbase + jmp #ldlong + +' Store Long VAR with Index +stlvx call #getadrz + call #pop_adr + shl adr, #2 + add adr, vbase + jmp #stlong + +' Execute Long VAR with Index +exlvx call #getadrz + call #pop_adr + shl adr, #2 + add adr, vbase + jmp #exoplong + +' Load Address Long VAR with Index +lalvx call #getadrz + call #popx1 + shl x, #2 + add x, op2 + add x, vbase + jmp #pushx1 + +' Load Word VAR with Index +ldwvx call #getadrz + call #pop_adr + shl adr, #1 + add adr, vbase + jmp #ldword + +' Store Word VAR with Index +stwvx call #getadrz + call #pop_adr + shl adr, #1 + add adr, vbase + jmp #stword + +' Execute Word VAR with Index +exwvx call #getadrz + call #pop_adr + shl adr, #1 + add adr, vbase + jmp #exopword + +' Load Address Word VAR with Index +lawvx call #getadrz + call #popx1 + shl x, #1 + add x, op2 + add x, vbase + jmp #pushx1 + +' Load Byte VAR with Index +ldbvx call #getadrz + call #pop_adr + add adr, vbase + jmp #ldbyte + +' Store Byte VAR with Index +stbvx call #getadrz + call #pop_adr + add adr, vbase + jmp #stbyte + +' Execute Byte VAR with Index +exbvx call #getadrz + call #pop_adr + add adr, vbase + jmp #exopbyte + +' Load Address Byte VAR with Index +labvx call #getadrz + call #popx1 + add x, op2 + add x, vbase + jmp #pushx1 + +'*********************************************************************** +' DAT Variable Instructions +'*********************************************************************** + +' Load Word Object +ldwo call #getadrz + mov adr, pbase + jmp #ldword + +' Store Word Object +stwo call #getadrz + mov adr, pbase + jmp #stword + +' Execute Word Object +exwo call #getadrz + mov adr, pbase + jmp #exopword + +' Load Byte Object +ldbo call #getadrz + mov adr, pbase + jmp #ldbyte + +' Store Byte Object +stbo call #getadrz + mov adr, pbase + jmp #stbyte + +' Execute Byte Object +exbo call #getadrz + mov adr, pbase + jmp #exopbyte + +'*********************************************************************** +' Indexed DAT Variable Instructions +'*********************************************************************** + +' Load Long Object with Index +ldlox call #getadrz + call #pop_adr + shl adr, #2 + add adr, pbase + jmp #ldlong + +' Store Long Object with Index +stlox call #getadrz + call #pop_adr + shl adr, #2 + add adr, pbase + jmp #stlong + +' Execute Long Object with Index +exlox call #getadrz + call #pop_adr + shl adr, #2 + add adr, pbase + jmp #exoplong + +' Load Address Long Object with Index +lalox call #getadrz + call #popx1 + shl x, #2 + add x, op2 + add x, pbase + jmp #pushx1 + +' Load Word Object with Index +ldwox call #getadrz + call #pop_adr + shl adr, #1 + add adr, pbase + jmp #ldword + +' Store Word Object with Index +stwox call #getadrz + call #pop_adr + shl adr, #1 + add adr, pbase + jmp #stword + +' Execute Word Object with Index +exwox call #getadrz + call #pop_adr + shl adr, #1 + add adr, pbase + jmp #exopword + +' Load Address Word Object with Index +lawox call #getadrz + call #popx1 + shl x, #1 + add x, op2 + add x, pbase + jmp #pushx1 + +' Execute Byte Object with Index +exbox call #getadrz + call #pop_adr + add adr, pbase + jmp #exopbyte + +'*********************************************************************** +' Absolute Address Instructions +'*********************************************************************** + +' Store Byte Absolute +stba call #popyx + jmp #stba1 + +' Store Word Absolute +stwa call #popyx + jmp #stwa1 + +' Store Long Absolute +stla call #popyx + jmp #stla1 + +' Execute Long Absolute +exla sub dcurr, #4 + rdlong adr, dcurr + jmp #exoplong1 + +' Execute Word Absolute +exwa sub dcurr, #4 + rdlong adr, dcurr + jmp #exopword1 + +' Execute Byte Absolute +exba sub dcurr, #4 + rdlong adr, dcurr + jmp #exopbyte1 + +' Load Address Absolute (NOP) +la_a jmp #loop + +'*********************************************************************** +' Absolute Address with Index Instructions +'*********************************************************************** +' Load Byte Absolute with Index +' Store Byte Absolute with Index +stbax call #popayx + add y, a +stba1 wrbyte x, y + jmp #loop + +' Store Word Absolute with Index +stwax call #popayx + shl a, #1 + add y, a +stwa1 wrword x, y + jmp #loop + +' Store Long Absolute with Index +stlax call #popayx + shl a, #2 + add y, a +stla1 wrlong x, y + jmp #loop + +' Execute Long Absolute with Index +exlax call #popay + shl a, #2 + mov adr, y + add adr, a + jmp #exoplong1 + +' Load Address Long Absolute with Index +lalax call #popyx + shl y, #2 + add x, y + jmp #pushx1 + +' Execute Word Absolute with Index +exwax call #popay + shl a, #1 + mov adr, y + add adr, a + jmp #exopword1 + +' Load Address Word Absolute with Index +lawax call #popyx + shl y, #1 + add x, y + jmp #pushx1 + +' Execute Word Absolute with Index +exbax call #popay + mov adr, y + add adr, a + jmp #exopbyte1 + +' Load Address Byte Absolute with Index +labax call #popyx + add x, y + jmp #pushx1 + +'*********************************************************************** +' Extended Instructions +'*********************************************************************** + +sexb shl x, #24 + sar x, #24 + jmp savex + +sexw shl x, #16 + sar x, #16 + jmp savex + +preinc add x, #1 + jmp savex + +predec sub x, #1 + jmp savex + +' Repeat-from-to-step Instruction +repeats call #popay + sub dcurr, #4 + rdlong t1, dcurr + jmp #repeaty + +' Repeat-from-to Instruction +repeatx + call #popay 'pop data (a=to, y=from, t1=step) + mov t1, #1 +repeaty call #getadrs + cmps a,y wc 'reverse range? + sumc x,t1 'add/sub step to/from var + call #range 'check if x in range y..a according to c + if_nc add pcurr,op2 'if in range, branch + mov op2, #0 'ensure we don't push to the stack + jmp savex + +' Check range +' must be preceded by: cmps a,y wc +' +range if_c xor a,y 'if reverse range, swap range values + if_c xor y,a + if_c xor a,y + cmps x,y wc 'c=0 if x within range + if_nc cmps a,x wc + ret + +randf neg t1, #1 wz + jmp #rand1 +randr mov t1, #0 wz +rand1 min x,#1 + mov y,#32 + mov a,#%10111 + if_z ror a,#1 +rand2 test x,a wc + if_nz rcr x,#1 + if_z rcl x,#1 + djnz y,@rand2 + jmp savex + +_sarx call #popy1 + sar x, y + jmp savex + +_mulx call #popy1 + mul32 x, y + getmull x + jmp savex + +_mulhx call #popy1 + mul32 x, y + getmulh x + jmp savex + +_addx call #popy1 + add x, y + jmp savex + +_subx call #popy1 + sub x, y + jmp savex + +_xorx call #popy1 + xor x, y + jmp savex + +'*********************************************************************** +' Math Instructions +'*********************************************************************** +_min call #popyx + min x, y + jmp savex + +_max call #popyx + max x, y + jmp savex + +_rev call #popyx + rev x, y + jmp savex + +decode call #popy1 + mov x, #1 + shl x, y + jmp savex + +encode call #popy1 + mov x, #1 +encode1 if_z jmp savex + add x, #1 + shr y, #1 wz + jmp #encode1 + +_sqrt call #popx1 +_sqrtx sqrt32 x + getsqrt x + jmp savex + +'*********************************************************************** +' Extended Math Instructions +'*********************************************************************** +_andlx cmp x, #0 wz + jmp #_andl+1 + +_orlx cmp x, #0 wz + jmp #_orl+1 + +_cmpltx call #popy1 + jmp #_cmplt+1 + +_cmpgtx call #popy1 + jmp #_cmpgt+1 + +_cmpnex call #popy1 + jmp #_cmpne+1 + +_cmpeqx call #popy1 + jmp #_cmpeq+1 + +_cmplex call #popy1 + jmp #_cmple+1 + +_cmpgex call #popy1 + jmp #_cmpge+1 + +_minx call #popy1 + min x, y + jmp savex + +_maxx call #popy1 + max x, y + jmp savex + +_revx call #popy1 + rev x, y + jmp savex + +decodex mov y, x + jmp #decode+1 + +encodex mov y, x + jmp #encode+1 + +'*********************************************************************** +' This code is used when absolute address 0 is accessed +'*********************************************************************** +ldclkfreq mov x, ##_clkfreq + jmp #pushx1 + +'*********************************************************************** +' Trap for unsupported instructions +'*********************************************************************** +_waitvi +_clkset +unsupp mov op2, #0 +unsupx mov t1, ##@str1 + call #putstr + mov t1, op + call #puthex + mov x, #" " + call #putch + mov t1, op2 + call #puthex + mov x, #13 + call #putch + cogid x + cogstop x + +puthex rol t1, #28 + call #puthexdigit + rol t1, #4 + call #puthexdigit + ret + +puthexdigit mov x, #15 + and x, t1 + mov y, ##@hexdigits + add y, x + rdbyte x, y + call #putch + ret + +putstr rdbyte x, t1 wz + if_z ret + add t1, #1 + call #putch + jmp #putstr + +putch or x, #$100 + shl x, #1 + mov y, #10 + getcnt a + add a, bitcycles +:loop ror x, #1 wc + 'setpc #30 + setpc #90 + waitcnt a, bitcycles + djnz y, @:loop + ret + +str1 byte "Unsupported opcode ", 0 +hexdigits byte "0123456789ABCDEF" + +'*********************************************************************** +' Spin program binary file +'*********************************************************************** +testprog file "test.binary" + +{{ ++-----------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++-----------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy | +|of this software and associated documentation files (the "Software"), to deal| +|in the Software without restriction, including without limitation the rights | +|to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | +|copies of the Software, and to permit persons to whom the Software is | +|furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in | +|all copies or substantial portions of the Software. | +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | +|IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | +|FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | +|AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | +|LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,| +|OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE| +|SOFTWARE. | ++-----------------------------------------------------------------------------+ +}} diff --git a/p1spin/spasm.txt b/p1spin/spasm.txt new file mode 100755 index 0000000..8ff1249 --- /dev/null +++ b/p1spin/spasm.txt @@ -0,0 +1,351 @@ +SPASM(1) User Commands SPASM(1) + +NAME + spasm - spin assembler + +SYNOPSIS + spasm [-l] [-d] FILE + +DESCRIPTION + Spasm assembles the source file given by FILE. The file name may + include the extension, or .spa will be assumed if no extension is + specified. The assembled binary program will written to a file with + the same root name plus a .bin extension. If -l is specified, it will + print an assembly listing. If -d is specified, spasm will print debug + information. + + Spasm is an assembly language that defines mnemonics for Spin + bytecodes. Spin bytecodes are executed by the Spin interpreter, which + is loaded at boot time from the internal ROM. The Spin interpreter is + a stack-based virtual machine that uses the stack to store parameters + that are used by operators, such as add, sub, etc. The operators store + their results back onto the stack. There are other operators that + transfer data back and forth between the stack and hub RAM. + + The Spin bytecodes are listed below. They are separated into four + major groups -- lower, memory, math and extened operators. The lower + group contains a mix of operators, including those that handle program + flow, lookup, lookdown, case, and several other miscellaneous functions. + The math operators implement the various math and logic functions that + use two arguments. + + The memory operators implement load, store, execute and address + functions. A load operation reads data from the hub RAM and pushes it + onto the stack. A store operation pops a value off the stack and + stores it in RAM. The address operator is used to push the absolute + address of a hub RAM location onto the stack. + + The execute operation is used to execute an operation directly on a RAM + location. The result can be optionally pushed to the stack. The + operations that can be executed directly on a hub RAM location include + the standard 32 math operations plus a small number of extended + operations. The extended operators include pre and post increment and + decrement, sign extension and the random function. + + The format of the memory mnemonics is as follows: + + + operation = {ld, st, ex, la}, + size = {b, w, l}, + type = {i, l, o, a, v, s} + mode = {c, x, 0, 1, m1, p} + + The operations are load, store, execute and load address as stated + earlier. The size refers to byte, word and long. The types are + immediate, local, object, absolute, variable and stack. The modes + are compact, indexed, zero, one, minus one and packed. + + As an example, the instruction ldwi means load-word-immediate. It + will load an immediate value onto the stack. The instruction stba + will store a byte at the absolute address residing in the stack. + + There are compact instructions that use a single byte to address + the first 8 long values residing in the method's stack frame or in + an object's variable space. These use the size, type and mode + characters "llc". As an example, the method result value can be + set with the "stllc 0" instruction. The fourth long in the objet's + variable section could be loaded with "ldllc 12". + + When an execute memory operation is specified it is followed by one of + the math operators or an extended operator. An execute instruction may + also specify the "load" extended operator to save the result on the + stack. Examples of using execute instructions are as follows: + + exlo $8 add ' Add value on stack to the object long at offset $8 + exwv $20 preinc ' Increment the VAR word at offset $20 + exll $10 postdec load ' Decrement stack location $10 and load + + Spasm also includes psuedo-ops, which are shortened versions of the + memory mnenomics. The psuedo-ops are made up only of the operation + and size fields, plus the "x" charater if it is indexed. The + psuedo-ops are mapped to explicit opcodes depending on the context + of the operand. As an example "ldl 1" maps into "ldli1", and + "ldl result" maps into "ldllc 0". + + The Spasm opcodes are listed below. The offsets used for the jump + instructions are signed offsets that are relative to the address of the + next instruction. A "jmp 0" instruction will just execute the next + instruction. + + Signed offsets are encoded in either one or two bytes depending + on the value of the most significant bit in the first byte. If the + MSB is zero the remaining seven bits are treated as a signed 7-bit + number in the range from -64 to 63. If the MSB is non-zero, the + remaining seven bits are used as the most significant bits of a 15-bit + signed number, and the next byte provides the eight least sigficant + bits. The 15-bit signed offset has a range from -16384 to 16383. + + The memory opcodes use an unsigned offset that can also be encoded in + one or two bytes. The MSB is used to determine whether it is one or + two bytes just like for signed offset. However, since it is unsigned, + the range for the one-byte offset is 0 to 128, and for two bytes it is + 0 to 32768. + + Lower Opcodes + ------------- + 00 ldfrmr - Load call frame with return value required + 01 ldfrm - Load call frame + 02 ldfrmar - Load call frame with abort trap & return value + 03 ldfrma - Load call frame with abort trap + 04 jmp offset - Jump to signed object offset + 05 call meth - Call method + 06 callobj meth, obj - Call method in object + 07 callobjx meth, obj - Call method in object with index + 08 tjz offset - Test and jump if zero + 09 djnz offset - Decrement and jump if not zero + 0a jz offset - Jump if zero + 0b jnz offset - Jump if not zero + 0c casedone - Case done without a match + 0d casevalue - Execute if value matches case value + 0e caserange - Execute if case value within range + 0f lookdone - Look up/down done without a match + 10 lookupval - + 11 lookdnval + 12 lookuprng + 13 lookdnrng + 14 pop - Discard N bytes from the stack + 15 run - Prepare new spin cog stack for execution + 16 strsize - Determine the size of a string + 17 strcomp - Compare two strings + 18 bytefill - Fill memory with a constant byte value + 19 wordfill - Fill memory with a constant word value + 1a longfill - Fill memory with a constant long value + 1b waitpeq - Wait till pins are equal to a value + 1c bytemove - Copy bytes to a new location + 1d wordmove - Copy words to a new location + 1e longmove - Copy longs to a new location + 1f waitpne - Wait till pins are not equal to value + 20 clkset - Change the clock frequency and mode + 21 cogstop - Stop the specified cog + 22 lockret - Return a lock + 23 waitcnt - Wait for cnt to equal a specified value + 24 ldlsx + 25 stlsx + 26 exlsx + 27 waitvid - Wait on video + 28 coginitret - Start a cog and return the cog number + 29 locknewret - Allocate a lock and return the lock number + 2a locksetret - Set a lock and return the previous value + 2b lockclrret - Clear a lock and return the previous value + 2c coginit - Start a cog + 2d locknew - Allocate a lock with no return value + 2e lockset - Set a lock with no return value + 2f lockclr - Clear a lock with no return value + 30 abort - Perform an abort to the next abort trap + 31 abortval - Perform an abort and return a value + 32 ret - Return without loading a return value + 33 retval - Return and load a return value on the stack + 34 ldlim1 - Load a minus 1 + 35 ldli0 - Load zero + 36 ldli1 - Load 1 + 37 ldlip value - Load a packed-byte constant + 38 ldbi value - Load a single-byte constant + 39 ldwi value - Load a two-byte constant + 3a ldmi value - Load a three-byte constant + 3b ldli value - Load a four-byte constant + 3c --- - Unused opcode + 3d ldregbit - Load a bit from a register + 3d stregbit - Store a bit to a register + 3e ldregbits - Load bits from a register + 3e stregbits - Store bit to a register + 3f ldreg - Load a register + 3f streg - Store a register + + Compact Memory Opcodes + -------------- + 40 ldlvc offset - Load long variable compact + 41 stlvc offset - Store long variable compact + 42 exlvc offset - Execute on a long variable compact + 43 lalvc offset - Load address of a long variable compact + 60 ldllc offset - Load long local compact + 61 stllc offset - Store long local compact + 62 exllc offset - Execute on a long local compact + 63 lallc offset - Load address of a long local compact + + Byte Memory Opcodes + -------------- + 80 ldba - Load byte absolute + 81 stba - Store byte absolute + 82 exba - Execute on a byte absolute + 83 laba - Load address of a byte absolute + 84 ldbo offset - Load byte object offset + 85 stbo offset + 86 exbo offset + 87 labo offset + 88 ldbv offset - Load byte variable offset + 89 stbv offset + 8a exbv offset + 8b labv offset + 8c ldbl offset - Load byte local offset + 8d stbl offset + 8e exbl offset + 8f labl offset + 90 ldbax - Load byte absolute with index + 91 stbax + 92 exbax + 93 labax + 94 ldbox offset - Load byte object offset with index + 95 stbox offset + 96 exbox offset + 97 labox offset + 98 ldbvx offset - Load byte variable offset with index + 99 stbvx offset + 9a exbvx offset + 9b labvx offset + 9c ldblx offset - Load byte local offset with index + 9d stblx offset + 9e exblx offset + 9f lablx offset + + Word Memory Opcodes + ------------------- + a0 ldwa - Load word absolute + a1 stwa + a2 exwa + a3 lawa + a4 ldwo offset + a5 stwo offset + a6 exwo offset + a7 lawo offset + a8 ldwv offset + a9 stwv offset + aa exwv offset + ab lawv offset + ac ldwl offset + ad stwl offset + ae exwl offset + af lawl offset + b0 ldwax - Load word absolute with index + b1 stwax + b2 exwax + b3 lawax + b4 ldwox offset + b5 stwox offset + b6 exwox offset + b7 lawox offset + b8 ldwvx offset + b9 stwvx offset + ba exwvx offset + bb lawvx offset + bc ldwlx offset + bd stwlx offset + be exwlx offset + bf lawlx offset + + Long Memory Opcodes + ------------------- + c0 ldla - Load long absolute + c1 stla + c2 exla + c3 lala + c4 ldlo offset + c5 stlo offset + c6 exlo offset + c7 lalo offset + c8 ldlv offset + c9 stlv offset + ca exlv offset + cb lalv offset + cc ldll offset + cd stll offset + ce exll offset + cf lall offset + d0 ldlax - Load long absolute with index + d1 stlax + d2 exlax + d3 lalax + d4 ldlox offset + d5 stlox offset + d6 exlox offset + d7 lalox offset + d8 ldlvx offset + d9 stlvx offset + da exlvx offset + db lalvx offset + dc ldllx offset + dd stllx offset + de exllx offset + df lallx offset + + Math Opcodes + ------------ + e0 ror - Rotate right + e1 rol - Rotate left + e2 shr - Shift right + e3 shl - Shift left + e4 min - Maximum + e5 max - Minimum + e6 neg - Negate + e7 com - Compliment + e8 and - Bitwise and + e9 abs - Absolute value + ea or - Bitwise or + eb xor - Bitwise exclusive or + ec add - Add + ed sub - Subtract + ee sar - Shift arithmetic right + ef rev - Bit reverse + f0 andl - Logical and + f1 encode - Shift "1" left + f2 orl - Logical or + f3 decode - Find left-most "1" bit + f4 mul - Multiply + f5 mulh - Multiply high + f6 div - Divide + f7 mod - Modulus + f8 sqrt - Square root + f9 cmplt - Less than + fa cmpgt - Greater than + fb cmpne - Not equal + fc cmpeq - Equal + fd cmple - Less than or equal + fe cmpge - Greater than or equal + ff notl - Logical not + + Extended opcodes + ---------------- + 00 load - Load the value + 02 repeat - Repeat index from first to last + 06 repeats - Repeat index from first to last with step + 08 randf - Forward random number + 0c randr - Reverse random number + 10 sexb - Sign extend byte + 14 sexw - Sign extend word + 18 postclr - Post clear to zero + 1c postset - Post set to all ones + 26 preinc - Pre-increment + 2e postinc - Post-increment + 36 predec - Pre-decrement + 3e postdec - Post-decrement + +AUTHOR + Dave Hein + +COPYRIGHT + Copyright (c) 2011, 2012, Dave Hein + MIT License (See license.txt in the root directory) + This is free software: you are free to change and redistribute it. + There is no warranty, to the extent permitted by law. + + +SPASM March 2012 SPASM(1) diff --git a/p1spin/test.binary b/p1spin/test.binary new file mode 100755 index 0000000..224a3bb Binary files /dev/null and b/p1spin/test.binary differ diff --git a/p1spin/test.spin b/p1spin/test.spin new file mode 100755 index 0000000..2d10bf5 --- /dev/null +++ b/p1spin/test.spin @@ -0,0 +1,14 @@ +CON + _clkmode = xtal1+pll16x + _clkfreq = 80_000_000 + +OBJ + ser : "Simple_Serial" + dry : "dry11" + +PUB main | ptr, count + 'waitcnt(clkfreq*3+cnt) + ser.init(31, 30, 19200) + ser.str(string(13, "Testing Spin Interpreter", 13)) + dry.Dhrystone11 + waitcnt(clkfreq/10+cnt) \ No newline at end of file diff --git a/pasmdebug.c b/pasmdebug.c new file mode 100755 index 0000000..ab7e1fe --- /dev/null +++ b/pasmdebug.c @@ -0,0 +1,231 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include "interp.h" + +char *FindChar(char *str, int32_t val); +int32_t CheckWaitFlag(PasmVarsT *pasmvars, int mode); + +extern char *hubram; +extern int32_t memsize; +extern int32_t loopcount; +extern int32_t cycleaccurate; + +extern FILE *tracefile; + +static char *condnames[16] = { + "if_never ", "if_nz_and_nc", "if_z_and_nc ", "if_nc ", + "if_nz_and_c ", "if_nz ", "if_z_ne_c ", "if_nz_or_nc ", + "if_z_and_c ", "if_z_eq_c ", "if_z ", "if_z_or_nc ", + "if_c ", "if_nz_or_c ", "if_z_or_c ", " "}; + + +static char *opnames[64][2] = { + {"wrbyte", "rdbyte"}, {"wrword", "rdword"}, {"wrlong", "rdlong"}, + {"hubop nr", "hubop"}, {"undef nr", "undef"}, {"undef nr", "undef"}, + {"undef nr", "undef"}, {"undef nr", "undef"}, {"ror nr", "ror"}, + {"rol nr", "rol"}, {"shr nr", "shr"}, {"shl nr", "shl"}, + {"rcr nr", "rcr"}, {"rcl nr", "rcl"}, {"sar nr", "sar"}, + {"rev nr", "rev"}, {"mins nr", "mins"}, {"maxs nr", "maxs"}, + {"min nr", "min"}, {"max nr", "max"}, {"movs nr", "movs"}, + {"movd nr", "movd"}, {"movi nr", "movi"}, {"jmp", "call"}, + {"test", "and"}, {"testn", "andn"}, {"or nr", "or"}, + {"xor nr", "xor"}, {"muxc nr", "muxc"}, {"muxnc nr", "muxnc"}, + {"muxz nr", "muxz"}, {"muxnz nr", "muxnz"}, {"add nr", "add"}, + {"cmp", "sub"}, {"addabs nr", "addabs"}, {"subabs nr", "subabs"}, + {"sumc nr", "sumc"}, {"sumnc nr", "sumnc"}, {"sumz nr", "sumz"}, + {"sumnz nr", "sumnz"}, {"mov nr", "mov"}, {"neg nr", "neg"}, + {"abs nr", "abs"}, {"absneg nr", "absneg"}, {"negc nr", "negc"}, + {"negnc nr", "negnc"}, {"negz nr", "negz"}, {"negnz nr", "negnz"}, + {"cmps", "cmps wr"}, {"cmpsx", "cmpsx wr"}, {"addx nr", "addx"}, + {"cmpx", "subx"}, {"adds nr", "adds"}, {"subs nr", "subs"}, + {"addsx nr", "addsx"}, {"subsx nr", "subsx"}, {"cmpsub nr", "cmpsub"}, + {"djnz nr", "djnz"}, {"tjnz", "tjnz wr"}, {"tjz", "tjz wr"}, + {"waitpeq", "waitpeq wr"}, {"waitpne", "waitpne wr"}, + {"waitcnt nr", "waitcnt"}, {"waitvid", "waitvid wr"}}; + +static char *hubops[8][2] = { + {"clkset", "clkset wr"}, {"cogid nr", "cogid"}, + {"coginit", "coginit wr"}, {"cogstop", "cogstop wr"}, + {"locknew nr", "locknew"}, {"lockret", "lockret wr"}, + {"lockset", "lockset wr"}, {"lockclr", "lockclr wr"}}; + +static int32_t swapshift[32] = { + 28, 23, 8, 16, 21, 7, 21, 7, 3, 7, 13, 9, 19, 4,-13, 15, + -8,-17, -3, 7, 2, -8,-16, 6,-21,-16, -8,-23,-26,-22,-25,-10}; + +static uint32_t swapmask[32] = { + 0x00000008, 0x00000080, 0x00200000, 0x00001000, 0x00000040, 0x00080000, + 0x00000010, 0x00020000, 0x00100000, 0x00008000, 0x00000100, 0x00000800, + 0x00000001, 0x00004000, 0x40000000, 0x00000002, 0x00800000, 0x80000000, + 0x00010000, 0x00000020, 0x00000200, 0x00040000, 0x02000000, 0x00000004, + 0x10000000, 0x00400000, 0x00002000, 0x08000000, 0x20000000, 0x01000000, + 0x04000000, 0x00000400}; + +static uint32_t swapit(uint32_t val1) +{ + int32_t i, shift; + uint32_t mask; + uint32_t val2; + + val2 = 0; + for (i = 0; i < 32; i++) + { + mask = swapmask[i]; + shift = swapshift[i]; + if (shift >= 0) + val2 |= (val1 & mask) << shift; + else + val2 |= (val1 & mask) >> -shift; + } + return val2; +} + +void StartPasmCog(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid) +{ + int32_t i; + + pasmvars->waitflag = 0; + pasmvars->cflag = 0; + pasmvars->zflag = 0; + pasmvars->pc = 0; + pasmvars->pc1 = 512; + pasmvars->pc2 = 512; + pasmvars->instruct1 = 0; + pasmvars->instruct2 = 0; + pasmvars->cogid = cogid; + pasmvars->state = 5; + pasmvars->mem[496] = par; + + for (i = 0; i < 496; i++) + { + if (addr & 0x8000) + pasmvars->mem[i] = swapit(LONG(addr)); + else + pasmvars->mem[i] = LONG(addr); + addr += 4; + } +} + +void DebugPasmInstruction(PasmVarsT *pasmvars) +{ + int32_t i; + int32_t cflag = pasmvars->cflag; + int32_t zflag = pasmvars->zflag; + int32_t instruct, cond, pc; + int32_t opcode, value2, value1, zcri; + int32_t srcaddr, dstaddr; + char *wzstr; + char *wcstr; + char *wrstr; + char *ptr; + char opstr[20]; + char *istr[2] = {" ", "#"}; + char *xstr[4] = {"X", " ", "W", "I"}; + int32_t xflag; + + // Fetch the instruction + if (pasmvars->waitflag) + { + pc = pasmvars->pc2; + instruct = pasmvars->instruct2; + } + else + { + pc = pasmvars->pc1; + instruct = pasmvars->instruct1; + } + cond = (instruct >> 18) & 15; + xflag = ((cond >> ((cflag << 1) | zflag)) & 1); + + // Check if the instruction is invalidated in the pipeline + if (pc & 0xfffffe00) + { + pc &= 0x1ff; + xflag = 3; + } + + // Extract parameters from the instruction + opcode = (instruct >> 26) & 63; + srcaddr = instruct & 511; + dstaddr = (instruct >> 9) & 511; + zcri = (instruct >> 22) & 15; + + // Get the two operands + value1 = pasmvars->mem[dstaddr]; + if (zcri & 1) + value2 = srcaddr; + else + value2 = pasmvars->mem[srcaddr]; + + // Check for wait cycles for djnz, tjnz, tjz or hubop + if (cycleaccurate && xflag == 1) + { + if (opcode <= 0x07) // hubop + { + if (CheckWaitFlag(pasmvars, 3)) xflag = 2; + } + else if (opcode == 0x3e) // waitcnt + { + int32_t result = GetCnt() - value1; + if (result < 0 || result >= 4) xflag = 2; + } + } + + if (zcri&8) wzstr = " wz"; + else wzstr = ""; + if (zcri&4) wcstr = " wc"; + else wcstr = ""; + wrstr = ""; + + if (opcode == 3) + strcpy(opstr, hubops[value2 & 7][(zcri>>1)&1]); + else + strcpy(opstr, opnames[opcode][(zcri>>1)&1]); + ptr = FindChar(opstr, ' '); + if (*ptr) + { + *ptr++ = 0; + if (*ptr == 'w') + wrstr = " wr"; + else if (*ptr == 'n') + wrstr = " nr"; + } + + i = strlen(opstr); + + while (i < 7) opstr[i++] = ' '; + opstr[i] = 0; + +#if 0 + fprintf(tracefile, "%3.3x %8.8x %d %d %s %s %s %3.3x %s%3.3x %8.8x %8.8x", pasmvars->pc, + instruct, zflag, cflag, xstr[xflag], condnames[cond], opstr, dstaddr, + istr[zcri & 1], srcaddr, value1, value2); +#else + fprintf(tracefile, "%6d %3.3x %8.8x %s %s %s %3.3x, %s%3.3x%s%s%s", loopcount * 4, pc, + instruct, xstr[xflag], condnames[cond], opstr, dstaddr, + istr[zcri & 1], srcaddr, wzstr, wcstr, wrstr); +#endif +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/pasmdebug2.c b/pasmdebug2.c new file mode 100755 index 0000000..f0cca09 --- /dev/null +++ b/pasmdebug2.c @@ -0,0 +1,448 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include "interp.h" +#include "spinsim.h" + +#define REG_PINA 0x1f4 + +extern char *hubram; +extern int32_t memsize; +extern int32_t loopcount; +extern int32_t cycleaccurate; +extern int32_t pin_val; + +extern FILE *tracefile; + +static char *condnames[16] = { + "if_never ", "if_nz_and_nc", "if_z_and_nc ", "if_nc ", + "if_nz_and_c ", "if_nz ", "if_z_ne_c ", "if_nz_or_nc ", + "if_z_and_c ", "if_z_eq_c ", "if_z ", "if_z_or_nc ", + "if_c ", "if_nz_or_c ", "if_z_or_c ", " "}; + +char *opcodes_lower[64] = { + "rdbyte","rdbytec","rdword","rdwordc","rdlong","rdlongc","rdaux","rdauxr", + "isob","notb","clrb","setb","setbc","setbnc","setbz","setbnz", + "andn","and","or","xor","muxc","muxnc","muxz","muxnz", + "ror","rol","shr","shl","rcr","rcl","sar","rev", + "mov","not","abs","neg","negc","negnc","negz","negnz", + "add","sub","addx","subx","adds","subs","addsx","subsx", + "sumc","sumnc","sumz","sumnz","min","max","mins","maxs", + "addabs","subabs","incmod","decmod","cmpsub","subr","mul","scl"}; + +char *opcodes_upper[62][4] = { + {"decod2", "decod2", "decod2", "decod2"}, + {"decod3", "decod3", "decod3", "decod3"}, + {"decod4", "decod4", "decod4", "decod4"}, + {"decod5", "decod5", "decod5", "decod5"}, + {"encod", "blmask", "encod", "blmask"}, + {"onecnt", "zercnt", "onecnt", "zercnt"}, + {"incpat", "incpat", "decpat", "decpat"}, + {"splitb", "mergeb", "splitw", "mergew"}, + + {"getnib", "setnib", "getnib", "setnib"}, + {"getnib", "setnib", "getnib", "setnib"}, + {"getnib", "setnib", "getnib", "setnib"}, + {"getnib", "setnib", "getnib", "setnib"}, + {"getword","setword","getword","setword"}, + {"setwrds","rolnib", "rolbyte","rolword"}, + {"sets", "setd", "setx", "seti"}, + {"cognew", "cognew", "waitcnt","waitcnt"}, + + {"getbyte","setbyte","getbyte","setbyte"}, + {"getbyte","setbyte","getbyte","setbyte"}, + {"setbyts","movbyts","packrgb","unpkrgb"}, + {"addpix", "mulpix", "blnpix", "mixpix"}, + {"jmpsw", "jmpsw", "jmpsw", "jmpsw"}, + {"jmpswd", "jmpswd", "jmpswd", "jmpswd"}, + {"ijz", "ijzd", "ijnz", "ijnzd"}, + {"djz", "djzd", "djnz", "djnzd"}, + + {"testb", "testb", "testb", "testb"}, + {"testn", "testn", "testn", "testn"}, + {"test", "test", "test", "test"}, + {"cmp", "cmp", "cmp", "cmp"}, + {"cmpx", "cmpx", "cmpx", "cmpx"}, + {"cmps", "cmps", "cmps", "cmps"}, + {"cmpsx", "cmpsx", "cmpsx", "cmpsx"}, + {"cmpr", "cmpr", "cmpr", "cmpr"}, + + {"coginit","waitvid","coginit","waitvid"}, + {"coginit","waitvid","coginit","waitvid"}, + {"coginit","waitvid","coginit","waitvid"}, + {"coginit","waitvid","coginit","waitvid"}, + {"waitpeq","waitpeq","waitpeq","waitpeq"}, + {"waitpeq","waitpeq","waitpeq","waitpeq"}, + {"waitpne","waitpne","waitpne","waitpne"}, + {"waitpne","waitpne","waitpne","waitpne"}, + + {"wrbyte", "wrbyte", "wrword", "wrword"}, + {"wrlong", "wrlong", "frac", "frac"}, + {"wraux", "wraux", "wrauxr", "wrauxr"}, + {"setacca","setacca","setaccb","setaccb"}, + {"maca", "maca", "macb", "macb"}, + {"mul32", "mul32", "mul32u", "mul32u"}, + {"div32", "div32", "div32u", "div32u"}, + {"div64", "div64", "div64u", "div64u"}, + + {"sqrt64", "sqrt64", "qsincos","qsincos"}, + {"qarctan","qarctan","qrotate","qrotate"}, + {"setsera","setsera","setserb","setserb"}, + {"setctrs","setctrs","setwavs","setwavs"}, + {"setfrqs","setfrqs","setphss","setphss"}, + {"addphss","addphss","subphss","subphss"}, + {"jp", "jp", "jpd", "jpd"}, + {"jnp", "jnp", "jnpd", "jnpd"}, + + {"cfgpins","cfgpins","cfgpins","cfgpins"}, + {"cfgpins","cfgpins","jmptask","jmptask"}, + {"setxfr", "setxfr", "setmix", "setmix"}, + {"jz", "jzd", "jnz", "jnzd"}, + {"locbase","locbyte","locword","loclong"}, + {"jmplist","locinst","augs", "augd"}}; + +int zci_upper[62][4] = { + {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, + {5, 5, 5, 5}, {5, 5, 5, 5}, {3, 3, 3, 3}, {1, 1, 1, 1}, + + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {3, 3, 3, 3}, + + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + {7, 7, 7, 7}, {7, 7, 7, 7}, {1, 1, 1, 1}, {1, 1, 1, 1}, + + {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, + {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, + + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + {3, 3, 3, 3}, {3, 3, 3, 3}, {3, 3, 3, 3}, {3, 3, 3, 3}, + + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, + + {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}; + +char *opcodes_ind[16] = { + "invalid", "fixinda", "setinda", "setinda", + "fixindb", "fixinds", "invalid", "invalid", + "setindb", "invalid", "setinds", "setinds", + "setindb", "invalid", "setinds", "setinds"}; + +char *opcodes_16[14] = { + "locptra","locptrb","jmp","jmpd","call","calld","calla", + "callad","callb","callbd","callx","callxd","cally","callyd"}; + +char *opcodes_set1[49] = { + "cogid","taskid","locknew","getlfsr","getcnt","getcntx","getacal","getacah", + "getacbl","getacbh","getptra","getptrb","getptrx","getptry","serina","serinb", + "getmull","getmulh","getdivq","getdivr","getsqrt","getqx","getqy","getqz", + "getphsa","getphza","getcosa","getsina","getphsb","getphzb","getcosb","getsinb", + "pushzc","popzc","subcnt","getpix","binbcd","bcdbin","bingry","grybin", + "eswap4","eswap8","seussf","seussr","incd","decd","incds","decds","pop"}; + +char *opcodes_set2[] = { + "clkset", "cogstop", "lockset", "lockclr", "lockret", "rdwidec", "rdwide", + "wrwide", "getp", "getnp", "serouta", "seroutb", "cmpcnt", "waitpx", + "waitpr", "waitpf", "setzc", "setmap", "setxch", "settask", "setrace", + "saracca", "saraccb", "saraccs", "setptra", "setptrb", "addptra", "addptrb", + "subptra", "subptrb", "setwide", "setwidz", "setptrx", "setptry", + "addptrx", "addptry", "subptrx", "subptry", "passcnt", "wait", "offp", + "notp", "clrp", "setp", "setpc", "setpnc", "setpz", "stpnz", "div64d", + "sqrt32", "qlog", "qexp", "setqi", "setqz", "cfgdacs", "setdacs", + "cfgdac0", "cfgdac1", "cfgdac2", "cfgdac3", "setdac0", "setdac1", + "setdac2", "seddac3", "setctra", "setwava", "setfrqa", "setphsa", + "addphsa", "subphsa", "setvid", "setvidy", "setctrb", "setwavb", "setfrqb", + "setphsb", "addphsb", "subphsb", "setvidi", "setvidq", "setpix", "setpixz", + "setpixu", "setpixv", "setpixa", "setpixr", "setpixg", "setpixb", + "setpora", "setporb", "setporc", "setpord", "push"}; + +char *opcodes_set3[40] = { + "jmp", "jmpd", "call", "calld", "calla", "callad", "callb", "callbd", + "callx", "callxd", "cally", "callyd", "reta", "retad", "retb", "retbd", + "retx", "retxd", "rety", "retyd", "ret", "retd", "polctra", "polctrb", + "polvid", "capctra", "capctrb", "capctrs", "setpixw", "clracca", "clraccb", + "clraccs", "chkptrx", "chkptry", "syntra", "synctrb", "dcachex", "icachex", + "icachep", "icachen"}; + +int zci_set3[40] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0}; + + +char *GetOpname2(unsigned int instr, int *pzci) +{ + int opcode = instr >> 25; + int zci = (instr >> 22) & 7; + int cond = (instr >> 18) & 15; + int src = instr & 0x1ff; + int dst = (instr >> 9) & 0x1ff; + int zc = zci >> 1; + + //printf("opcode = $%2.2x, zci = %d\n", opcode, zci); + + if (opcode < 64) + { + *pzci = 7; + return opcodes_lower[opcode]; + } + else if(opcode < 126) + { + *pzci = zci_upper[opcode-64][zc]; + return opcodes_upper[opcode-64][zc]; + } + else if (opcode == 126 && zci == 0) + { + *pzci = 0; + return opcodes_ind[cond]; + } + else if (opcode == 126) + { + *pzci = 0; + return opcodes_16[(zci-1)*2 + (dst >> 8)]; + } + else if (src <= 48) + { + if (src < 44 || src == 48) + *pzci = 7; + else + *pzci = 5; + return opcodes_set1[src]; + } + if (src < 64) + { + *pzci = 0; + return "invalid"; + } + if (src < 128) + { + *pzci = 1; + return "repd"; + } + if (src < 220) + { + if (src == 136 || src == 137 || src == 144) + *pzci = 7; + else if (src == 130 || src == 131) + *pzci = 3; + else + *pzci = 1; + return opcodes_set2[src-128]; + } + if (src < 0xf4) + { + *pzci = 0; + return "invalid"; + } + if (src <= 0x11b) + { + *pzci = zci_set3[src-0xf4]; + return opcodes_set3[src-0xf4]; + } + *pzci = 0; + return "invalid"; +} + +void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid) +{ + int32_t i; + + // printf("\nStartPasmCog2: %8.8x, %8.8x, %d\n", par, addr, cogid); + par &= 0x3ffff; + addr &= 0x3fffc; + pasmvars->waitflag = 0; + pasmvars->cflag = 0; + pasmvars->zflag = 0; + pasmvars->pc = 0; + pasmvars->cogid = cogid; + pasmvars->state = 5; + pasmvars->ptra = par; + pasmvars->ptrb = addr; + pasmvars->ptrx = 0; + pasmvars->ptry = 0; + pasmvars->inda = 0x1f2; + pasmvars->indatop = 0; + pasmvars->indabot = 0; + pasmvars->indb = 0x1f3; + pasmvars->indbtop = 0; + pasmvars->indbbot = 0; + pasmvars->repcnt = 0; + pasmvars->repbot = 0; + pasmvars->reptop = 0; + pasmvars->repforever = 0; + pasmvars->dcachehubaddr = 0xffffffff; + pasmvars->dcachecogaddr = 0xffffffff; + pasmvars->instruct1 = 0; + pasmvars->instruct2 = 0; + pasmvars->instruct3 = 0; + pasmvars->instruct4 = 0; + pasmvars->pc1 = INVALIDATE_INSTR; + pasmvars->pc2 = INVALIDATE_INSTR; + pasmvars->pc3 = INVALIDATE_INSTR; + pasmvars->pc4 = INVALIDATE_INSTR; + pasmvars->retptr = 0; + pasmvars->acca = 0; + pasmvars->accb = 0; + pasmvars->mulcount = 0; + pasmvars->breakpnt = -1; + pasmvars->augsflag = 0; + pasmvars->augsvalue = 0; + pasmvars->augdflag = 0; + pasmvars->augdvalue = 0; + pasmvars->icachehubaddr[0] = 0xffffffff; + pasmvars->icachehubaddr[1] = 0xffffffff; + pasmvars->icachehubaddr[2] = 0xffffffff; + pasmvars->icachehubaddr[3] = 0xffffffff; + pasmvars->icachenotused[0] = 0; + pasmvars->icachenotused[1] = 0; + pasmvars->icachenotused[2] = 0; + pasmvars->icachenotused[3] = 0; + pasmvars->prefetch = 1; + + for (i = 0; i < 0x1f4; i++) + { + pasmvars->mem[i] = LONG(addr); + addr += 4; + } + for (i = 0x1f4; i < 512; i++) pasmvars->mem[i] = 0; +} + +void DebugPasmInstruction2(PasmVarsT *pasmvars) +{ + int32_t i; + int32_t cflag = pasmvars->cflag; + int32_t zflag = pasmvars->zflag; + int32_t instruct, pc, cond, xflag; + int32_t opcode, zci; + int32_t srcaddr, dstaddr; + char *wzstr = ""; + char *wcstr = ""; + char opstr[20]; + char *istr[3] = {" ", "#", "@"}; + char *xstr[8] = {" ", "X", "I", "H", "C", "P", "W", "?"}; + int zci_mask; + int32_t sflag, dflag, indirect, opcode_zci; + + // Fetch the instruction + pc = pasmvars->pc4; + instruct = pasmvars->instruct4; + cond = (instruct >> 18) & 15; + + // Extract parameters from the instruction + opcode = (instruct >> 25) & 127; + srcaddr = instruct & 511; + dstaddr = (instruct >> 9) & 511; + zci = (instruct >> 22) & 7; + opcode_zci = (opcode << 3) | zci; + + // Decode the immediate flags for the source and destination fields + sflag = (opcode_zci >= 0x3ea) | (zci & 1); + + dflag = (opcode >= 0x68 && opcode <= 0x7a && (zci & 2)) | + (opcode_zci >= 0x302 && opcode_zci <= 0x31f) | + (opcode != 0x7f && opcode_zci >= 0x3eb) | + (opcode == 0x7f && srcaddr >= 0x40 && srcaddr <= 0xdc && (zci & 1)) | + (opcode == 0x7f && srcaddr >= 0x100); + + // Determine if indirect registers are used + indirect = (!sflag && (srcaddr & 0x1fe) == 0x1f2) | + (!dflag && (dstaddr & 0x1fe) == 0x1f2) | + (opcode_zci == 0x3f0); + + if (indirect) cond = 0xf; + xflag = ((cond >> ((cflag << 1) | zflag)) & 1); + xflag ^= 1; + + // Check if the instruction is invalidated in the pipeline + if (pc & INVALIDATE_INSTR) + { + pc &= ~INVALIDATE_INSTR; + xflag = 2; + } + + if (pasmvars->waitflag && pasmvars->waitmode == WAIT_CACHE) xflag = 4; + else if (xflag == 4) xflag = 5; + + if (pasmvars->waitflag) + { + if (pasmvars->waitmode == WAIT_CACHE) + xflag = 4; + else if (pasmvars->waitmode == WAIT_CNT) + xflag = 6; + else if (pasmvars->waitmode == WAIT_PIN) + xflag = 5; + else if (pasmvars->waitmode == WAIT_HUB) + xflag = 3; + else + xflag = 7; + } + + strcpy(opstr, GetOpname2(instruct, &zci_mask)); + + zci &= zci_mask; + if (zci & 4) wzstr = " wz"; + if (zci & 2) wcstr = " wc"; + + i = strlen(opstr); + while (i < 7) opstr[i++] = ' '; + opstr[i] = 0; + + // Check for NOP + if (!instruct) + { + cond = 15; + if (xflag == 1) xflag = 0; + strcpy(opstr, "nop "); + } + + // Check for REPS + if ((instruct & 0xffc00000) == 0xfac00000) + { + cond = 15; + if (xflag == 1) xflag = 0; + strcpy(opstr, "reps "); + } + + // Check for AUGS or AUGD + if (opcode_zci >= 0x3ec && opcode_zci <= 0x3ef) + { + cond = 15; + if (xflag == 1) xflag = 0; + } + + if (pasmvars->printflag - 2 < xflag && xflag != 0) + { + pasmvars->printflag = 0; + return; + } + + fprintf(tracefile, "Cog %d: %8.8x ", pasmvars->cogid, loopcount); + fprintf(tracefile, "%4.4x %8.8x %s %s %s %s%3.3x, %s%3.3x%s%s", pc, + instruct, xstr[xflag], condnames[cond], opstr, istr[dflag], dstaddr, + istr[sflag], srcaddr, wzstr, wcstr); +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/pasmsim.c b/pasmsim.c new file mode 100755 index 0000000..832825e --- /dev/null +++ b/pasmsim.c @@ -0,0 +1,742 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include "interp.h" + +extern char *hubram; +extern int32_t memsize; +extern char lockstate[8]; +extern char lockalloc[8]; +extern PasmVarsT PasmVars[8]; +extern int32_t pasmspin; +extern int32_t cycleaccurate; +extern int32_t loopcount; +extern int32_t proptwo; +extern int32_t pin_val; + +extern FILE *tracefile; + +void PrintResults(int32_t zcri, int32_t zflag, int32_t cflag, int32_t result) +{ + if (zcri & 8) printf(" Z=%d", zflag); + if (zcri & 4) printf(" C=%d", cflag); + if (zcri & 2) printf(" R=%8.8x", result); +} + +static int32_t parity(int32_t val) +{ + val ^= val >> 16; + val ^= val >> 8; + val ^= val >> 4; + val ^= val >> 2; + val ^= val >> 1; + return val & 1; +} + +static int32_t abs(int32_t val) +{ + return val < 0 ? -val : val; +} + +int32_t CheckWaitFlag(PasmVarsT *pasmvars, int mode) +{ + int32_t hubmode = mode & 1; + int32_t debugmode = mode & 2; + int32_t waitflag = pasmvars->waitflag; + + if (waitflag) + { + waitflag--; + } + else if (hubmode) + { + if (proptwo) + waitflag = (pasmvars->cogid - loopcount) & 7; + else + waitflag = ((pasmvars->cogid >> 1) - loopcount) & 3; + waitflag++; + } + else + { + if (proptwo) + waitflag = 2; + else + waitflag = 1; + } + if (!debugmode) + { + //if (waitflag) + //pasmvars->pc = (pasmvars->pc - 1) & 511; + pasmvars->waitflag = waitflag; + } + + return waitflag; +} + +void AdjustPipeForJump(PasmVarsT *pasmvars, int32_t value, int32_t jump) +{ + int32_t pc = value & 0x1ff; + pasmvars->instruct1 = pasmvars->mem[pc]; + if (jump) + { + pasmvars->pc = (pc + 1) & 511; + pasmvars->pc1 = pc; + } + else + { + pasmvars->pc = pasmvars->pc1; + pasmvars->pc1 = pc | 512; + } +} + +int32_t ExecutePasmInstruction(PasmVarsT *pasmvars) +{ + int32_t cflag = pasmvars->cflag; + int32_t zflag = pasmvars->zflag; + int32_t instruct, cond, pc; + int32_t opcode, value2, value1, zcri; + int32_t srcaddr, dstaddr; + int32_t result = 0; + + // Fetch a new instruction and update the pipeline + if (!pasmvars->waitflag) + { + //printf("Fetch new instruction\n"); + pasmvars->instruct2 = pasmvars->instruct1; + pasmvars->instruct1 = pasmvars->mem[pasmvars->pc]; + pasmvars->pc2 = pasmvars->pc1; + pasmvars->pc1 = pasmvars->pc; + pasmvars->pc = (pasmvars->pc + 1) & 511; + } + + // Get the instruction and pc at the end of the pipeline + instruct = pasmvars->instruct2; + pc = pasmvars->pc2; + cond = (instruct >> 18) & 15; + + // Return if not executed + if ((!((cond >> ((cflag << 1) | zflag)) & 1)) || (pc & 0xfffffe00)) + { + return 0; + } + + // Check for a hub wait + if (cycleaccurate && !(instruct & 0xe0000000)) + { + if (CheckWaitFlag(pasmvars, 1)) return 0; + } + + // Extract parameters from the instruction + opcode = (instruct >> 26) & 63; + srcaddr = instruct & 511; + dstaddr = (instruct >> 9) & 511; + zcri = (instruct >> 22) & 15; + + // Get the two operands + value1 = pasmvars->mem[dstaddr]; + if (zcri & 1) + value2 = srcaddr; + else if (srcaddr == 0x1f1) + value2 = GetCnt(); + else if (srcaddr == 0x1f2) + value2 = pin_val; + else + value2 = pasmvars->mem[srcaddr]; + + // Decode the three most significant bits of the opcode + switch(opcode >> 3) + { + // Hub access opcodes + case 0: + switch (opcode & 7) + { + case 0: // wrbyte, rdbyte + case 1: // wrword, rdword + case 2: // wrlong, rdlong + if (zcri & 2) // read + { + if ((opcode & 7) == 0) + result = BYTE(value2); + else if ((opcode & 7) == 1) + result = WORD(value2); + else + result = LONG(value2); + zflag = (result == 0); + } + else // write + { + if ((opcode & 7) == 0) + BYTE(value2) = pasmvars->mem[dstaddr]; + else if ((opcode & 7) == 1) + WORD(value2) = pasmvars->mem[dstaddr]; + else + LONG(value2) = pasmvars->mem[dstaddr]; + } + break; + + case 3: // misc hubops + switch (value2 & 7) + { + int32_t par, addr; + case 0: // clkset + result = value1 & 0xff; + if (result & 0x80) + { + RebootProp(); + return 0; + } + break; + + case 1: // cogid + result = pasmvars->cogid; + //pasmvars->mem[dstaddr] = result; + break; + + case 2: // coginit + par = (value1 >> 16) & 0xfffc; + addr = (value1 >> 2) & 0xfffc; + if (value1 & 8) // Start new cog + { + // Look for next available cog + for (result = 0; result < 8; result++) + { + if (!PasmVars[result].state) break; + } + if (result == 8) // Check if none available + { + cflag = 1; + result = 7; + zflag = 0; + break; + } + } + else + { + result = value1 & 7; + } + cflag = 0; + zflag = (result == 0); + if (addr == 0xf004 && !pasmspin) + { + SpinVarsT *spinvars = (SpinVarsT *)&PasmVars[result].mem[0x1e0]; + StartCog(spinvars, par, result); + } + else + { + StartPasmCog(&PasmVars[result], par, addr, result); + } + UpdatePins(); + // Return without saving if we restarted this cog + if (result == pasmvars->cogid) return result; + break; + + case 3: // cogstop + for (result = 0; result < 8; result++) + { + if (!PasmVars[result].state) break; + } + cflag = (result == 8); + result = value1 & 7; + zflag = (result == 0); + PasmVars[result].state = 0; + UpdatePins(); + // Return without saving if we stopped this cog + if (result == pasmvars->cogid) return result; + break; + + case 4: // locknew + for (result = 0; result < 8; result++) + { + if (!lockalloc[result]) break; + } + if (result == 8) + { + cflag = 1; + result = 7; + } + else + { + cflag = 0; + lockalloc[result] = 1; + } + zflag = (result == 0); + break; + + case 5: // lockret + for (result = 0; result < 8; result++) + { + if (!lockalloc[result]) break; + } + cflag = (result == 8); + result = value1 & 7; + zflag = (result == 0); + lockalloc[result] = 0; + break; + + case 6: // lockset + result = value1 & 7; + zflag = (result == 0); + cflag = lockstate[result] & 1; + lockstate[result] = -1; + break; + + case 7: // lockclr + result = value1 & 7; + zflag = (result == 0); + cflag = lockstate[result] & 1; + lockstate[result] = 0; + break; + } + break; + + default: // Not defined + //printf("Undefined op - %8.8x\n", instruct); + break; + } + break; + + // Rotate and shift + case 1: + value2 &= 0x1f; // Get five LSB's + switch (opcode & 7) + { + case 0: // ror + result = (((uint32_t)value1) >> value2) | (value1 << (32 - value2)); + cflag = value1 & 1; + break; + + case 1: // rol + result = (((uint32_t)value1) >> (32 - value2)) | (value1 << value2); + cflag = (value1 >> 31) & 1; + break; + + case 2: // shr + result = (((uint32_t)value1) >> value2); + cflag = value1 & 1; + break; + + case 3: // shl + result = (value1 << value2); + cflag = (value1 >> 31) & 1; + break; + + case 4: // rcr + if (value2) + { + result = (cflag << 31) | (((uint32_t)value1) >> 1); + result >>= (value2 - 1); + } + else + result = value1; + cflag = value1 & 1; + break; + + case 5: // rcl + result = cflag ? (1 << value2) - 1 : 0; + result |= (value1 << value2); + cflag = (value1 >> 31) & 1; + break; + + case 6: // sar + result = value1 >> value2; + cflag = value1 & 1; + break; + + case 7: // rev + cflag = value1 & 1; + value2 = 32 - value2; + result = 0; + while (value2-- > 0) + { + result = (result << 1) | (value1 & 1); + value1 >>= 1; + } + break; + } + zflag = (result == 0); + break; + + // Jump, call, return and misc. + case 2: + switch (opcode & 7) + { + case 0: // mins + cflag = (value1 < value2); + zflag = (value2 == 0); + result = cflag ? value2 : value1; + break; + + case 1: // maxs + cflag = (value1 < value2); + zflag = (value2 == 0); + result = cflag ? value1 : value2; + break; + + case 2: // min + cflag = (((uint32_t)value1) < ((uint32_t)value2)); + zflag = (value2 == 0); + result = cflag ? value2 : value1; + break; + + case 3: // max + cflag = (((uint32_t)value1) < ((uint32_t)value2)); + zflag = (value2 == 0); + result = cflag ? value1 : value2; + break; + + case 4: // movs + cflag = ((uint32_t)value1) < ((uint32_t)value2); + result = (value1 & 0xfffffe00) | (value2 &0x1ff); + zflag = (result == 0); + break; + + case 5: // movd + cflag = ((uint32_t)value1) < ((uint32_t)value2); + result = (value1 & 0xfffc01ff) | ((value2 &0x1ff) << 9); + zflag = (result == 0); + break; + + case 6: // movi + cflag = ((uint32_t)value1) < ((uint32_t)value2); + result = (value1 & 0x007fffff) | ((value2 &0x1ff) << 23); + zflag = (result == 0); + break; + + case 7: // ret, jmp, call, jmpret + cflag = ((uint32_t)value1) < ((uint32_t)value2); + result = (value1 & 0xfffffe00) | ((pc + 1) & 0x1ff); + //pasmvars->pc = value2 & 0x1ff; + AdjustPipeForJump(pasmvars, value2, 1); + zflag = (result == 0); + break; + } + break; + + // Logical operations + case 3: + switch (opcode & 7) + { + case 0: // test, and + result = value1 & value2; + break; + + case 1: // testn, andn + result = value1 & (~value2); + break; + + case 2: // or + result = value1 | value2; + break; + + case 3: // xor + result = value1 ^ value2; + break; + + case 4: // muxc + result = (value1 & (~value2)) | (value2 & (-cflag)); + break; + + case 5: // muxnc + result = (value1 & (~value2)) | (value2 & (~(-cflag))); + break; + + case 6: // muxz + result = (value1 & (~value2)) | (value2 & (-zflag)); + break; + + case 7: // muxnz + result = (value1 & (~value2)) | (value2 & (~(-zflag))); + break; + } + zflag = (result == 0); + cflag = parity(result); + break; + + // Add and subtract + case 4: + switch (opcode & 7) + { + case 0: // add + result = value1 + value2; + cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + break; + + case 1: // cmp, sub + result = value1 - value2; + cflag = ((uint32_t)value1) < ((uint32_t)value2); + break; + + case 2: // addabs + cflag = (value2 >> 31) & 1; + value2 = abs(value2); + result = value1 + value2; + cflag ^= (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + break; + + case 3: // subabs + result = abs(value2); + cflag = ((value2 >> 31) & 1) ^ + (((uint32_t)value1) < ((uint32_t)result)); + result = value1 - result; + break; + + case 4: // sumc + result = cflag ? value1 - value2 : value1 + value2; + cflag = (~cflag) << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 5: // sumnc + result = cflag ? value1 + value2 : value1 - value2; + cflag = cflag << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 6: // sumz + result = zflag ? value1 - value2 : value1 + value2; + cflag = (~zflag) << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 7: // sumnz + result = zflag ? value1 + value2 : value1 - value2; + cflag = zflag << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + } + zflag = (result == 0); + break; + + // Move, absolute and negate + case 5: + switch (opcode & 7) + { + case 0: // mov + result = value2; + cflag = (value2 >> 31) & 1; + break; + + case 1: // neg + cflag = value2 < 0; + result = -value2; + break; + + case 2: // abs + cflag = (value2 >> 31) & 1; + result = abs(value2); + break; + + case 3: // absneg + cflag = (value2 >> 31) & 1; + result = -abs(value2); + break; + + case 4: // negc + result = cflag ? -value2 : value2; + cflag = (value2 >> 31) & 1; + break; + + case 5: // negnc + result = cflag ? value2 : -value2; + cflag = (value2 >> 31) & 1; + break; + + case 6: // negz + result = zflag ? -value2 : value2; + cflag = (value2 >> 31) & 1; + break; + + case 7: // negnz + result = zflag ? value2 : -value2; + cflag = (value2 >> 31) & 1; + break; + } + zflag = (result == 0); + break; + + // More add and subtract + case 6: + switch (opcode & 7) + { + case 0: // cmps + result = value1 - value2; + cflag = value1 < value2; + zflag = (result == 0); + break; + + case 1: // cmpsx + result = value1 - value2 - cflag; + cflag = value1 < (value2 + cflag); + zflag = (result == 0) & zflag; + break; + + case 2: // addx + result = value1 + value2 + cflag; + cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + + case 3: // cmpx, subx + result = value1 - value2 - cflag; + if (value2 != 0xffffffff || !cflag) + cflag = ((uint32_t)value1) < ((uint32_t)(value2 + cflag)); + zflag = (result == 0) & zflag; + break; + + case 4: // adds + result = value1 + value2; + cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0); + break; + + case 5: // subs + result = value1 - value2; + zflag = (result == 0); + cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 6: // addsx + result = value1 + value2 + cflag; + cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + + case 7: // subsx + result = value1 - value2 - cflag; + cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + } + break; + + // Test and jump and wait ops + case 7: + switch (opcode & 7) + { + case 0: // cmpsub + cflag = (((uint32_t)value1) >= ((uint32_t)value2)); + result = cflag ? value1 - value2 : value1; + zflag = (result == 0); + break; + + case 1: // djnz + result = value1 - 1; + zflag = (result == 0); + cflag = (result == -1); + AdjustPipeForJump(pasmvars, value2, !zflag); + break; + + case 2: // tjnz + result = value1; + zflag = (result == 0); + cflag = 0; + AdjustPipeForJump(pasmvars, value2, !zflag); + break; + + case 3: // tjz + result = value1; + zflag = (result == 0); + cflag = 0; + AdjustPipeForJump(pasmvars, value2, zflag); + break; + + case 4: // waitpeq - result, zflag and cflag not validated + result = (pin_val & value2) ^ value1; + if (result) + { + //pasmvars->state = 6; + //pasmvars->pc = (pasmvars->pc - 1) & 511; + pasmvars->waitflag = 1; + return 0; + } + else + { + //pasmvars->state = 5; + zflag = (result == 0); + cflag = 0; + } + break; + + case 5: // waitpne - result, zflag and cflag not validated + result = (pin_val & value2) ^ value1; + if (!result) + { + //pasmvars->state = 6; + //pasmvars->pc = (pasmvars->pc - 1) & 511; + pasmvars->waitflag = 1; + return 0; + } + else + { + //pasmvars->state = 5; + zflag = (result == 0); + cflag = zflag; + } + break; + + case 6: // waitcnt + result = GetCnt() - value1; + if (result < 0 || result >= 4) + { + //pasmvars->state = 6; + //pasmvars->pc = (pasmvars->pc - 1) & 511; + pasmvars->waitflag = 1; + return 0; + } + else + { + //pasmvars->state = 5; + pasmvars->waitflag = 0; + result = value1 + value2; + zflag = (result == 0); + cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + } + break; + + case 7: // waitvid + break; + } + break; + } + + // Conditionally update flags and write result + if (zcri & 8) pasmvars->zflag = zflag; + if (zcri & 4) pasmvars->cflag = cflag; + if (zcri & 2) + { + //if (dstaddr == 0x1f4) printf("outa = %8.8x\n", result); + pasmvars->mem[dstaddr] = result; + // Check if we need to update the pins + if (dstaddr == 0x1f4 || dstaddr == 0x1f6) UpdatePins(); + } + //CheckSerialOut(pasmvars); + if (pasmvars->waitflag) + { + fprintf(tracefile, "XXXXXXXXXX BAD XXXXXXXXXXXXXXX\n"); + pasmvars->waitflag--; + } + if (pasmvars->printflag) + PrintResults(zcri, zflag, cflag, result); + return result; +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/pasmsim2.c b/pasmsim2.c new file mode 100755 index 0000000..15c9a60 --- /dev/null +++ b/pasmsim2.c @@ -0,0 +1,3377 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include "interp.h" +#include "spinsim.h" + +#define IGNORE_WZ_WC +#define PRINT_RAM_ACCESS + +#define AUX_SIZE 256 +#define AUX_MASK (AUX_SIZE - 1) + +#define REG_INDA 0x1f2 +#define REG_INDB 0x1f3 +#define REG_PINA 0x1f4 +#define REG_PINB 0x1f5 +#define REG_PINC 0x1f6 +#define REG_PIND 0x1f7 +#define REG_OUTA 0x1f8 +#define REG_OUTB 0x1f9 +#define REG_OUTC 0x1fa +#define REG_OUTD 0x1fb +#define REG_DIRA 0x1fc +#define REG_DIRB 0x1fd +#define REG_DIRC 0x1fe +#define REG_DIRD 0x1ff + +extern char *hubram; +extern int32_t memsize; +extern char lockstate[8]; +extern char lockalloc[8]; +extern PasmVarsT PasmVars[8]; +extern int32_t pasmspin; +extern int32_t cycleaccurate; +extern int32_t loopcount; +extern int32_t proptwo; +extern int32_t pin_val; + +extern FILE *tracefile; + +char *GetOpname2(unsigned int, int *); + +void NotImplemented(int instruction) +{ + int dummy; + char *opname = GetOpname2(instruction, &dummy); + printf("\n%s not implemented - %8.8x\n", opname, instruction); + spinsim_exit(1); +} + +static int32_t parity(int32_t val) +{ + val ^= val >> 16; + val ^= val >> 8; + val ^= val >> 4; + val ^= val >> 2; + val ^= val >> 1; + return val & 1; +} + +static int32_t _abs(int32_t val) +{ + return val < 0 ? -val : val; +} + +static int32_t seuss(int32_t value, int32_t forward) +{ + uint32_t a, c, x, y; + + x = value; + if (!x) x = 1; + y = 32; + a = 0x17; + if (!forward) a = (a >> 1) | (a << 31); + while (y--) + { + c = x & a; + while (c & 0xfffffffe) c = (c >> 1) ^ (c & 1); + if (forward) + x = (x >> 1) | (c << 31); + else + x = (x << 1) | c; + } + return x; +} + +uint32_t sqrt32(uint32_t y) +{ + uint32_t x, t1; + + x = 0; + t1 = 1 << 30; + while (t1) + { + x |= t1; + if (x <= y) + { + y -= x; + x += t1; + } + else + x -= t1; + x >>= 1; + t1 >>= 2; + } + return x; +} + +uint32_t sqrt64(uint64_t y) +{ + uint64_t x, t1; + + x = 0; + t1 = 1; + t1 <<= 60; + while (t1) + { + x |= t1; + if (x <= y) + { + y -= x; + x += t1; + } + else + x -= t1; + x >>= 1; + t1 >>= 2; + } + return (uint32_t)x; +} + +int32_t CheckWaitPin(PasmVarsT *pasmvars, int32_t instruct, int32_t value1, int32_t value2) +{ + int32_t match, pin_values; + int32_t portnum = (instruct >> 24) & 3; + + if (portnum == 0) + pin_values = pin_val; + else + pin_values = 0xffffffff; + + if (instruct & 0x04000000) + match = ((pin_values & value2) != value1); // waitpne + else + match = ((pin_values & value2) == value1); // waitpne + + return match; +} + +int wait1[128] = { + 7, 3, 7, 3, 7, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,16,16,16,16, 1,10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13, 0}; + +int wait2[0x120] = { + 6, 0, 6, 0, 0, 0, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, + 12,12,12,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 5, 5, 1, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14,14,14,14, 0, 0, 0, 0, + 15,15,15,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static int32_t CheckWaitFlag2(PasmVarsT *pasmvars, int instruct, int value1, int value2) +{ + int32_t hubcycles; + int32_t waitmode = 0; + int32_t srcaddr = instruct & 511; + int32_t waitflag = pasmvars->waitflag; + int32_t opcode = (instruct >> (32 - 7)) & 127; + int32_t hubop = 0; + + if (waitflag) + { + waitflag--; + if ((instruct & 0xf8000000) == 0xc8000000) + { + if (CheckWaitPin(pasmvars, instruct, value1, value2)) + waitflag = 0; + } + pasmvars->waitflag = waitflag; + if (waitflag == 0) pasmvars->waitmode = 0; + return waitflag; + } + + if (opcode != 127) + waitflag = wait1[opcode]; + else if (srcaddr < 0x120) + waitflag = wait2[srcaddr]; + else + waitflag = 0; + + // if (waitflag) printf("CheckWaitFlag2: %8.8x %d\n", instruct, waitflag); + + hubcycles = (pasmvars->cogid - loopcount) & 7; + + switch (waitflag) + { + case 0: // 1 + break; + + case 1: // 1 - 8 + hubop = 1; + waitflag = hubcycles; + waitmode = WAIT_HUB; + break; + + case 2: // 2 + waitflag = 1; + waitmode = WAIT_MULT; + break; + + case 3: // 1 or 3 - 10 rdxxxxc +//printf("\nvalue2 = %8.8x, dcachehubaddr = %8.8x\n", value2&0xffffffe0, pasmvars->dcachehubaddr); + if ((value2 & 0xfffffe0) == pasmvars->dcachehubaddr) + waitflag = 0; + else + { + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles + 2; + } + break; + + case 4: // 1 or 1 - 8 + if ((value2 & 0xfffffe0) == pasmvars->dcachehubaddr) + waitflag = 0; + else + { + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles; + } + break; + + case 5: // 1 - 9 for lockset and lockclr + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles; + if (instruct & 0x00800000) + waitflag++; + break; + + case 6: // 2 - 9 + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles + 1; + break; + + case 7: // 3 - 10 rdxxxx + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles + 2; + break; + + case 8: // mac + waitflag = 0; + break; + + case 9: // 1 - 9 for cognew or N for waitcnt + if (instruct & 0x01000000) + { + waitmode = WAIT_CNT; + waitflag = value1 - GetCnt(); + } + else + { + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles; + if (instruct & 0x00800000) + waitflag++; + } + break; + + case 10: // 1 - 8 for wrlong or 1 for frac + if (instruct & 0x01000000) + waitflag = 0; + else + { + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles; + } + break; + + case 11: // N for wait + if (!value1) + waitflag = 0; + else + { + waitmode = WAIT_CNT; + waitflag = value1 - 1; + } + break; + + case 12: // mulcount + waitmode = WAIT_MULT; + waitflag = pasmvars->mulcount; + break; + + case 13: // 1 - 8 for callax, callbx + if ((instruct & 0x01800000) == 0x01000000) + { + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles; + } + else + waitflag = 0; + break; + + case 14: // 1 - 8 for callax, callbx + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles; + break; + + case 15: // 2 - 9 for retax, retbx + hubop = 1; + waitmode = WAIT_HUB; + waitflag = hubcycles + 1; + break; + + case 16: // N for waitpxx + waitmode = WAIT_PIN; + waitflag = pasmvars->lastd - GetCnt(); + break; + } + + pasmvars->waitflag = waitflag; + pasmvars->waitmode = waitmode; + + return hubop; +} + +// Compute the hub RAM address from the pointer instruction - SUPIIIIII +int32_t GetPointer(PasmVarsT *pasmvars, int32_t ptrinst, int32_t size) +{ + int32_t address = 0; // Set to zero to avoid compiler warning + int32_t offset = (ptrinst << 26) >> (26 - size); + + switch ((ptrinst >> 6) & 7) + { + case 0: // ptra[offset] + address = (pasmvars->ptra + offset) & 0x3ffff; + break; + + case 1: // ptra + address = pasmvars->ptra; + break; + + case 2: // ptra[++offset] + address = (pasmvars->ptra + offset) & 0x3ffff; + //pasmvars->ptra = address; + pasmvars->ptra0 = address; + break; + + case 3: // ptra[offset++] + address = pasmvars->ptra; + //pasmvars->ptra = (pasmvars->ptra + offset) & 0x3ffff; + pasmvars->ptra0 = (pasmvars->ptra + offset) & 0x3ffff; + break; + + case 4: // ptrb[offset] + address = (pasmvars->ptrb + offset) & 0x3ffff; + break; + + case 5: // ptrb + address = pasmvars->ptrb; + break; + + case 6: // ptrb[++offset] + address = (pasmvars->ptrb + offset) & 0x3ffff; + //pasmvars->ptrb = address; + pasmvars->ptrb0 = address; + break; + + case 7: // ptrb[offset++] + address = pasmvars->ptrb; + //pasmvars->ptrb = (pasmvars->ptrb + offset) & 0x3ffff; + pasmvars->ptrb0 = (pasmvars->ptrb + offset) & 0x3ffff; + break; + } + + return address; +} + +// Compute the aux RAM pointer from the pointer instruction - 1SUPIIIII +int32_t GetAuxPointer(PasmVarsT *pasmvars, int32_t ptrinst) +{ + int32_t address = 0; // Set to zero to avoid compiler warning + int32_t offset = (ptrinst << 27) >> 27; + + switch ((ptrinst >> 5) & 7) + { + case 0: // ptrx[offset] + address = (pasmvars->ptrx + offset) & 255; + break; + + case 1: // ptrx + address = pasmvars->ptrx; + break; + + case 2: // ptrx[++offset] + address = (pasmvars->ptrx + offset) & 255; + pasmvars->ptrx = address; + break; + + case 3: // ptrx[offset++] + address = pasmvars->ptrx; + pasmvars->ptrx = (pasmvars->ptrx + offset) & 255; + break; + + case 4: // ptry[offset] + address = (pasmvars->ptry + offset) & 255; + break; + + case 5: // ptry + address = pasmvars->ptry; + break; + + case 6: // ptry[++offset] + address = (pasmvars->ptry + offset) & 255; + pasmvars->ptry = address; + break; + + case 7: // ptry[offset++] + address = pasmvars->ptry; + pasmvars->ptry = (pasmvars->ptry + offset) & 255; + break; + } + + return address; +} + +void UpdatePins2(void) +{ + int32_t i; + int32_t mask1; + int32_t val = 0; + int32_t mask = 0; + + for (i = 0; i < 8; i++) + { + if (PasmVars[i].state) + { + mask1 = PasmVars[i].mem[REG_DIRA]; // dira + val |= mask1 & PasmVars[i].mem[REG_OUTA]; // outa + mask |= mask1; + } + } + pin_val = (~mask) | val; + //printf("UpdatePins2: %8.8x\n", pin_val); +} + +void CheckIndRegs(PasmVarsT *pasmvars, int32_t instruct, int32_t sflag, int32_t dflag, int32_t *pdstaddr, int32_t *psrcaddr) +{ + int32_t dstaddr = *pdstaddr; + int32_t srcaddr = *psrcaddr; + int32_t cond = (instruct >> 18) & 15; + int32_t opcode_zci = (instruct >> 22) & 0x3ff; + int32_t indirects = (!sflag && (srcaddr & 0x1fe) == 0x1f2); + int32_t indirectd = (!dflag && (dstaddr & 0x1fe) == 0x1f2); + int32_t pre_indexs = cond & 3; + int32_t pre_indexd = cond >> 2; + int32_t post_indexs = pre_indexs; + int32_t post_indexd = pre_indexd; + static int32_t postincrtab[4] = {0, 1, -1, 1}; + int32_t incra = 0; + int32_t incrb = 0; + + // Don't handle fixindx or setindx here + if (opcode_zci == 0x3f0) return; + + // Return if neither source or destination is indirect + if (!indirects && !indirectd) return; + + // Or post-increment indices if source and destination use same register + if (indirects && indirectd && srcaddr == dstaddr) + post_indexs = post_indexd = (pre_indexs | pre_indexd); + + if (indirectd) + { + if (dstaddr == REG_INDA) + { + incra = postincrtab[post_indexd]; + dstaddr = pasmvars->inda + (pre_indexd == 3); + if (dstaddr > pasmvars->indatop) dstaddr = pasmvars->indabot; + } + else + { + incrb = postincrtab[post_indexd]; + dstaddr = pasmvars->indb + (pre_indexd == 3); + if (dstaddr > pasmvars->indbtop) dstaddr = pasmvars->indbbot; + } + } + + if (indirects) + { + if (srcaddr == REG_INDA) + { + incra = postincrtab[post_indexd]; + srcaddr = pasmvars->inda + (pre_indexd == 3); + if (srcaddr > pasmvars->indatop) srcaddr = pasmvars->indabot; + } + else + { + incrb = postincrtab[post_indexd]; + srcaddr = pasmvars->indb + (pre_indexd == 3); + if (srcaddr > pasmvars->indbtop) srcaddr = pasmvars->indbbot; + } + } + + if (incra == 1) + { + if (pasmvars->inda < pasmvars->indatop) + pasmvars->inda0 = pasmvars->inda + 1; + else + pasmvars->inda0 = pasmvars->indabot; + } + else if (incra == -1) + { + if (pasmvars->inda > pasmvars->indabot) + pasmvars->inda0 = pasmvars->inda - 1; + else + pasmvars->inda0 = pasmvars->indatop; + } + + if (incrb == 1) + { + if (pasmvars->indb < pasmvars->indbtop) + pasmvars->indb0 = pasmvars->indb + 1; + else + pasmvars->indb0 = pasmvars->indbbot; + } + else if (incrb == -1) + { + if (pasmvars->indb > pasmvars->indbbot) + pasmvars->indb0 = pasmvars->indb - 1; + else + pasmvars->indb0 = pasmvars->indbtop; + } + + // Update values of srcaddr and dstaddr + *psrcaddr = srcaddr; + *pdstaddr = dstaddr; +} + +#if 0 +void IncrementIndRegs(PasmVarsT *pasmvars) +{ + pasmvars->inda += pasmvars->indaincr; + if (pasmvars->inda > pasmvars->indatop) + pasmvars->inda = pasmvars->indabot; + else if (pasmvars->inda < pasmvars->indabot) + pasmvars->inda = pasmvars->indatop; + + pasmvars->indb += pasmvars->indbincr; + if (pasmvars->indb > pasmvars->indbtop) + pasmvars->indb = pasmvars->indbbot; + else if (pasmvars->indb < pasmvars->indbbot) + pasmvars->indb = pasmvars->indbtop; +} +#endif + +void SaveRegisters(PasmVarsT *pasmvars) +{ + pasmvars->inda0 = pasmvars->inda; + pasmvars->indb0 = pasmvars->indb; + pasmvars->ptra0 = pasmvars->ptra; + pasmvars->ptrb0 = pasmvars->ptrb; +} + +void UpdateRegisters(PasmVarsT *pasmvars) +{ + pasmvars->inda = pasmvars->inda0; + pasmvars->indb = pasmvars->indb0; + pasmvars->ptra = pasmvars->ptra0; + pasmvars->ptrb = pasmvars->ptrb0; +} + +int32_t FetchHubInstruction(PasmVarsT *pasmvars, int32_t prefetch) +{ + int32_t i, j, pc, lineaddr, maxnotused; + + if (prefetch) + pc = (pasmvars->pc1 + 8) & 0xffff; + else + pc = pasmvars->pc & 0xffff; + lineaddr = (pc << 2) & 0x3ffe0; + + // Check if already cached + for (i = 0; i < 4; i++) + { + if (lineaddr == pasmvars->icachehubaddr[i]) break; + } + + // Update usage if not prefetch + if (!prefetch) + { + for (j = 0; j < 4; j++) + { + if (j == i) + pasmvars->icachenotused[j] = 0; + else + { + pasmvars->icachenotused[j]++; + if (pasmvars->icachenotused[j] > 255) + pasmvars->icachenotused[j] = 255; + } + } + } + + // Return if cached + if (i < 4) + return pasmvars->icache[i][pc&7]; + + // Find the least used cache buffer + j = 0; + maxnotused = pasmvars->icachenotused[0]; + for (i = 1; i < 4; i++) + { + if (pasmvars->icachenotused[i] > maxnotused) + { + j = i; + maxnotused = pasmvars->icachenotused[i]; + } + } + + // Fill selected cache buffer and return +#if 0 + if (!prefetch) + printf("FetchHubInstruction: Fetch into cache %d, pc = %4.4x\n", j, pc); + else + printf("FetchHubInstruction: Prefetch into cache %d, pc = %4.4x\n", j, pc); +#endif + if (!prefetch) + { + pasmvars->waitmode = WAIT_CACHE; + pasmvars->waitflag = ((pasmvars->cogid - loopcount) & 7) + 2; + } + pasmvars->icache[j][0] = LONG(lineaddr); + pasmvars->icache[j][1] = LONG(lineaddr + 4); + pasmvars->icache[j][2] = LONG(lineaddr + 8); + pasmvars->icache[j][3] = LONG(lineaddr + 12); + pasmvars->icache[j][4] = LONG(lineaddr + 16); + pasmvars->icache[j][5] = LONG(lineaddr + 20); + pasmvars->icache[j][6] = LONG(lineaddr + 24); + pasmvars->icache[j][7] = LONG(lineaddr + 28); + pasmvars->icachehubaddr[j] = lineaddr; + pasmvars->icachenotused[j] = 0; + return pasmvars->icache[j][pc&7]; +} + +void CheckPrefetch(PasmVarsT *pasmvars) +{ + if (!pasmvars->prefetch) return; + if (pasmvars->cogid != (loopcount & 7)) return; + if (pasmvars->waitmode & WAIT_HUB) return; + if (pasmvars->pc < 0x200) return; + FetchHubInstruction(pasmvars, 1); +} + +int32_t ExecutePasmInstruction2(PasmVarsT *pasmvars) +{ + int32_t cflag = pasmvars->cflag; + int32_t zflag = pasmvars->zflag; + int32_t instruct, pc, cond; + int32_t opcode, value2, value1, zci; + int32_t srcaddr, dstaddr; + int32_t result = 0; + int32_t temp, write_zcr, sflag, dflag, psflag, pdflag; + int32_t opcode_zci, indirect, rflag, aflag; + int32_t returnflag = 0; + int32_t breakflag = 0; + int32_t hubop = 0; + + // Check if multiplier working + if (pasmvars->mulcount) + pasmvars->mulcount--; + + // Check if we can skip further processing if not printing, not waiting + // for a pin state and wait flag is greater than 1. + if (pasmvars->waitflag > 1 && !pasmvars->printflag && pasmvars->waitmode != WAIT_PIN) + { + CheckPrefetch(pasmvars); + pasmvars->waitflag--; + return 0; + } + + // Fetch a new instruction and update the pipeline + if (!pasmvars->waitflag) + { + // Update instruction pipeline and fetch new instruction + pasmvars->instruct4 = pasmvars->instruct3; + pasmvars->instruct3 = pasmvars->instruct2; + pasmvars->instruct2 = pasmvars->instruct1; + if ((pasmvars->pc & 0xfff8) == pasmvars->dcachecogaddr) + pasmvars->instruct1 = pasmvars->dcache[pasmvars->pc & 7]; + else if (pasmvars->pc < 0x200) + pasmvars->instruct1 = pasmvars->mem[pasmvars->pc]; + else if (pasmvars->pc) + pasmvars->instruct1 = FetchHubInstruction(pasmvars, 0); + // Update PC pipeline and increment PC + pasmvars->pc4 = pasmvars->pc3; + pasmvars->pc3 = pasmvars->pc2; + pasmvars->pc2 = pasmvars->pc1; + pasmvars->pc1 = pasmvars->pc; + if (pasmvars->repcnt && pasmvars->pc >= pasmvars->reptop) + { + if (!pasmvars->repforever) pasmvars->repcnt--; + pasmvars->pc = pasmvars->repbot; + } + else + pasmvars->pc = (pasmvars->pc + 1) & 0xffff; + // Check for REPS instruction in the second stage of the pipeline + if ((pasmvars->instruct2 & 0xffc00000) == 0xfac00000 && !(pasmvars->pc2 & INVALIDATE_INSTR)) + { + pasmvars->repcnt = (pasmvars->instruct2 >> 6) & 0xffff; + pasmvars->repbot = pasmvars->pc; + pasmvars->reptop = (pasmvars->pc + (pasmvars->instruct2 & 63)) & 0xffff; + } + } + + // Check for cache wait + if (pasmvars->waitflag && pasmvars->waitmode == WAIT_CACHE) + { + if (--pasmvars->waitflag == 0) + pasmvars->waitmode = 0; + else + { + if (pasmvars->printflag) DebugPasmInstruction2(pasmvars); + return 0; + } + } + + // Get the instruction and pc at the end of the pipeline + instruct = pasmvars->instruct4; + pc = pasmvars->pc4; + + // Return if instruction has been invalidated and not printing + if (pc & INVALIDATE_INSTR) + { + if (!pasmvars->printflag) + { + CheckPrefetch(pasmvars); +#if 0 + if (pasmvars->waitflag) + { + pasmvars->waitflag--; + if (!pasmvars->waitflag) pasmvars->waitmode = 0; + } +#endif + return 0; + } + returnflag = 1; + } + + // Extract bit fields from the instruction + opcode = (instruct >> 25) & 127; + zci = (instruct >> 22) & 7; + cond = (instruct >> 18) & 15; + dstaddr = (instruct >> 9) & 511; + srcaddr = instruct & 511; + opcode_zci = (opcode << 3) | zci; + + // Decode the immediate flags for the source and destination fields + sflag = (opcode_zci >= 0x3ea) | (zci & 1); + + dflag = (opcode >= 0x68 && opcode <= 0x7a && (zci & 2)) | + ((opcode_zci & 0x3e2) == 0x302 && opcode_zci < 0x31e) | + (opcode != 0x7f && opcode_zci >= 0x3eb) | + (opcode == 0x7f && srcaddr >= 0x40 && srcaddr <= 0xdc && (zci & 1)) | + (opcode == 0x7f && srcaddr >= 0x100); + + // Determine if indirect registers are used + indirect = (!sflag && (srcaddr & 0x1fe) == 0x1f2) | + (!dflag && (dstaddr & 0x1fe) == 0x1f2) | + (opcode_zci == 0x3f0); + + // Determine if ptra or ptrb are referenced + psflag = ((opcode < 6) | (opcode_zci >= 0x340 && opcode_zci <= 0x34b)) & sflag; + pdflag = (opcode == 0x7f && srcaddr >= 0x085 && srcaddr <= 0x087 && dflag); + + // Determine if instruction uses relative address + rflag = (((opcode >= 0x54 && opcode <= 0x57) | + (opcode >= 0x76 && opcode <= 0x77) | + (opcode_zci >= 0x3d8 && opcode_zci <= 0x3e8)) & sflag) | + (opcode_zci == 0x3ea); + + // Determine if instruction is AUGS or AUGD + aflag = (opcode_zci >= 0x3ec && opcode_zci <= 0x3ef); + + // Save ptra, ptrb, inda and indb + SaveRegisters(pasmvars); + + // Handle the indirect registers + if (indirect) CheckIndRegs(pasmvars, instruct, sflag, dflag, &dstaddr, &srcaddr); + + // else return if condition code is not met and + // not using indirect registers and not augx instruction + else if (!((cond >> ((cflag << 1) | zflag)) & 1) && !aflag) + { + if (!pasmvars->printflag) + { + CheckPrefetch(pasmvars); +#if 0 + if (pasmvars->waitflag) + { + pasmvars->waitflag--; + if (!pasmvars->waitflag) pasmvars->waitmode = 0; + } +#endif + return 0; + } + returnflag = 1; + } + + // Set the flag that controls writing the result, zero flag and carry flag + write_zcr = zci | 1; // Assume writing result + + // Get value1 from the destination field + if (pdflag) + value1 = GetPointer(pasmvars, dstaddr, 5); + else if (dflag) + { + if (pasmvars->augdflag) + value1 = (pasmvars->augdvalue << 9) | dstaddr; + else + value1 = dstaddr; + } + else if ((dstaddr & 0x1f8) == pasmvars->dcachecogaddr) + value1 = pasmvars->dcache[dstaddr & 7]; + else + value1 = pasmvars->mem[dstaddr]; + + // Get value2 from the source field + if (psflag) + { + if (opcode < 6) + value2 = GetPointer(pasmvars, srcaddr, opcode >> 1); + else + value2 = GetPointer(pasmvars, srcaddr, (opcode_zci >> 2) & 3); + } + else if (sflag) + { + if (pasmvars->augsflag) + value2 = (pasmvars->augsvalue << 9) | srcaddr; + else if (rflag) + value2 = (srcaddr << 23) >> 23; + else + value2 = srcaddr; + } + else if (srcaddr == REG_PINA) + value2 = pin_val; + else if ((srcaddr & 0x1f8) == pasmvars->dcachecogaddr) + value2 = pasmvars->dcache[srcaddr & 7]; + else + value2 = pasmvars->mem[srcaddr]; + + // Check sflag and dflag and reset augsflag and augdflag if needed + if (sflag) pasmvars->augsflag = 0; + if (dflag) pasmvars->augdflag = 0; + + // Check the wait flag if the return flag is not set + if (returnflag) + { + if (pasmvars->waitflag) + { + pasmvars->waitflag--; + if (!pasmvars->waitflag) pasmvars->waitmode = 0; + } + } + else + hubop = CheckWaitFlag2(pasmvars, instruct, value1, value2); + + if (!hubop) + CheckPrefetch(pasmvars); + + // Print instruction if printflag set + if (pasmvars->printflag) DebugPasmInstruction2(pasmvars); + + // Return if returnflag or waitflag is set + if (returnflag || pasmvars->waitflag) return 0; + + // Check for breakpoint + if (pc == pasmvars->breakpnt) + { + if (!pasmvars->printflag) pasmvars->printflag = 15; + DebugPasmInstruction2(pasmvars); + breakflag = 1; + } + + // Update ptra, ptrb, inda and indb + UpdateRegisters(pasmvars); + + // Decode the opcode and execute the instruction + // Set the variables result, zflag and cflag. + // Clear bits within write_zcr to prevent writing variables. + switch(opcode >> 3) // Decode the four most significant bits + { + case 0: // rdxxxx, rdxxxc, rdaux, rdauxr + if (opcode < 6) + { +#if 0 + // Check if using a ptr register + if (sflag) value2 = GetPointer(pasmvars, srcaddr, opcode >> 1); + +#endif + if (opcode & 1) // cache read + { + int32_t hubaddr = value2 & 0xffffffe0; + if (hubaddr != pasmvars->dcachehubaddr) + { + pasmvars->dcache[0] = LONG(hubaddr); + pasmvars->dcache[1] = LONG(hubaddr+4); + pasmvars->dcache[2] = LONG(hubaddr+8); + pasmvars->dcache[3] = LONG(hubaddr+12); + pasmvars->dcache[4] = LONG(hubaddr+16); + pasmvars->dcache[5] = LONG(hubaddr+20); + pasmvars->dcache[6] = LONG(hubaddr+24); + pasmvars->dcache[7] = LONG(hubaddr+28); + pasmvars->dcachehubaddr = hubaddr; + } + } + } + switch(opcode) + { + uint8_t *bptr; + uint16_t *wptr; + + case 0: // rdbyte + result = BYTE(value2); + if (pasmvars->printflag > 1) + fprintf(tracefile, ", rdb[%x]", value2); + break; + + case 1: // rdbytec + bptr = (uint8_t *)pasmvars->dcache; + result = bptr[value2 & 31]; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", rdb[%x]", value2); + break; + + case 2: // rdword + result = WORD(value2); + if (pasmvars->printflag > 1) + fprintf(tracefile, ", rdw[%x]", value2); + break; + + case 3: // rdwordc + wptr = (uint16_t *)pasmvars->dcache; + result = wptr[(value2 >> 1) & 15]; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", rdw[%x]", value2); + break; + + case 4: // rdlong + result = LONG(value2); + if (pasmvars->printflag > 1) + fprintf(tracefile, ", rdl[%x]", value2); + break; + + case 5: // rdlongc + result = pasmvars->dcache[(value2 >> 2) & 7]; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", rdl[%x]", value2); + break; + + case 6: // rdaux + case 7: // rdauxr + if ((zci & 1) && (srcaddr & 0x100)) + temp = GetAuxPointer(pasmvars, srcaddr); + else + temp = value2 & 0xff; + if (opcode & 1) + temp ^= 0xff; + result = pasmvars->auxram[temp]; + break; + } + zflag = (result == 0); + break; + + case 1: // isob, notb, clrb, setbxx + value2 = (value2 & 0x1f); + cflag = (value1 >> value2) & 1; + switch ((value2 >> 5) & 7) + { + case 0: // isob + result = (value1 >> value2) & 1; + break; + + case 1: // notb + result = value1 ^ (1 << value2); + break; + + case 2: // clrb + result = value1 & (~(1 << value2)); + break; + + case 3: // setb + result = value1 | (1 << value2); + break; + + case 4: // setbc + result = value1 & (~(1 << value2)); + result |= cflag << value2; + break; + + case 5: // setbnc + result = value1 & (~(1 << value2)); + result |= (cflag ^ 1) << value2; + break; + + case 6: // setbz + result = value1 & (~(1 << value2)); + result |= zflag << value2; + break; + + case 7: // setbnz + result = value1 & (~(1 << value2)); + result |= (zflag ^ 1) << value2; + break; + } + zflag = (result == 0); + break; + + case 2: // andn, and, or, xor, muxxx + switch (opcode & 7) + { + case 0: // andn + result = value1 & (~value2); + break; + + case 1: // and + result = value1 & value2; + break; + + case 2: // or + result = value1 | value2; + break; + + case 3: // xor + result = value1 ^ value2; + break; + + case 4: // muxc + result = (value1 & (~value2)) | (value2 & (-cflag)); + break; + + case 5: // muxnc + result = (value1 & (~value2)) | (value2 & (~(-cflag))); + break; + + case 6: // muxz + result = (value1 & (~value2)) | (value2 & (-zflag)); + break; + + case 7: // muxnz + result = (value1 & (~value2)) | (value2 & (~(-zflag))); + break; + } + zflag = (result == 0); + cflag = parity(result); + break; + + case 3: // rotate and shift + value2 &= 0x1f; // Get five LSB's + switch (opcode & 7) + { + case 0: // ror + result = (((uint32_t)value1) >> value2) | (value1 << (32 - value2)); + cflag = value1 & 1; + break; + + case 1: // rol + result = (((uint32_t)value1) >> (32 - value2)) | (value1 << value2); + cflag = (value1 >> 31) & 1; + break; + + case 2: // shr + result = (((uint32_t)value1) >> value2); + cflag = value1 & 1; + break; + + case 3: // shl + result = (value1 << value2); + cflag = (value1 >> 31) & 1; + break; + + case 4: // rcr + if (value2) + { + result = (cflag << 31) | (((uint32_t)value1) >> 1); + result >>= (value2 - 1); + } + else + result = value1; + cflag = value1 & 1; + break; + + case 5: // rcl + result = cflag ? (1 << value2) - 1 : 0; + result |= (value1 << value2); + cflag = (value1 >> 31) & 1; + break; + + case 6: // sar + result = value1 >> value2; + cflag = value1 & 1; + break; + + case 7: // rev + cflag = value1 & 1; + value2 = 32 - value2; + result = 0; + while (value2-- > 0) + { + result = (result << 1) | (value1 & 1); + value1 >>= 1; + } + break; + } + zflag = (result == 0); + break; + + case 4: // mov, not abs, negxx + switch (opcode & 7) + { + case 0: // mov + result = value2; + cflag = (value2 >> 31) & 1; + break; + + case 1: // not + cflag = value2 < 0; + result = ~value2; + break; + + case 2: // abs + cflag = (value2 >> 31) & 1; + result = _abs(value2); + break; + + case 3: // neg + cflag = (value2 >> 31) & 1; + result = -value2; + break; + + case 4: // negc + result = cflag ? -value2 : value2; + cflag = (value2 >> 31) & 1; + break; + + case 5: // negnc + result = cflag ? value2 : -value2; + cflag = (value2 >> 31) & 1; + break; + + case 6: // negz + result = zflag ? -value2 : value2; + cflag = (value2 >> 31) & 1; + break; + + case 7: // negnz + result = zflag ? value2 : -value2; + cflag = (value2 >> 31) & 1; + break; + } + zflag = (result == 0); + break; + + case 5: // addxx, subxx + switch (opcode & 7) + { + case 0: // add + result = value1 + value2; + cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + break; + + case 1: // sub + result = value1 - value2; + cflag = ((uint32_t)value1) < ((uint32_t)value2); + break; + + case 2: // addx + result = value1 + value2 + cflag; + cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + + case 3: // subx + result = value1 - value2 - cflag; + if (value2 != 0xffffffff || !cflag) + cflag = ((uint32_t)value1) < ((uint32_t)(value2 + cflag)); + zflag = (result == 0) & zflag; + break; + + case 4: // adds + result = value1 + value2; + cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0); + break; + + case 5: // subs + result = value1 - value2; + zflag = (result == 0); + cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 6: // addsx + result = value1 + value2 + cflag; + cflag = (((~(value1 ^ value2)) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + + case 7: // subsx + result = value1 - value2 - cflag; + cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + } + zflag = (result == 0); + break; + + + case 6: // sumxx, min, max, mins, maxs + switch (opcode & 7) + { + case 0: // sumc + result = cflag ? value1 - value2 : value1 + value2; + cflag = (~cflag) << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 1: // sumnc + result = cflag ? value1 + value2 : value1 - value2; + cflag = cflag << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 2: // sumz + result = zflag ? value1 - value2 : value1 + value2; + cflag = (~zflag) << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 3: // sumnz + result = zflag ? value1 + value2 : value1 - value2; + cflag = zflag << 31; + cflag = (((cflag ^ value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + break; + + case 4: // min + cflag = (((uint32_t)value1) < ((uint32_t)value2)); + zflag = (value2 == 0); + result = cflag ? value2 : value1; + break; + + case 5: // max + cflag = (((uint32_t)value1) < ((uint32_t)value2)); + zflag = (value2 == 0); + result = cflag ? value1 : value2; + break; + + case 6: // mins + cflag = (value1 < value2); + zflag = (value2 == 0); + result = cflag ? value2 : value1; + break; + + case 7: // maxs + cflag = (value1 < value2); + zflag = (value2 == 0); + result = cflag ? value1 : value2; + break; + } + break; + + case 7: // addabs, subabs, incmod, decmod, cmpsub, subr, mul, scl + switch (opcode & 7) + { + case 0: // addabs + cflag = (value2 >> 31) & 1; + value2 = _abs(value2); + result = value1 + value2; + cflag ^= (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + break; + + case 1: // subabs + result = _abs(value2); + cflag = ((value2 >> 31) & 1) ^ + (((uint32_t)value1) < ((uint32_t)result)); + result = value1 - result; + break; + + case 2: // incmod + cflag = (value1 == value2); + if (cflag) + result = 0; + else + result = value1 + 1; + break; + + case 3: // decmod + cflag = (value1 == 0); + if (cflag) + result = value2; + else + result = value1 - 1; + break; + + case 4: // cmpsub + cflag = (((uint32_t)value1) >= ((uint32_t)value2)); + result = cflag ? value1 - value2 : value1; + zflag = (result == 0); + break; + + case 5: // subr + result = value2 - value1; + cflag = ((uint32_t)value2) < ((uint32_t)value1); + break; + + case 6: // mul + value1 = (value1 << 12) >> 12; + value2 = (value2 << 12) >> 12; + result = value1 * value2; + break; + + case 7: // scl + NotImplemented(instruct); + break; + } + zflag = (result == 0); + break; + + case 8: // decodex, encod, blmask, onecnt, zercnt, incpar, decpar, splitx, mergex + switch(opcode&7) + { + case 0: // decod2 + result = 1 << (value1 & 3); + result |= result << 4; + result |= result << 8; + result |= result << 16; + break; + + case 1: // decod3 + result = 1 << (value1 & 7); + result |= result << 8; + result |= result << 16; + break; + + case 2: // decod4 + result = 1 << (value1 & 0xf); + result |= result << 16; + break; + + case 3: // decod5 + result = 1 << (value1 & 0x1f); + break; + + case 4: // encod, blmask + if (!(zci & 2)) // encod + { + for (result = 32; result > 0; result--) + { + if (value2 & 0x80000000) break; + value2 <<= 1; + } + } + else // blmask + { + value1 = (value1 & 0x1f) + 1; + if (value1 == 32) + result = 0xffffffff; + else + result = (1 << value1) - 1; + } + break; + + case 5: // onecnt, zercnt + if (!(zci & 2)) // onecnt + { + for (result = 0; value1; value1 <<= 1) + { + if (value1 & 0x80000000) result++; + } + } + else // zercnt + { + for (result = 32; value1; value1 <<= 1) + { + if (value1 & 0x80000000) result--; + } + } + break; + + case 6: // incpat, decpat + if (!(zci & 4)) // incpat + { + NotImplemented(instruct); + } + else // decpat + { + NotImplemented(instruct); + } + break; + + case 7: //splitb, mergeb, splitw, mergew + switch (zci >> 1) + { + int i; + case 0: // splitb + NotImplemented(instruct); + break; + + case 1: // mergeb + NotImplemented(instruct); + break; + + case 2: // splitw + for (i = 0; i < 16; i++) + { + result = (result << 1) | + ((value1 >> 15)&0x10000) | ((value1 >> 30)&1); + value1 <<= 1; + } + break; + + case 3: // mergew + for (i = 0; i < 16; i++) + { + result = (result << 2) | + ((value1 >> 30) & 2) | ((value1 >> 15) & 1); + value1 <<= 1; + } + break; + } + break; + } + break; + + + case 9: // getnib, setbin, getword, setword, setwrds, rolnib, ... + switch (opcode & 7) + { + case 0: // getnib, setnib + case 1: + case 2: + case 3: + temp = (instruct >> 22) & 0x1c; + if (!(zci&2)) // getnib + { + result = (value1 >> temp) & 15; + } + else // setnib + { + result = (value2 & 15) << temp; + temp = ~(15 << temp); + result |= (value1 & temp); + } + break; + + case 4: // getword, setword + temp = (instruct >> 20) & 16; + if (!(zci&2)) // getword + { + result = (value1 >> temp) & 0xffff; + } + else // setword + { + result = (value2 & 0xffff) << temp; + temp = ~(0xffff << temp); + result |= (value1 & temp); + } + break; + + case 5: // setwrds, rolnib, rolbyte, rolword + NotImplemented(instruct); + break; + + case 6: // sets, setd, setx, seti + switch (zci >> 1) + { + case 0: // sets + result = (value1 & 0xfffffe00) | (value2 &0x1ff); + break; + + case 1: // setd + result = (value1 & 0xfffc01ff) | ((value2 &0x1ff) << 9); + break; + + case 2: // setx + result = (value1 & 0xff83ffff) | ((value2 &0x1f) << 18); + NotImplemented(instruct); + break; + + case 3: // seti + result = (value1 & 0x007fffff) | ((value2 &0x1ff) << 23); + break; + } + write_zcr &= 1; + break; + + case 7: + write_zcr &= 3; + if (!(zci & 4)) // cognew + { + // Look for next available cog + for (result = 0; result < 8; result++) + { + if (!PasmVars[result].state) break; + } + if (result == 8) // None available + { + cflag = 1; + result = 7; + } + else // Start cog + { + cflag = 0; + StartPasmCog2(&PasmVars[result], (value2 & 0x3ffff), (value1 & 0x3fffc), result); + } + } + else // waitcnt + { + if (value1 != GetCnt()) + { + printf("ERROR: waitcnt value1 = %8.8x, cnt = %8.8x\n", value1, GetCnt()); + spinsim_exit(1); + } + result = value1 + value2; + zflag = (result == 0); + cflag = (((value1 & value2) | ((value1 | value2) & (~result))) >> 31) & 1; + } + break; + } + break; + + case 10: // getbyte, setbyte, movbyts, xxxxrgb, xxxpix, jmpxx, xjxx + switch (opcode & 7) + { + case 0: // getbyte, setbyte + case 1: + temp = (instruct >> 21) & 0x18; + if (!(zci&2)) // getbyte + { + result = (value1 >> temp) & 255; + } + else // setbyte + { + result = (value2 & 255) << temp; + temp = ~(255 << temp); + result |= (value1 & temp); + } + break; + + case 2: // setbyts, movbyts, packrgb, unpkrgb + NotImplemented(instruct); + break; + + case 3: // addpix, mulpix, blnpix, mixpix + NotImplemented(instruct); + break; + + case 4: // jmpsw + case 5: // jmpswd + if (zci&1) + pasmvars->pc = (pc + value2) & 0xffff; + else + pasmvars->pc = value2 & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + pc += 4; + result = pc; + zflag = (result == 0); + cflag = 0; + break; + + case 6: // ijz, ijzd, ijnz, ijnzd + result = value1 + 1; + zflag = (result == 0); + cflag = (result == 0); + // Determine if we should jump + if (zflag != (zci >> 2)) + { + if (instruct & 0x00400000) + pasmvars->pc = (pc + value2) & 0xffff; + else + pasmvars->pc = value2 & 0xffff; + // Invalidate the instruction pipeline if non-delayed jump + if (!(zci & 2)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + } + write_zcr &= 1; + break; + + case 7: // djz, djzd, djnz, djnzd + result = value1 - 1; + zflag = (result == 0); + cflag = (result == -1); + // Determine if we should jump + if (zflag != (zci >> 2)) + { + if (instruct & 0x00400000) + pasmvars->pc = (pc + value2) & 0xffff; + else + pasmvars->pc = value2 & 0xffff; + // Invalidate the instruction pipeline if non-delayed jump + if (!(zci & 2)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + } + write_zcr &= 1; + break; + } + break; + + case 11: // testxx, cmpxx + write_zcr &= 6; + switch (opcode & 7) + { + case 0: // testb + NotImplemented(instruct); + break; + + case 1: // testn + result = value1 & (~value2); + zflag = (result == 0); + cflag = parity(result); + break; + + case 2: // test + result = value1 & value2; + zflag = (result == 0); + cflag = parity(result); + break; + + case 3: // cmp + //printf("\ncmp $%x $%x\n", value1, value2); + result = value1 - value2; + zflag = (result == 0); + cflag = ((uint32_t)value1) < ((uint32_t)value2); + break; + + case 4: // cmpx + result = value1 - value2 - cflag; + if (value2 != 0xffffffff || !cflag) + cflag = ((uint32_t)value1) < ((uint32_t)(value2 + cflag)); + zflag = (result == 0) & zflag; + break; + + case 5: // cmps + //printf("\ncmps $%x $%x\n", value1, value2); + result = value1 - value2; + zflag = (result == 0); + cflag = value1 < value2; + break; + + case 6: // cmpsx + result = value1 - value2 - cflag; + cflag = (((value1 ^ value2) & (value1 ^ result)) >> 31) & 1; + zflag = (result == 0) & zflag; + break; + + case 7: // cmpr + NotImplemented(instruct); + break; + } + break; + + case 12: // coginit, waitvid, waitpeq, waitpne + switch (opcode & 7) + { + case 0: // coginit, waitvid + case 1: + case 2: + case 3: + if (!(zci&2)) // coginit + { + result = (instruct >> 24) & 7; + //printf("\ncoginit: cog = %d, value1 = %8.8x, dflag = %d\n", result, value1, dflag); + StartPasmCog2(&PasmVars[result], (value2 & 0x3ffff), (value1 & 0x3fffc), result); + UpdatePins2(); + // Return without saving if we restarted this cog + if (result == pasmvars->cogid) return breakflag; + } + else // waitvid + { + NotImplemented(instruct); + } + write_zcr = 0; + break; + + case 4: // waitpeq + case 5: + case 6: // waitpne + case 7: + write_zcr &= 2; + cflag = !CheckWaitPin(pasmvars, instruct, value1, value2); + break; + } + break; + + case 13: // wrxxx, frac, setaccx, macx, mul32x, div32x, div64x + temp = ((opcode & 7) << 1) | (zci >> 2); + +#if 0 + if (temp <= 2) + { + // Check if using a ptr register + if (sflag) value2 = GetPointer(pasmvars, srcaddr, temp & 3); + } + +#endif + switch (temp) + { + case 0: // wrbyte + BYTE(value2) = value1; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", wrb[%x] = %x", value2, value1); + break; + + case 1: // wrword + WORD(value2) = value1; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", wrw[%x] = %x", value2, value1); + break; + + case 2: // wrlong + LONG(value2) = value1; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", wrl[%x] = %x", value2, value1); + break; + + case 3: // frac + if (value2) + { + pasmvars->divq = ((uint64_t)value1 << 32) / (uint64_t)value2; + pasmvars->divr = ((uint64_t)value1 << 32) % (uint64_t)value2; + } + else + { + pasmvars->divq = 0; + pasmvars->divr = 0; + } + break; + + case 4: // wraux + case 5: // wrauxr + if ((zci & 1) && (srcaddr & 0x100)) + temp = GetAuxPointer(pasmvars, srcaddr); + else + temp = value2 & 0xff; + if (opcode & 1) + temp ^= 0xff; + pasmvars->auxram[temp] = value1; + break; + + case 6: // setacca + pasmvars->acca = (((int64_t)value1) << 32) | (uint64_t)value2; + break; + + case 7: // setaccb + pasmvars->accb = (((int64_t)value1) << 32) | (uint64_t)value2; + break; + + case 8: // maca + value1 = (value1 << 12) >> 12; + value2 = (value2 << 12) >> 12; + pasmvars->acca += (int64_t)value1 * (int64_t)value2; + break; + + case 9: // macb + value1 = (value1 << 12) >> 12; + value2 = (value2 << 12) >> 12; + pasmvars->accb += (int64_t)value1 * (int64_t)value2; + break; + + case 10: // mul32 + pasmvars->mulcount = 17; + pasmvars->mul = (int64_t)value1 * (int64_t)value2; + break; + + case 11: // mul32u + pasmvars->mulcount = 17; + pasmvars->mul = (uint64_t)value1 * (uint64_t)value2; + break; + + case 12: // div32 + pasmvars->mulcount = 17; + if (value2) + { + pasmvars->divq = value1 / value2; + pasmvars->divr = value1 % value2; + } + else + { + pasmvars->divq = 0; + pasmvars->divr = 0; + } + break; + + case 13: // div32u + pasmvars->mulcount = 17; + if (value2) + { + pasmvars->divq = (uint32_t)value1 / (uint32_t)value2; + pasmvars->divr = (uint32_t)value1 % (uint32_t)value2; + } + else + { + pasmvars->divq = 0; + pasmvars->divr = 0; + } + break; + + case 14: // div64 + pasmvars->mulcount = 17; + if (pasmvars->divisor) + { + pasmvars->divq = ((((int64_t)value1) << 32) | (uint64_t)value2) / (int64_t)pasmvars->divisor; + pasmvars->divr = ((((int64_t)value1) << 32) | (uint64_t)value2) % (int64_t)pasmvars->divisor; + } + else + { + pasmvars->divq = 0; + pasmvars->divr = 0; + } + break; + + case 15: // div64u + pasmvars->mulcount = 17; + if (pasmvars->divisor) + { + pasmvars->divq = ((((uint64_t)value1) << 32) | (uint64_t)value2) / (uint64_t)pasmvars->divisor; + pasmvars->divr = ((((uint64_t)value1) << 32) | (uint64_t)value2) % (uint64_t)pasmvars->divisor; + } + else + { + pasmvars->divq = 0; + pasmvars->divr = 0; + } + break; + } + write_zcr = 0; + break; + + case 14: // sqrt64, qsincos, qarctan, qrotate, setserx, setctrs, ... + temp = ((opcode & 7) << 1) | (zci >> 2); + switch (temp) + { + case 0: // sqrt64 + write_zcr = 0; + pasmvars->mulcount = 32; + pasmvars->sqrt = sqrt64(((uint64_t)value1<<32) | (uint32_t)value2); + break; + + case 1: // qsincos + NotImplemented(instruct); + break; + + case 2: // qartan + NotImplemented(instruct); + break; + + case 3: // qrotate + NotImplemented(instruct); + break; + + case 4: // setsera + NotImplemented(instruct); + break; + + case 5: // setserb + NotImplemented(instruct); + break; + + case 6: // setctrs + NotImplemented(instruct); + break; + + case 7: // setwavs + NotImplemented(instruct); + break; + + case 8: // setfrqs + NotImplemented(instruct); + break; + + case 9: // setphss + NotImplemented(instruct); + break; + + case 10: // addphss + NotImplemented(instruct); + break; + + case 11: // subphss + NotImplemented(instruct); + break; + + case 12: // jp + case 13: // jpd + if (value1 < 32 && ((pin_val >> value1) & 1)) + { + if (instruct & 0x10000) + pasmvars->pc = (pc + value2) & 0xffff; + else + pasmvars->pc = value2 & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + } + break; + + case 14: // jnp + case 15: // jnpd + if (value1 < 32 && !((pin_val >> value1) & 1)) + { + if (instruct & 0x10000) + pasmvars->pc = (pc + value2) & 0xffff; + else + pasmvars->pc = value2 & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + } + break; + } + write_zcr = 0; + break; + + case 15: + switch(opcode & 7) + { + case 0: // cfgpins + case 1: // cfgpins, jmptask + NotImplemented(instruct); + break; + + case 2: // setxft, setmix + NotImplemented(instruct); + break; + + case 3: // jz, jzd, jnz, jnzd + if ((value1 == 0) != (zci >> 2)) + { + if (instruct & 0x00400000) + pasmvars->pc = (pc + value2) & 0xffff; + else + pasmvars->pc = value2 & 0xffff; + // Invalidate the instruction pipeline if non-delayed jump + if (!(zci & 2)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + } + write_zcr = 0; + break; + + case 4: // locbase, locbyte, locword, loclong + if (sflag) + result = (pc + value2) << 2; + else + result = value2 << 2; + switch (zci >> 1) + { + case 0: // locbase + result &= 0x3ffff; + break; + + case 1: // locbyte + result = (result + value1) & 0x3ffff; + break; + + case 2: // locword + result = (result + (value1 << 1)) & 0x3ffff; + break; + + case 3: // loclong + result = (result + (value1 << 2)) & 0x3ffff; + break; + } + break; + + case 5: // jmplist, locinst, reps, augs, augd + switch (zci) + { + case 0: // jmplist + case 1: + NotImplemented(instruct); + break; + + case 2: // locinst + NotImplemented(instruct); + break; + + case 3: // reps + break; + + case 4: // augs + case 5: + pasmvars->augsflag = 1; + pasmvars->augsvalue = instruct & 0x007fffff; + break; + + case 6: // augd + case 7: + pasmvars->augdflag = 1; + pasmvars->augdvalue = instruct & 0x007fffff; + break; + } + write_zcr = 0; + break; + + case 6: // fixindx, setindx, locptrx, jmpx, callx, callax, callbx, callxx, callyx + switch (zci) + { + case 0: // fixindx, setindx + switch (cond & 3) // Handle inda + { + case 0: + break; + + case 1: // fixinda + pasmvars->inda = srcaddr; + if (srcaddr < dstaddr) + { + pasmvars->indabot = srcaddr; + pasmvars->indatop = dstaddr; + } + else + { + pasmvars->indabot = dstaddr; + pasmvars->indatop = srcaddr; + } + break; + + case 2: // setindb #addr + pasmvars->inda = srcaddr; + pasmvars->indabot = 0; + pasmvars->indatop = 511; + break; + + case 3: // setindb ++/--delt + pasmvars->inda = (pasmvars->inda + ((srcaddr << 23) >> 23)) & 511; + pasmvars->indabot = 0; + pasmvars->indatop = 511; + break; + } + switch (cond >> 2) // Handle indb + { + case 0: + break; + + case 1: // fixindb + pasmvars->indb = srcaddr; + if (srcaddr < dstaddr) + { + pasmvars->indbbot = srcaddr; + pasmvars->indbtop = dstaddr; + } + else + { + pasmvars->indbbot = dstaddr; + pasmvars->indbtop = srcaddr; + } + break; + + case 2: // setindb #addr + pasmvars->indb = dstaddr; + pasmvars->indbbot = 0; + pasmvars->indbtop = 511; + break; + + case 3: // setindb ++/--delt + pasmvars->indb = (pasmvars->indb + ((dstaddr << 23) >> 23)) & 511; + pasmvars->indbbot = 0; + pasmvars->indbtop = 511; + } + break; + + case 1: // locptra, locptrb + switch ((instruct >> 16) & 3) + { + case 0: // locptra #abs + pasmvars->ptra = (instruct & 0xffff) << 2; + break; + + case 1: // locptra @rel + pasmvars->ptra = ((pc + instruct) & 0xffff) << 2; + break; + + case 2: // locptrb #abs + pasmvars->ptrb = (instruct & 0xffff) << 2; + break; + + case 3: // locptrb @rel + pasmvars->ptrb = ((pc + instruct) & 0xffff) << 2; + break; + } + break; + + case 2: // jmp, jmpd + if (instruct & 0x10000) + pasmvars->pc = (pc + instruct) & 0xffff; + else + pasmvars->pc = instruct & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 3: // call, calld + if (instruct & 0x10000) + pasmvars->pc = (pc + instruct) & 0xffff; + else + pasmvars->pc = instruct & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + pc += 4; + pc |= (pasmvars->zflag << 17) | (pasmvars->cflag << 16); + pasmvars->retstack[pasmvars->retptr] = pc; + pasmvars->retptr = (pasmvars->retptr + 1) & 3; + if (pasmvars->retptr == 0) + printf("return stack overflow\n"); + break; + + case 4: // calla, callad + if (instruct & 0x10000) + pasmvars->pc = (pc + instruct) & 0xffff; + else + pasmvars->pc = instruct & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + { + pc += 4; + } + pc |= (pasmvars->zflag << 17) | (pasmvars->cflag << 16); + LONG(pasmvars->ptra) = pc; + pasmvars->ptra = (pasmvars->ptra + 4) & 0x3ffff; + break; + + case 5: // callb, callbd + if (instruct & 0x10000) + pasmvars->pc = (pc + instruct) & 0xffff; + else + pasmvars->pc = instruct & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + { + pc += 4; + } + pc |= (pasmvars->zflag << 17) | (pasmvars->cflag << 16); + LONG(pasmvars->ptrb) = pc; + pasmvars->ptrb = (pasmvars->ptrb + 4) & 0x3ffff; + break; + + case 6: // callx, callxd + if (instruct & 0x10000) + pasmvars->pc = (pc + instruct) & 0xffff; + else + pasmvars->pc = instruct & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + pc += 4; + pc |= (pasmvars->zflag << 17) | (pasmvars->cflag << 16); + pasmvars->auxram[pasmvars->ptrx] = pc; + pasmvars->ptrx = (pasmvars->ptrx + 1) & AUX_MASK; + break; + + case 7: // cally, callyd + if (instruct & 0x10000) + pasmvars->pc = (pc + instruct) & 0xffff; + else + pasmvars->pc = instruct & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct & 0x20000)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + pc += 4; + pc |= (pasmvars->zflag << 17) | (pasmvars->cflag << 16); + pasmvars->auxram[pasmvars->ptry^255] = pc; + pasmvars->ptry = (pasmvars->ptry + 1) & AUX_MASK; + break; + } + write_zcr = 0; + break; + + case 7: + if ((instruct&511) >= 0x40 && (instruct&511) <= 0xdc) + { + write_zcr &= 6; + if (zci & 1) + value1 = (instruct >> 9) & 511; + } + + switch ((instruct >> 6) & 7) + { + case 0: + switch (instruct & 511) + { + case 0x000: // cogid + result = pasmvars->cogid; + break; + + case 0x001: // taskid + NotImplemented(instruct); + break; + + case 0x002: // locknew + for (result = 0; result < 8; result++) + { + if (!lockalloc[result]) break; + } + if (result == 8) + { + cflag = 1; + result = 7; + } + else + { + cflag = 0; + lockalloc[result] = 1; + } + zflag = (result == 0); + break; + + case 0x003: // getlfsr + NotImplemented(instruct); + break; + + case 0x004: // getcnt + result = GetCnt(); + zflag = (result == 0); + cflag = 0; + break; + + case 0x005: // getcntx + NotImplemented(instruct); + break; + + case 0x006: // getacal + result = pasmvars->acca & 0xffffffff; + break; + + case 0x007: // getacah + result = pasmvars->acca >> 32; + break; + + case 0x008: // getacbl + result = pasmvars->accb & 0xffffffff; + break; + + case 0x009: // getacbh + result = pasmvars->accb >> 32; + break; + + case 0x00a: // getptra + result = pasmvars->ptra; + zflag = (result == 0); + cflag = 0; + break; + + case 0x00b: // getptrb + result = pasmvars->ptrb; + zflag = (result == 0); + cflag = 0; + break; + + case 0x00c: // getptrx + result = pasmvars->ptrx; + break; + + case 0x00d: // getptry + result = pasmvars->ptry; + break; + + case 0x00e: // serina + NotImplemented(instruct); + break; + + case 0x00f: // serinb + NotImplemented(instruct); + break; + + case 0x010: // getmull + result = pasmvars->mul & 0xffffffff; + zflag = (result == 0); + cflag = 0; + break; + + case 0x011: // getmulh + result = (pasmvars->mul >> 32) & 0xffffffff; + zflag = (result == 0); + cflag = 0; + break; + + case 0x012: // getdivq + result = pasmvars->divq; + zflag = (result == 0); + cflag = 0; + break; + + case 0x013: // getdivr + result = pasmvars->divr; + zflag = (result == 0); + cflag = 0; + break; + + case 0x014: // getsqrt + result = pasmvars->sqrt; + zflag = (result == 0); + cflag = 0; + break; + + case 0x015: // getqx + NotImplemented(instruct); + break; + + case 0x016: // getqy + NotImplemented(instruct); + break; + + case 0x017: // getqz + NotImplemented(instruct); + break; + + case 0x018: // getphsa + NotImplemented(instruct); + break; + + case 0x019: // getphza + NotImplemented(instruct); + break; + + case 0x01a: // getcosa + NotImplemented(instruct); + break; + + case 0x01b: // getsina + NotImplemented(instruct); + break; + + case 0x01c: // getphsb + NotImplemented(instruct); + break; + + case 0x01d: // getphzb + NotImplemented(instruct); + break; + + case 0x01e: // getcosb + NotImplemented(instruct); + break; + + case 0x01f: // getsinb + NotImplemented(instruct); + break; + + case 0x020: // pushzc + result = (value1 << 2) | (zflag << 1) | cflag; + zflag = (value1 >> 31) & 1; + cflag = (value1 >> 30) & 1; + break; + + case 0x021: // popzc + result = ((value1 >> 2) & 0x3fffffff) | (zflag << 31) | (cflag << 30); + zflag = (value1 >> 1) & 1; + cflag = value1 & 1; + break; + + case 0x022: // subcnt + result = GetCnt() - value1; + cflag = (result >> 31) & 1; + zflag = (result == 0); + NotImplemented(instruct); + break; + + case 0x023: // getpix + NotImplemented(instruct); + break; + + case 0x024: // binbcd + NotImplemented(instruct); + break; + + case 0x025: // bcdbin + NotImplemented(instruct); + break; + + case 0x026: // bingry + result = value1 ^ ((value1 >> 1) & 0x7fffffff); + break; + + case 0x027: // grybin + NotImplemented(instruct); + break; + + case 0x028: // eswap4 + NotImplemented(instruct); + break; + + case 0x029: // eswap8 + NotImplemented(instruct); + break; + + case 0x02a: // seussf + result = seuss(value1, 1); + break; + + case 0x02b: // seussr + result = seuss(value1, 0); + break; + + case 0x02c: // incd + result = value1 + 0x200; + zflag = (result == 0); + write_zcr &= 5; + break; + + case 0x02d: // decd + result = value1 - 0x200; + zflag = (result == 0); + write_zcr &= 5; + break; + + case 0x02e: // incds + result = value1 + 0x201; + zflag = (result == 0); + write_zcr &= 5; + break; + + case 0x02f: // decds + result = value1 - 0x201; + zflag = (result == 0); + write_zcr &= 5; + break; + + case 0x030: // pop + pasmvars->retptr = (pasmvars->retptr - 1) & 3; + pasmvars->retstack[pasmvars->retptr] = value1; + if (pasmvars->retptr == 3) + printf("return stack underflow\n"); + break; + + default: + NotImplemented(instruct); + break; + } + break; + + case 1: // repd + if ((instruct & 0xffc3fe00) == 0xfe03fe00) + { + pasmvars->repcnt = 1; + pasmvars->repforever = 1; + } + else + pasmvars->repcnt = value1; + pasmvars->repbot = (pasmvars->pc) & 0xffff; + pasmvars->reptop = (pasmvars->pc + (srcaddr & 63)) & 0xffff; + break; + + case 2: + write_zcr = 0; + switch (instruct & 511) + { + case 0x080: // clkset + result = value1 & 0x1ff; + if (result & 0x100) + { + RebootProp(); + return breakflag; + } + break; + + case 0x081: // cogstop + PasmVars[value1&7].state = 0; + UpdatePins2(); + break; + + case 0x082: // lockset + result = value1 & 7; + cflag = lockstate[result] & 1; + lockstate[result] = -1; + write_zcr = (zci & 2); + break; + + case 0x083: // lockclr + result = value1 & 7; + cflag = lockstate[result] & 1; + lockstate[result] = 0; + write_zcr = (zci & 2); + break; + + case 0x084: // lockret + for (result = 0; result < 8; result++) + { + if (!lockalloc[result]) break; + } + cflag = (result == 8); + result = value1 & 7; + zflag = (result == 0); + lockalloc[result] = 0; + break; + + case 0x085: // rdwidec + case 0x086: // rdwide +#if 0 + // Check if using a ptr register + if (zci & 1) value1 = GetPointer(pasmvars, dstaddr, 5); +#endif + value1 &= 0xffffffe0; + if (!(instruct & 1) || value1 != pasmvars->dcachehubaddr) + { + pasmvars->dcache[0] = LONG(value1); + pasmvars->dcache[1] = LONG(value1+4); + pasmvars->dcache[2] = LONG(value1+8); + pasmvars->dcache[3] = LONG(value1+12); + pasmvars->dcache[4] = LONG(value1+16); + pasmvars->dcache[5] = LONG(value1+20); + pasmvars->dcache[6] = LONG(value1+24); + pasmvars->dcache[7] = LONG(value1+28); + pasmvars->dcachehubaddr = value1; + } +#if 0 + fprintf(tracefile, "rdwide(%8.8x) %8.8x %8.8x %8.8x %8.8x\n", + value1, pasmvars->dcache[0], pasmvars->dcache[1], + pasmvars->dcache[2], pasmvars->dcache[3]); +#endif + write_zcr = 0; + break; + + case 0x087: // wrwide +#if 0 + // Check if using a ptr register + if (zci & 1) value1 = GetPointer(pasmvars, dstaddr, 5); +#endif + value1 &= 0xffffffe0; + LONG(value1) = pasmvars->dcache[0]; + LONG(value1+4) = pasmvars->dcache[1]; + LONG(value1+8) = pasmvars->dcache[2]; + LONG(value1+12) = pasmvars->dcache[3]; + LONG(value1+16) = pasmvars->dcache[4]; + LONG(value1+20) = pasmvars->dcache[5]; + LONG(value1+24) = pasmvars->dcache[6]; + LONG(value1+28) = pasmvars->dcache[7]; +#if 0 + fprintf(tracefile, "wrwide(%8.8x) %8.8x %8.8x %8.8x %8.8x\n", + value1, pasmvars->dcache[0], pasmvars->dcache[1], + pasmvars->dcache[2], pasmvars->dcache[3]); +#endif + write_zcr = 0; + break; + + case 0x088: // getp + if (value1 < 32) + cflag = (pin_val >> value1) & 1; + else + cflag = 1; + zflag = cflag ^ 1; + write_zcr = (zci & 6); + break; + + case 0x089: // getnp + if (value1 < 32) + zflag = (pin_val >> value1) & 1; + else + zflag = 1; + cflag = zflag ^ 1; + write_zcr = (zci & 6); + break; + + case 0x08a: // serouta + NotImplemented(instruct); + break; + + case 0x08b: // seroutb + NotImplemented(instruct); + break; + + case 0x08c: // cmpcnt + result = GetCnt() - value1; + cflag = (result >> 31) & 1; + zflag = (result == 0); + write_zcr = (zci & 6); + break; + + case 0x08d: // waitpx + NotImplemented(instruct); + break; + + case 0x08e: // waitpr + NotImplemented(instruct); + break; + + case 0x08f: // waitpf + NotImplemented(instruct); + break; + + case 0x090: // setzc + zflag = (value1 >> 1) & 1; + cflag = value1 & 1; + write_zcr = (zci & 6); + break; + + case 0x091: // setmap + NotImplemented(instruct); + break; + + case 0x092: // setxch + NotImplemented(instruct); + break; + + case 0x093: // settask + NotImplemented(instruct); + break; + + case 0x094: // setrace + NotImplemented(instruct); + break; + + case 0x095: // saracca + pasmvars->acca >>= (value1 & 63); + write_zcr = 0; + break; + + case 0x096: // saraccb + pasmvars->accb >>= (value1 & 63); + write_zcr = 0; + break; + + case 0x097: // saraccs + pasmvars->acca >>= (value1 & 63); + pasmvars->accb >>= (value1 & 63); + write_zcr = 0; + break; + + case 0x098: // setptra + pasmvars->ptra = value1 & 0x3ffff; + write_zcr = 0; + break; + + case 0x099: // setptrb + pasmvars->ptrb = value1 & 0x3ffff; + write_zcr = 0; + break; + + case 0x09a: // addptra + pasmvars->ptra = (pasmvars->ptra + value1) & 0x3ffff; + write_zcr = 0; + break; + + case 0x09b: // addptrb + pasmvars->ptrb = (pasmvars->ptrb + value1) & 0x3ffff; + break; + + case 0x09c: // subptra + pasmvars->ptra = (pasmvars->ptra - value1) & 0x3ffff; + break; + + case 0x09d: // subptrb + pasmvars->ptrb = (pasmvars->ptrb - value1) & 0x3ffff; + break; + + case 0x09e: // setwide + pasmvars->dcachecogaddr = value1 & 0x1f8; + break; + + case 0x09f: // setwidz + NotImplemented(instruct); + break; + + case 0x0a0: // setptrx + pasmvars->ptrx = value1 & 255; + break; + + case 0x0a1: // setptry + pasmvars->ptry = value1 & 255; + break; + + case 0x0a2: // addptrx + pasmvars->ptrx = (pasmvars->ptrx + value1) & 255; + break; + + case 0x0a3: // addptry + pasmvars->ptry = (pasmvars->ptry + value1) & 255; + break; + + case 0x0a4: // subptrx + pasmvars->ptrx = (pasmvars->ptrx - value1) & 255; + break; + + case 0x0a5: // subptry + pasmvars->ptry = (pasmvars->ptry - value1) & 255; + break; + + case 0x0a6: // passcnt + NotImplemented(instruct); + break; + + case 0x0a7: // wait + write_zcr = 0; + break; + + case 0x0a8: // offp + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] &= ~(1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + result = pasmvars->mem[dstaddr] & ~(1 << (value1 & 31)); + break; + + case 0x0a9: // notp + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + result = pasmvars->mem[dstaddr] ^ (1 << (value1 & 31)); + break; + + case 0x0aa: // clrp + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + result = pasmvars->mem[dstaddr] & ~(1 << (value1 & 31)); + break; + + case 0x0ab: // setp + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + result = pasmvars->mem[dstaddr] | (1 << (value1 & 31)); + break; + + case 0x0ac: // setpc + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + if (pasmvars->cflag) + result = pasmvars->mem[dstaddr] | (1 << (value1 & 31)); + else + result = pasmvars->mem[dstaddr] & ~(1 << (value1 & 31)); + break; + + case 0x0ad: // setpnc + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + if (!pasmvars->cflag) + result = pasmvars->mem[dstaddr] | (1 << (value1 & 31)); + else + result = pasmvars->mem[dstaddr] & ~(1 << (value1 & 31)); + break; + + case 0x0ae: // setpz + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + if (pasmvars->zflag) + result = pasmvars->mem[dstaddr] | (1 << (value1 & 31)); + else + result = pasmvars->mem[dstaddr] & ~(1 << (value1 & 31)); + break; + + case 0x0af: // setpnz + write_zcr = 1; + dstaddr = ((value1 & 127) >> 5) + REG_DIRA; + pasmvars->mem[dstaddr] |= (1 << (value1 & 31)); + dstaddr = ((value1 & 127) >> 5) + REG_OUTA; + if (!pasmvars->zflag) + result = pasmvars->mem[dstaddr] | (1 << (value1 & 31)); + else + result = pasmvars->mem[dstaddr] & ~(1 << (value1 & 31)); + break; + + case 0x0b0: // div64d + write_zcr = 0; + pasmvars->divisor = value1; + break; + + case 0x0b1: // sqrt32 + write_zcr = 0; + pasmvars->mulcount = 16; + pasmvars->sqrt = sqrt32(value1); + break; + + case 0x0b2: // qlog + NotImplemented(instruct); + break; + + case 0x0b3: // qexp + NotImplemented(instruct); + break; + + case 0x0b4: // setqi + NotImplemented(instruct); + break; + + case 0x0b5: // setqz + NotImplemented(instruct); + break; + + case 0x0b6: // cfgdacs + NotImplemented(instruct); + break; + + case 0x0b7: // setdacs + NotImplemented(instruct); + break; + + case 0x0b8: // cfgdac0 + NotImplemented(instruct); + break; + + case 0x0b9: // cfgdac1 + NotImplemented(instruct); + break; + + case 0x0ba: // cfgdac2 + NotImplemented(instruct); + break; + + case 0x0bb: // cfgdac3 + NotImplemented(instruct); + break; + + case 0x0bc: // setdac0 + NotImplemented(instruct); + break; + + case 0x0bd: // setdac1 + NotImplemented(instruct); + break; + + case 0x0be: // setdac2 + NotImplemented(instruct); + break; + + case 0x0bf: // setdac3 + NotImplemented(instruct); + break; + + default: + NotImplemented(instruct); + break; + } + break; + + case 3: + write_zcr = 0; + switch (instruct & 511) + { + case 0x0c0: // setctra + NotImplemented(instruct); + break; + + case 0x0c1: // setwava + NotImplemented(instruct); + break; + + case 0x0c2: // setfrqa + NotImplemented(instruct); + break; + + case 0x0c3: // setphsa + NotImplemented(instruct); + break; + + case 0x0c4: // addphsa + NotImplemented(instruct); + break; + + case 0x0c5: // subphsa + NotImplemented(instruct); + break; + + case 0x0c6: // setvid + NotImplemented(instruct); + break; + + case 0x0c7: // setvidy + NotImplemented(instruct); + break; + + case 0x0c8: // setctrb + NotImplemented(instruct); + break; + + case 0x0c9: // setwavb + NotImplemented(instruct); + break; + + case 0x0ca: // setfrqb + NotImplemented(instruct); + break; + + case 0x0cb: // setphsb + NotImplemented(instruct); + break; + + case 0x0cc: // addphsb + NotImplemented(instruct); + break; + + case 0x0cd: // subphsb + NotImplemented(instruct); + break; + + case 0x0ce: // setvidi + NotImplemented(instruct); + break; + + case 0x0cf: // setvidq + NotImplemented(instruct); + break; + + case 0x0d0: // setpix + NotImplemented(instruct); + break; + + case 0x0d1: // setpixz + NotImplemented(instruct); + break; + + case 0x0d2: // setpixu + NotImplemented(instruct); + break; + + case 0x0d3: // setpixv + NotImplemented(instruct); + break; + + case 0x0d4: // setpixa + NotImplemented(instruct); + break; + + case 0x0d5: // setpixr + NotImplemented(instruct); + break; + + case 0x0d6: // setpixg + NotImplemented(instruct); + break; + + case 0x0d7: // setpixb + NotImplemented(instruct); + break; + + case 0x0d8: // setpora + NotImplemented(instruct); + break; + + case 0x0d9: // setporb + NotImplemented(instruct); + break; + + case 0x0da: // setporc + NotImplemented(instruct); + break; + + case 0x0db: // setpord + NotImplemented(instruct); + break; + + case 0x0dc: // push + pasmvars->retstack[pasmvars->retptr] = value1; + pasmvars->retptr = (pasmvars->retptr + 1) & 3; + if (pasmvars->retptr == 0) + printf("return stack overflow\n"); + break; + + case 0x0f4: // jmp + case 0x0f5: // jmpd + pasmvars->pc = value1 & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 0x0f6: // call + case 0x0f7: // calld + pasmvars->pc = value1 & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + pc++; + } + else + pc += 4; + pc |= (pasmvars->zflag << 17) | (pasmvars->cflag << 16); + pasmvars->retstack[pasmvars->retptr] = pc; + pasmvars->retptr = (pasmvars->retptr + 1) & 3; + if (pasmvars->retptr == 0) + printf("return stack overflow\n"); + break; + + case 0x0f8: // calla + NotImplemented(instruct); + break; + + case 0x0f9: // callad + NotImplemented(instruct); + break; + + case 0x0fa: // callb + NotImplemented(instruct); + break; + + case 0x0fb: // callbd + NotImplemented(instruct); + break; + + case 0x0fc: // callx + NotImplemented(instruct); + break; + + case 0x0fd: // callxd + NotImplemented(instruct); + break; + + case 0x0fe: // cally + NotImplemented(instruct); + break; + + case 0x0ff: // callyd + NotImplemented(instruct); + break; + + default: + NotImplemented(instruct); + break; + } + break; + + case 4: + write_zcr &= 6; + switch (instruct & 511) + { + case 0x100: // reta + case 0x101: // retad + pasmvars->ptra = (pasmvars->ptra - 4) & 0x3ffff; + result = LONG(pasmvars->ptra); + cflag = (result >> 16) & 1; + zflag = (result >> 17) & 1; + pasmvars->pc = result & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 0x102: // retb + case 0x103: // retbd + pasmvars->ptrb = (pasmvars->ptrb - 4) & 0x3ffff; + result = LONG(pasmvars->ptrb); + cflag = (result >> 16) & 1; + zflag = (result >> 17) & 1; + pasmvars->pc = result & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 0x104: // retx + case 0x105: // retxd + pasmvars->ptrx = (pasmvars->ptrx - 1) & AUX_MASK; + result = pasmvars->auxram[pasmvars->ptrx]; + cflag = (result >> 16) & 1; + zflag = (result >> 17) & 1; + pasmvars->pc = result & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 0x106: // rety + case 0x107: // retyd + pasmvars->ptry = (pasmvars->ptry - 1) & AUX_MASK; + result = pasmvars->auxram[pasmvars->ptry^255]; + cflag = (result >> 16) & 1; + zflag = (result >> 17) & 1; + pasmvars->pc = result & 0xffff; + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 0x108: // ret + case 0x109: // retd + pasmvars->retptr = (pasmvars->retptr - 1) & 3; + result = pasmvars->retstack[pasmvars->retptr]; + cflag = (result >> 16) & 1; + zflag = (result >> 17) & 1; + pasmvars->pc = result & 0xffff; + if (pasmvars->retptr == 3) + printf("return stack underflow\n"); + // Invalidate the instruction pipeline if non-delayed + if (!(instruct&1)) + { + pasmvars->pc1 |= INVALIDATE_INSTR; + pasmvars->pc2 |= INVALIDATE_INSTR; + pasmvars->pc3 |= INVALIDATE_INSTR; + } + break; + + case 0x10a: // polctra + NotImplemented(instruct); + break; + + case 0x10b: // polctrb + NotImplemented(instruct); + break; + + case 0x10c: // polvid + NotImplemented(instruct); + break; + + case 0x10d: // capctra + NotImplemented(instruct); + write_zcr = 0; + break; + + case 0x10e: // capctrb + NotImplemented(instruct); + write_zcr = 0; + break; + + case 0x10f: // capctrs + NotImplemented(instruct); + write_zcr = 0; + break; + + case 0x110: // setpixw + NotImplemented(instruct); + write_zcr = 0; + break; + + case 0x111: // clracca + pasmvars->acca = 0; + write_zcr = 0; + break; + + case 0x112: // clraccb + pasmvars->accb = 0; + write_zcr = 0; + break; + + case 0x113: // clraccs + pasmvars->acca = 0; + pasmvars->accb = 0; + write_zcr = 0; + break; + + case 0x114: // chkptrx + zflag = (pasmvars->ptrx == 0); + cflag = (pasmvars->ptrx >> 7) & 1; + break; + + case 0x115: // chkptry + zflag = (pasmvars->ptry == 0); + cflag = (pasmvars->ptry >> 7) & 1; + break; + + case 0x116: // synctra + NotImplemented(instruct); + write_zcr = 0; + break; + + case 0x117: // synctrb + NotImplemented(instruct); + write_zcr = 0; + break; + + case 0x118: // dcachex + pasmvars->dcachehubaddr = 0xffffffff; + write_zcr = 0; + break; + + case 0x119: // icachex + pasmvars->icachehubaddr[0] = 0xffffffff; + pasmvars->icachehubaddr[1] = 0xffffffff; + pasmvars->icachehubaddr[2] = 0xffffffff; + pasmvars->icachehubaddr[3] = 0xffffffff; + write_zcr = 0; + break; + + case 0x11a: // icachep + pasmvars->prefetch = 1; + write_zcr = 0; + break; + + case 0x11b: // icachen + pasmvars->prefetch = 0; + write_zcr = 0; + break; + + default: + NotImplemented(instruct); + write_zcr = 0; + break; + } + break; + + default: + NotImplemented(instruct); + break; + } + } + } + + // Conditionally update flags and write result + if (write_zcr & 4) + { + pasmvars->zflag = zflag; + if (pasmvars->printflag > 1) fprintf(tracefile, ", z = %d", zflag); + } + if (write_zcr & 2) + { + pasmvars->cflag = cflag; + if (pasmvars->printflag > 1) fprintf(tracefile, ", c = %d", cflag); + } + if (write_zcr & 1) + { + pasmvars->lastd = result; + if ((dstaddr & 0x1f8) == pasmvars->dcachecogaddr) + { + pasmvars->dcache[dstaddr & 7] = result; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", dcache[%d] = %x", dstaddr & 7, result); + } + else + { + pasmvars->mem[dstaddr] = result; + if (pasmvars->printflag > 1) + fprintf(tracefile, ", cram[%x] = %x", dstaddr, result); + } + // Check if we need to update the pins + if (dstaddr >= REG_OUTA && dstaddr <= REG_DIRD) UpdatePins2(); + } + if (pasmvars->waitflag) + { + fprintf(tracefile, "XXXXXXXXXX BAD XXXXXXXXXXXXXXX\n"); + pasmvars->waitflag--; + if (!pasmvars->waitflag) pasmvars->waitmode = 0; + } + return breakflag; +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/pfth103_p2/bufser.fth b/pfth103_p2/bufser.fth new file mode 100755 index 0000000..53e6bc4 --- /dev/null +++ b/pfth103_p2/bufser.fth @@ -0,0 +1,89 @@ +\ Define data space that will be used by the serial cog +create bufserstack 40 allot \ Data stack space +create bufserreturn 40 allot \ Return stack space +create bufserbuffer 32 allot \ Serial buffer +create bufserrdindex 0 , \ Read index +create bufserwrindex 0 , \ Write index + +\ This word runs in a separate cog and writes input characters into the buffer +: bufsercog + bufserbuffer + begin + getchar over bufserwrindex @ + c! + bufserwrindex dup @ 1 + 31 and swap ! + again ; + +\ This word replaces the old KEY word with one that reads from the buffer +: bufkey + bufserrdindex @ + begin + dup + bufserwrindex @ + - + until + bufserbuffer + c@ + bufserrdindex dup @ 1 + 31 and swap ! + ; + +\ This is the cog configuration structure used by the serial cog +create bufserconfig \ Forth cog config structure + ' bufsercog >body , \ Get execution token for TOGGLE + bufserstack , \ Initial value of stack ptr + bufserstack , \ Empty value for stack ptr + bufserreturn , \ Initial value of return ptr + bufserreturn , \ Empty value for return ptr + +\ This word starts a cog running the BUFSER word +: startbufsercog forth @ bufserconfig cognew ; + +\ This word starts the serial cog and sets key to the new one +: bufser startbufsercog ['] bufkey is key ; + +\ Buffer the serial input into memory until an ESC is received +: bufferit here 256 + dup + ." Buffering serial input to memory" cr + ." Enter to exit" cr + begin + key dup 27 <> + while + over c! 1+ + repeat + drop over - + \ over infile cog! +; + +\ Determine the length of the current line +: linelen ( addr count -- addr len ) + >r dup ( addr ptr ) ( left ) + begin + r@ 0 <= + if over - r> drop exit then + dup c@ dup 10 = swap 13 = or + if over - r> drop exit then + 1+ r> 1- >r + again +; + +\ Variables to store the buffer address and count +variable evalbufaddr +variable evalbufcount + +\ Evaluate a buffer containing multiple lines +: evalbuf ( addr count ) + evalbufcount ! + evalbufaddr ! + begin + evalbufcount @ 0 > + while + evalbufaddr @ evalbufcount @ + linelen + dup 1+ dup + evalbufaddr @ + evalbufaddr ! + evalbufcount @ swap - evalbufcount ! + over over type cr + evaluate + repeat +; + +\ Redefine switch to use buffered serial +\ : switch bufser ; diff --git a/pfth103_p2/changes.txt b/pfth103_p2/changes.txt new file mode 100755 index 0000000..05e8826 --- /dev/null +++ b/pfth103_p2/changes.txt @@ -0,0 +1,94 @@ + Changes in pfth 1.03 + +1. Added umod and u/ words + +2. Fixed the #, udmod and ud/ words to handle numbers with the MSB set. + These changes fix a problem with the u. word when the MSB is set. + +3. Fixed the putch PASM routine so that it only writes P30 in OUTA + + + Changes in pfth 1.02 + +1. Added ospfth.spin, which runs under Spinix + +2. Added support for two simultaneous open files + +3. Added bye and reboot words + +4. Added sub-directory support + +5. Added CD word to change the working directory + +6. Modified the s" word to work in the interpretation mode + +7. Added a kernel word to make constants and values more efficient + + + Changes in pfth 1.00 + +1. Fixed the FOR and NEXT words + +2. Fixed a bug in UNLOOP + +3. Added create-file, file-write, file-line, file-flush, file-close and + delete-file + +4. Added linux.fth that implements simple ls, rm, cp and cat commands + +5. Added sdutils.fth that contains some file utilities + +6. Added TED -- a tiny text editor + +7. Changed SAVE to EESAVE in i2c.fth + + + Changes in pfth 0.89 + +1. Changed the dictionary word structure to use 16-bit pointers instead of 32 + bits. + +2. Changed the execution list in compiled words to use 16-bit execution tokens + instead of 32 bits. + +3. Changed the positions of the code pointer and DOES pointer to make the inner + loop more efficient. It now runs about 25% faster. + +4. Changed SEE back to printing "_lit" for numbers. + +5. Implemented a _loop kernel word to make DO-LOOP faster. + + + Changes in pfth 0.83 + +1. Changed SEE in see.fth so that it doesn't print "_lit" for numbers + +2. Added bufser.fth that contains a buffered serial driver + +3. Added a BUFFERIT word in bufser.fth that reads the serial input into memory + until it encounters an "ESC" character. + +4. Added an EVALBUF word in bufser.fth that will evaluate multiple lines in a + memory buffer + +5. Updated the readme.txt file with text contributed by Loopy + +6. Updated the readme.txt file with a description of the dictionary word format + +7. Added a SAVE word to i2c.fth that will write the current hub RAM image to + EEPROM. Note: The small Spin program at the end of memory must have been + preserved for this to boot properly. + +8. Changed the CR word so that it emits both a carriage return and a line feed. + +9. Added CASE, ENDCASE, OF and ENDOF to init.fth + +10. Improved WAITCNT and MS in propwords.fth. Removed INA! + +11. Fixed LIST-FILES in sd.fth to skip over deleted files in the directory + +12. Changed the execution token so that it points to the code pointer instead + of the beginning of the word in the dictionary + +13. Made KEY a deferred word so that it can be re-assigned to the serial input + after reading the FILEs in memory diff --git a/pfth103_p2/chess.fth b/pfth103_p2/chess.fth new file mode 100755 index 0000000..d832ffb --- /dev/null +++ b/pfth103_p2/chess.fth @@ -0,0 +1,608 @@ +\ This program was written by Lennart Benschop and converted to ANS Forth by +\ by Jeff Fox. It was further modified by Dave Hein to run under pfth. The +\ orignal source is available at http://www.ultatechnology.com/chess.html. + +HEX + +: scroll cr ; +: cls page ; +: key? 1 ; +: off false swap ! ; +: >defer 2 + w@ 4 - ; + +3 constant maxlevel +create bp0 +maxlevel 1 + c0 * allot + +variable bpv + +: bp bpv @ ; +: b@ bpv @ + c@ ; +: b! bpv @ + c! ; + +: boardvar create , + does> c@ bpv @ + ; + 0c boardvar start + 0d boardvar castlew + 0e boardvar castleb + 0f boardvar ep + 1c boardvar starting + 1d boardvar piece + 1e boardvar best + 1f boardvar farther? + 2c boardvar wlcastle? + 2d boardvar blcastle? + 2e boardvar check + 2f boardvar pawnmove + 3c boardvar kingw + 3d boardvar kingb + 3e boardvar inpassing + 3f boardvar advance + 4c boardvar valuew + 5c boardvar alfa + 6c boardvar beta + 7c boardvar (eval) + 8c boardvar highest + 9c boardvar cutoff + ac boardvar valueb + bc boardvar played + +variable level + +variable lastcnt + +: +level + bp dup c0 + c0 cmove + c0 bpv +! 1 level +! ; + +: -level + -c0 bpv +! -1 level +! ; + + +create symbols + + CHAR . , CHAR p , CHAR k , CHAR b , + CHAR r , CHAR q , CHAR K , + +create values + 0 , 40 , c0 , c0 , 140 , 240 , 3000 , + +: .board + cls + 0 0 at-xy 20 spaces + cr 2 spaces + [CHAR] H 1 + [CHAR] A do i emit 2 spaces loop + bp 20 + 8 0 do + cr 20 spaces + cr [CHAR] 8 i - emit + 0a 2 do space + dup i + c@ dup + 07 and cells symbols + 1 type + dup 80 and if ." W" drop else + if ." B" else ." ." then + then + loop + 10 + + loop cr drop ; + +: .pos + 10 /mod + swap 2 - [CHAR] A + emit + [CHAR] 8 2 + swap - emit ; + +\ constants that indicate the directions on the board +-11 constant nw -0f constant no + 0f constant zw 11 constant zo +-10 constant n 10 constant z + -1 constant w 1 constant o + +create spring +-12 , -21 , -1f , -0e , 12 , 21 , 1f , 0e , + +defer tmove + +defer attacktest + +: mine? + b@ dup 0= 0= swap 80 and start c@ = and ; + +variable movits + +: moveit + starting c@ best c! 1 farther? c! + begin + best c@ over + dup best c! + dup mine? over b@ 87 = or 0= + farther? c@ and while + tmove + b@ 0= farther? c! + repeat + drop drop + 1 movits +! ; + +: Bishop + no nw zo zw moveit moveit moveit moveit ; + +: Rook + n o z w moveit moveit moveit moveit ; + +: Queen + n o z w no nw zo zw 8 0 do moveit loop ; + +: Knight + 8 0 do + i cells spring + @ + starting c@ + dup best c! + dup mine? swap b@ 87 = or 0= + if tmove then + loop ; + +: ?castle + start c@ 80 = if castlew else castleb then c@ check c@ 0= and ; + +: ?lcastle + start c@ 80 = if wlcastle? else blcastle? then c@ check c@ 0= and ; + +: king + n o z w no nw zo zw 8 0 do + starting c@ + dup best c! + dup mine? swap b@ 87 = or 0= + if tmove then + loop + ?castle if 28 start c@ if 70 + then + dup bp + 1- @ 0= + if + dup 1- attacktest 0= + if + best c! tmove + else drop then + else drop then + then + ?lcastle if 24 start c@ if 70 + then + dup bp + @ over bp + 1- @ or 0= + if + dup 1 + attacktest 0= + if + best c! tmove + else drop then + else drop then + then ; + +: Pawnrow + start c@ if negate then ; + +: Pawnz + dup best c! + f0 and start c@ if 20 else 90 then = + if 6 2 do i advance c! tmove loop + else tmove then + 0 pawnmove c! 0 inpassing c! 0 advance c! ; + +: Pawn + starting c@ z Pawnrow + + dup b@ if + drop + else + dup Pawnz + z Pawnrow + dup b@ if + drop + else + starting c@ f0 and + start c@ if 80 else 30 then = + if starting c@ 0f and pawnmove c! + Pawnz + else drop + then + then + then + zw zo 2 0 do + Pawnrow starting c@ + + dup f0 and start c@ if 40 else 70 then = + over 0f and ep c@ = and + if 1 inpassing c! + dup Pawnz + then + dup b@ dup 0= 2 pick mine? or + swap 87 = or + if drop else Pawnz then + loop ; + +create pieces + + ' noop , ' Pawn , ' Knight , ' Bishop , ' Rook , ' Queen , ' king , + +: piecemove +\ using above jump table for each type of piece - jump table uses , (CELLS) + piece c@ cells pieces + @ execute ; + +: ?piecemove + starting c@ dup mine? if + b@ 07 and piece c! + 0 pawnmove c! 0 inpassing c! 0 advance c! + piecemove + else drop then ; + +: allmoves + [char] . emit + start c@ 0= if + 22 starting c! + 8 0 do + 8 0 do + ?piecemove starting c@ 1 + starting c! + loop + starting c@ 8 + starting c! + loop + else + 92 starting c! + 8 0 do + 8 0 do + ?piecemove starting c@ 1 + starting c! + loop + starting c@ 18 - starting c! + loop + then ; + +variable attack + +: ?attack + best c@ dup mine? 0= + swap b@ 07 and piece c@ = and + attack @ or attack ! ; + +: attacked? + attack off 0 7 1 do + i piece c! + piecemove + attack @ if drop 1 leave then + loop ; + +variable starting' +variable best' +variable start' +variable tmove' + +: settest + starting c@ starting' c! + best c@ best' c! + start c@ start' c! + ['] tmove >defer tmove' ! + ['] ?attack is tmove ; + +: po@ + starting' c@ starting c! + best' c@ best c! + start' c@ start c! + tmove' @ is tmove ; + +: changecolor + start c@ 80 xor start c! ; + +variable endf +variable playlevel +variable #legal +variable selected +variable compcolor +variable move# + +create bp1 c0 allot + +: endgame? + start c@ if valueb else valuew then @ c1 < ; + +: evalboard + valueb @ valuew @ - start c@ if negate then + 55 mine? 1 and + 56 mine? 1 and + 65 mine? 1 and + 66 mine? 1 and + + changecolor 55 mine? + 56 mine? + 65 mine? + 66 mine? + changecolor + + endgame? if + start c@ if kingb else kingw then c@ + dup f0 and dup 20 = swap 90 = or 7 and + swap 0f and dup 2 = swap 9 = or 7 and + + + then ; + +: ?check + settest + start c@ if kingw else kingb then c@ + starting c! attacked? check c! + po@ ; + +: (attacktest) + ['] tmove >defer ['] ?attack <> if + settest + starting c! + attacked? + po@ + else drop true + then ; + +' (attacktest) is attacktest + +variable seed + +: rnd + seed @ 743 * 43 + dup seed ! ; +\ 1 ; + +: domove + best c@ b@ 7 and cells values + @ negate start c@ + if valueb else valuew then +! + starting c@ b@ best c@ b! + 0 starting c@ b! + advance c@ if + advance c@ dup cells values + @ 40 - start c@ + if valueb else valueb then +! + start c@ or best c@ b! + then + piece c@ 4 = if + starting c@ 0f and 2 = + if + 0 start c@ if wlcastle? else blcastle? then c! + then + starting c@ 0f and 9 = + if + 0 start c@ if castlew else castleb then c! + then + then + piece c@ 6 = if + 0 0 start c@ if castlew else castleb then dup >r c! + r> 1f + c! + best c@ starting c@ - 2 = + if + 4 start c@ or best c@ 1- b! + 0 best c@ 1 + b! + then + best c@ starting c@ - -2 = + if + 4 start c@ or best c@ 1 + b! + 0 best c@ 2 - b! + then + best c@ start c@ if kingw else kingb then c! + then + inpassing c@ if + 0 best c@ n Pawnrow + b! + -40 start c@ if valueb else valuew then +! + then + pawnmove c@ ep c! ; + +: deeper + cutoff @ + invert if + +level + domove + ?check check c@ if -level exit then + -1 played c0 - ! + level @ playlevel @ = if + evalboard + (eval) c0 - ! + else + alfa @ highest ! + alfa @ negate beta @ negate alfa ! beta ! + changecolor + 0 played ! + allmoves + played @ 0= if + ?check check c@ if -2000 highest ! else 0 highest ! then + then + highest @ negate + (eval) c0 - ! + then + -level + (eval) @ highest @ max + highest ! + highest @ beta @ > if TRUE cutoff ! then + + + then ; + +: analyse + +level + domove + ?check check c@ 0= if + 1 #legal +! + changecolor + ['] tmove >defer + ['] deeper is tmove + 0 played ! + allmoves + is tmove + played @ 0= if + ?check check c@ if -2000 highest ! else 0 highest ! then + then + highest @ beta c0 - @ = if + rnd 2000 > if #legal @ selected ! then + then + highest @ beta c0 - @ < if + #legal @ selected ! + highest @ beta c0 - ! + then + then + -level ; + +: select + +level + domove + ?check check c@ 0= if + 1 #legal +! + #legal @ selected @ = if + bp bp1 c0 cmove + starting c@ .pos ." -" best c@ .pos space + then + then + -level ; + +: against + +level + domove + ?check check c@ 0= if + 1 #legal +! + then + -level ; + +: compmove + .board + ['] analyse is tmove + 0 #legal ! + -4000 alfa ! 4000 beta ! + +\ 0 18 at-xy cr + scroll + + \ 28 spaces + start c@ if 1 move# +! move# @ 3 .r space else 4 spaces then + ?check check c@ if ." Check" then + 1 selected ! + allmoves + #legal @ 0= if + check c@ if + ." mate" + else + ." Pat" + then + TRUE endf ! + else + ['] select is tmove + 0 #legal ! + allmoves + bp1 bp0 c0 cmove + changecolor + ['] against is tmove + 0 #legal ! + allmoves + ?check check c@ if ." Check" then + #legal @ 0= if + check c@ if + ." mate" + else + ." Pat" + then + TRUE endf ! + then + then + .board ; + +variable startingm +variable bestm +variable personmove + +: legal + startingm @ starting c@ = + bestm @ best c@ = and + personmove @ advance c@ = and + if + +level + domove + ?check check c@ 0= if + 1 #legal ! + bp bp1 c0 cmove + then + -level + then ; + +create inputbuf 6 allot + +: inpos + dup inputbuf + c@ [CHAR] A - + dup 8 u< + rot inputbuf + 1 + c@ [CHAR] 1 - + dup 8 u< rot and + swap 7 swap - 10 * rot + 22 + ; + +: promote + 0 6 2 do over symbols i cells + c@ = if drop i then loop ; + +: person + begin + .board + + scroll + + \ 28 spaces + start c@ if 1 move# +! move# @ 3 .r else 3 spaces then + + inputbuf 5 expect cr + + \ [char] X emit inputbuf 5 type [char] X emit + + inputbuf c@ [CHAR] Q = if quit then + 0 inpos startingm ! + 2 inputbuf + c@ [CHAR] - = and + 3 inpos bestm ! + and + bestm @ f0 and start c@ if 20 else 90 then = + startingm b@ 07 and 1 = and + if + ." What piece? " 0 0 begin drop drop key promote dup until + personmove ! emit + else + 0 personmove ! + then + if + ['] legal is tmove + 0 #legal ! + startingm c@ starting c! ?piecemove + #legal @ + else + 0 + then + dup 0= start c@ and if -1 move# +! then + until + bp1 bp0 c0 cmove + changecolor + + cr + + .board ; + +: setmove + compcolor @ 0< start c@ 80 = = if compmove else person then ; + +variable manVsMachine + +: askcolor + manVSmachine @ + if ." Do you want White Y/N" + key dup [CHAR] Y = swap [CHAR] y = or + if 1 else -1 then compcolor ! + then ; + +: asklevel + cr ." Level? 2-" + maxlevel . key [CHAR] 0 - 2 max maxlevel min playlevel ! + cls ; + +: init + 0 level ! bp0 bpv ! + bp c0 87 fill + 4 2 3 6 5 3 2 4 8 0 do bp 22 + i + c! loop + bp 32 + 8 01 fill + bp 42 + 8 00 fill bp 52 + 8 00 fill + bp 62 + 8 00 fill bp 72 + 8 00 fill + bp 82 + 8 81 fill + 84 82 83 86 85 83 82 84 8 0 do bp 92 + i + c! loop + 1 castlew c! 1 castleb c! 0 ep c! 1 wlcastle? c! 1 blcastle? c! 0 advance c! + 80 start c! 96 kingw c! 26 kingb c! + askcolor cr asklevel + 0 move# ! 0 endf ! + 0 check c! 9c0 valuew ! 9c0 valueb ! ; + +: play + begin setmove endf @ until ; + +: games + begin init play again ; + +: autoplay + begin setmove compcolor @ negate compcolor ! key? if quit then endf @ until ; + +: auto + init -1 compcolor ! autoplay ; + +: chess + cls + ." ANS Forth Chess" cr + ." Do you want to play against the computer? Y/N" cr + begin rnd drop key? until key + dup [CHAR] Y = swap [CHAR] y = or dup manVsMachine ! + if games else auto then ; + +decimal diff --git a/pfth103_p2/chkcore.fth b/pfth103_p2/chkcore.fth new file mode 100755 index 0000000..139e90e --- /dev/null +++ b/pfth103_p2/chkcore.fth @@ -0,0 +1,145 @@ +( This program checks for all 133 ANS Forth core words ) + +: checkword 1 + ' 0 = + if swap 1 + swap source type ." failed" 13 emit 10 emit then ; + +: checkdone swap dup + if swap dup rot rot swap - . ." out of " + else drop ." All " then + . ." ANS Forth core words implemented" 13 emit 10 emit ; + +0 0 +checkword ! +checkword # +checkword #> +checkword #S +checkword ' +checkword ( +checkword * +checkword */ +checkword */MOD +checkword + +checkword +! +checkword +LOOP +checkword , +checkword - +checkword . +checkword ." +checkword / +checkword /MOD +checkword 0< +checkword 0= +checkword 1+ +checkword 1- +checkword 2! +checkword 2* +checkword 2/ +checkword 2@ +checkword 2DROP +checkword 2DUP +checkword 2OVER +checkword 2SWAP +checkword : +checkword ; +checkword < +checkword <# +checkword = +checkword > +checkword >BODY +checkword >IN +checkword >NUMBER +checkword >R +checkword ?DUP +checkword @ +checkword ABORT +checkword ABORT" +checkword ABS +checkword ACCEPT +checkword ALIGN +checkword ALIGNED +checkword ALLOT +checkword AND +checkword BASE +checkword BEGIN +checkword BL +checkword C! +checkword C, +checkword C@ +checkword CELL+ +checkword CELLS +checkword CHAR +checkword CHAR+ +checkword CHARS +checkword CONSTANT +checkword COUNT +checkword CR +checkword CREATE +checkword DECIMAL +checkword DEPTH +checkword DO +checkword DOES> +checkword DROP +checkword DUP +checkword ELSE +checkword EMIT +checkword ENVIRONMENT? +checkword EVALUATE +checkword EXECUTE +checkword EXIT +checkword FILL +checkword FIND +checkword FM/MOD +checkword HERE +checkword HOLD +checkword I +checkword IF +checkword IMMEDIATE +checkword INVERT +checkword J +checkword KEY +checkword LEAVE +checkword LITERAL +checkword LOOP +checkword LSHIFT +checkword M* +checkword MAX +checkword MIN +checkword MOD +checkword MOVE +checkword NEGATE +checkword OR +checkword OVER +checkword POSTPONE +checkword QUIT +checkword R> +checkword R@ +checkword RECURSE +checkword REPEAT +checkword ROT +checkword RSHIFT +checkword S" +checkword S>D +checkword SIGN +checkword SM/REM +checkword SOURCE +checkword SPACE +checkword SPACES +checkword STATE +checkword SWAP +checkword THEN +checkword TYPE +checkword U. +checkword U< +checkword UM* +checkword UM/MOD +checkword UNLOOP +checkword UNTIL +checkword VARIABLE +checkword WHILE +checkword WORD +checkword XOR +checkword [ +checkword ['] +checkword [CHAR] +checkword ] +checkdone diff --git a/pfth103_p2/chkcorex.fth b/pfth103_p2/chkcorex.fth new file mode 100755 index 0000000..b0c2717 --- /dev/null +++ b/pfth103_p2/chkcorex.fth @@ -0,0 +1,57 @@ +( This program checks for all 45 ANS Forth core ext words ) + +: checkword 1 + ' 0 = + if swap 1 + swap source type ." failed" 13 emit 10 emit then ; + +: checkdone swap dup + if swap dup rot rot swap - . ." out of " + else drop ." All " then + . ." ANS Forth core ext words implemented" 13 emit 10 emit ; + +0 0 +checkword #tib +checkword .( +checkword .r +checkword 0<> +checkword 0> +checkword 2>r +checkword 2r> +checkword 2r@ +checkword :noname +checkword <> +checkword ?do +checkword again +checkword c" +checkword case +checkword compile, +checkword convert +checkword endcase +checkword endof +checkword erase +checkword expect +checkword false +checkword hex +checkword marker +checkword nip +checkword of +checkword pad +checkword parse +checkword pick +checkword query +checkword refill +checkword restore-input +checkword roll +checkword save-input +checkword source-id +checkword span +checkword tib +checkword to +checkword true +checkword tuck +checkword u.r +checkword u> +checkword value +checkword within +checkword [compile] +checkword \ +checkdone diff --git a/pfth103_p2/comus.fth b/pfth103_p2/comus.fth new file mode 100755 index 0000000..b876b67 --- /dev/null +++ b/pfth103_p2/comus.fth @@ -0,0 +1,29 @@ +( Useful non-standard words ) +: @+ dup cell+ swap @ ; +: !+ over ! cell+ ; +: c@+ dup char+ swap c@ ; +: c!+ over c! char+ ; +: between 1+ within ; +: bounds over + swap ; +: buffer: create allot ; +: cell 4 ; +: cell- cell - ; +: not 0= ; +: parse-word bl word count ; +: perform @ execute ; +: >= < 0= ; +: <= > 0= ; +: -rot rot rot ; +: 2- 2 - ; +: 2+ 2 + ; +: 3dup dup 2over rot ; +: 4dup 2over 2over ; +: noop ; +: off false swap ! ; +: on true swap ! ; +: for ['] >r compile, ['] _lit compile, 0 compile, ['] >r compile, here ; + immediate +: next ['] _lit compile, 1 compile, ['] _loop compile, ['] _jz compile, + compile, ['] r> compile, ['] r> compile, ['] 2drop compile, ; immediate +: zstrlen dup begin dup c@ while 1+ repeat swap - ; +: zcount dup zstrlen ; diff --git a/pfth103_p2/fds.fth b/pfth103_p2/fds.fth new file mode 100755 index 0000000..5a58de4 --- /dev/null +++ b/pfth103_p2/fds.fth @@ -0,0 +1,88 @@ +\ ############################################################################ +\ # fds.fth - This program implements a full duplex serial port. It is base +\ # on the FullDuplexSerial Spin object. +\ # +\ # Copyright (c) 2012 Dave Hein +\ # MIT Licensed +\ ############################################################################ + +0 value fds_cog +create fds_vars 68 allot + +: fds_var create , does> @ fds_vars + ; + + 0 fds_var rx_head + 4 fds_var rx_tail + 8 fds_var tx_head +12 fds_var tx_tail +16 fds_var rx_pin +20 fds_var tx_pin +24 fds_var rxtx_mode +28 fds_var bit_ticks +32 fds_var buffer_ptr +36 fds_var rx_buffer +52 fds_var tx_buffer + +hex + +create fds_entry + a0bca9f0 , 80fca810 , 08bcaa54 , a0fcb201 , 2cbcb255 , 80fca804 , 08bcaa54 , + a0fcbe01 , 2cbcbe55 , 80fca804 , 08bcae54 , 80fca804 , 08bcb054 , 80fca804 , + 08bcb454 , a0bcc05a , 80fcc010 , 627cae04 , 617cae02 , 689be85f , 68abec5f , + a0fcc833 , 5cbcbc64 , 627cae01 , 613cb3f2 , 5c640016 , a0fcb809 , a0bcba58 , + 28fcba01 , 80bcbbf1 , 80bcba58 , 5cbcbc64 , a0bca85d , 84bca9f1 , c17ca800 , + 5c4c001f , 613cb3f2 , 30fcb601 , e4fcb81e , 28fcb617 , 60fcb6ff , 627cae01 , + 6cd4b6ff , 08bcabf0 , 80bcaa5a , 003cb655 , 84bcaa5a , 80fcaa01 , 60fcaa0f , + 083cabf0 , 5c7c0016 , 5cbcc85e , a0bca9f0 , 80fca808 , 08bcaa54 , 80fca804 , + 08bcac54 , 863caa56 , 5c680033 , 80bcac60 , 00bcc256 , 84bcac60 , 80fcac01 , + 60fcac0f , 083cac54 , 68fcc300 , 2cfcc202 , 68fcc201 , a0fcc40b , a0bcc7f1 , + 627cae04 , 617cae02 , 6ce0c201 , 29fcc201 , 70abe85f , 7497ec5f , 80bcc658 , + 5cbcc85e , a0bca863 , 84bca9f1 , c17ca800 , 5c4c004d , e4fcc446 , 5c7c0033 , + +decimal + +: fds_start ( rxpin txpin mode baudrate ... ) + >r + fds_vars 16 0 fill + rxtx_mode ! tx_pin ! rx_pin ! + clkfreq@ r> / bit_ticks ! + rx_buffer buffer_ptr ! + 0 dira! + fds_entry rx_head cognew + 1+ dup to fds_cog +; + +: fds_stop fds_cog if fds_cog 1- cogstop 0 to fds_cog then ; + +: fds_rxcheck rx_tail @ rx_head @ 2dup . . cr = + if + -1 + else + rx_tail @ rx_buffer + c@ + rx_tail @ 1+ 15 and rx_tail ! + then +; + +: fds_rx begin fds_rxcheck dup -1 = while drop repeat ; + +: fds_tx begin tx_tail @ tx_head @ 1+ 15 and <> until + tx_head @ tx_buffer + c! + tx_head @ 1+ 15 and tx_head ! + rxtx_mode @ 8 and if fds_rx then +; + +: fdstest + ." Type 'q' to quit" cr + 31 30 0 115200 fds_start + drop + begin + fds_rx + dup [char] q <> + while + [char] < fds_tx fds_tx [char] > fds_tx + repeat + drop + fds_stop + 1 30 lshift dira! +; + diff --git a/pfth103_p2/i2c.fth b/pfth103_p2/i2c.fth new file mode 100755 index 0000000..0c8852d --- /dev/null +++ b/pfth103_p2/i2c.fth @@ -0,0 +1,217 @@ +\ ############################################################################ +\ # i2c.fth - This program reads and writes EEPROMs using the I2C protocol. +\ # This program is based on Mike Green's basic_i2c_driver, which is found in +\ # the Parallax Object Exchange (OBEX). +\ # +\ # The first parameter for all routines is the pin number of the clock. It +\ # is assumed that the data pin number is one greater than the clock pin +\ # number. +\ # +\ # Copyright (c) 2012 Dave Hein +\ # MIT Licensed +\ ############################################################################ + +: i2c_dira_sda_high dup dira@ or dira! ; +: i2c_outa_sda_high dup outa@ or outa! ; +: i2c_dira_scl_high over dira@ or dira! ; +: i2c_outa_scl_high over outa@ or outa! ; +: i2c_dira_sda_low dup invert dira@ and dira! ; +: i2c_outa_sda_low dup invert outa@ and outa! ; +: i2c_dira_scl_low over invert dira@ and dira! ; +: i2c_outa_scl_low over invert outa@ and outa! ; + +\ This routine should be called before calling any of the other ones to ensure +\ that the EEPROM is in a known ready state. +: i2c_init ( scl ... ) + 1 swap lshift dup 2* \ sda := scl + 1 + i2c_outa_scl_high \ outa[scl] := 1 + i2c_dira_scl_high \ dira[scl] := 1 + i2c_dira_sda_low \ dira[sda] := 0 + 9 0 do \ repeat 9 + i2c_outa_scl_low \ outa[scl] := 0 + i2c_outa_scl_high \ outa[scl[ := 1 + dup ina@ and if leave then \ if ina[sda] quit + loop + 2drop +; + +\ This routine sends a start bit +: i2c_start ( scl ... ) + 1 swap lshift dup 2* \ sda := scl + 1 + i2c_outa_scl_high \ outa[scl]~~ + i2c_dira_scl_high \ dira[scl]~~ + i2c_outa_sda_high \ outa[sda]~~ + i2c_dira_sda_high \ dira[sda]~~ + i2c_outa_sda_low \ outa[sda]~ + i2c_outa_scl_low \ outa[scl]~ + 2drop +; + +\ This routine sends a stop bit +: i2c_stop ( scl ... ) + 1 swap lshift dup 2* \ sda := scl + 1 + i2c_outa_scl_high \ outa[scl]~~ + i2c_outa_sda_high \ outa[sda]~~ + i2c_dira_scl_low \ dira[scl]~ + i2c_dira_sda_low \ dira[sda]~ + 2drop +; + +\ This routine sends one byte and returns the ACK bit +: i2c_write ( scl data ... ackbit ) + 23 lshift swap \ data <<= 23 + 1 swap lshift dup 2* \ sda := scl + 1 + 8 0 do \ repeat 8 + rot 2* dup 0< + if + rot rot + i2c_outa_sda_high \ outa[sda] := 1 + else + rot rot + i2c_outa_sda_low \ outa[sda] := 0 + then + i2c_outa_scl_high \ outa[scl]~~ + i2c_outa_scl_low \ dira[scl]~ + loop + i2c_dira_sda_low \ dira[sda]~ + i2c_outa_scl_high \ outa[scl]~~ + dup ina@ and >r \ ackbit := ina[sda] + i2c_outa_scl_low \ outa[scl]~ + i2c_outa_sda_low \ outa[sda]~ + i2c_dira_sda_high \ dira[sda]~~ + 2drop drop + r> \ return ackbit +; + +\ This routine reads one byte from the EEPROM +: i2c_read ( scl ackbit ... data ) + >r \ save ackbit + 0 swap \ data := 0 + 1 swap lshift dup 2* \ sda := scl + 1 + i2c_dira_sda_low \ dira[sda]~ + 8 0 do \ repeat 8 + i2c_outa_scl_high \ outa[scl]~~ + rot 2* \ data <<= 1 + over ina@ and if 1 or then \ if ina[sda] data |= 1 + rot rot + i2c_outa_scl_low \ outa[scl]~ + loop + r> if + i2c_outa_sda_high \ outa[sda]~~ + else + i2c_outa_sda_low \ outa[sda]~ + then + i2c_dira_sda_high \ dira[sda]~~ + i2c_outa_scl_high \ outa[scl]~~ + i2c_outa_scl_low \ outa[scl]~ + i2c_outa_sda_low \ outa[sda]~ + 2drop \ return data +; + +\ This routine reads up to one page of data from the EEPROM +: i2c_readpage ( scl devsel addrreg dataptr count ... ackbit ) + >r >r \ Move count and dataptr to the return stack + dup 15 rshift 14 and rot or \ Assemble the devsel byte + dup >r rot dup dup >r \ Copy devsel and scl to the return stack + i2c_start \ Send a start bit + swap \ Arrange the scl and devsel on the stack + i2c_write drop \ Send the devsel byte + dup 8 rshift 255 and r@ swap \ Extract the second address byte + i2c_write drop \ Send the second address byte + 255 and r@ swap \ Extract the third address byte + i2c_write drop \ Send it + r@ \ Get the scl from the return stack + i2c_start \ Send a start bit + r> r> 1 or over >r \ Get the scl and devsel byte and set the LSB + i2c_write drop \ Send the devsel byte + r> r> r> 1 ?do \ Get scl, dataptr and count and start do loop + over 0 i2c_read over c! 1+ \ Read a byte from the EEPROM and save it + loop + over 1 i2c_read swap c! \ Read the last byte from the EEPROM + i2c_stop \ Send a stop bit + 0 \ Return the ack bit +; + +variable i2c_var + +\ This routine reads a byte from the specified address +: i2c_readbyte ( scl devsel addrreg ) + i2c_var 1 i2c_readpage drop i2c_var c@ ; + +\ This routine reads a word from the specified address +: i2c_readword ( scl devsel addrreg ) + 0 i2c_var ! i2c_var 2 i2c_readpage drop i2c_var @ ; + +\ This routine reads a long from the specified address +: i2c_readlong ( scl devsel addrreg ) + i2c_var 4 i2c_readpage drop i2c_var @ ; + +\ This routine writes up to one page of data to the EEPROM +: i2c_writepage ( scl devsel addrreg dataptr count ... ackbit ) + >r >r \ ( scl devsel addrreg ) r( count dataptr ) + dup 15 rshift 14 and rot or \ ( scl addrreg devsel ) + rot dup >r \ ( addrreg devsel scl ) r( count dataptr scl ) + i2c_start \ ( addrreg devsel ) r( count dataptr scl ) + r@ swap \ ( addrreg slc devsel ) r( count dataptr scl ) + i2c_write drop \ ( addrreg ) r( count dataptr scl ) + dup 8 rshift 255 and r@ swap + i2c_write drop + 255 and r@ swap + i2c_write drop + r> r> r> 0 ?do + 2dup c@ i2c_write drop 1+ + loop + drop + i2c_stop + 0 +; + +\ This routine writes a byte to the specified address +: i2c_writebyte ( scl devsel addrreg data ) + i2c_var ! i2c_var 1 i2c_writepage drop ; + +\ This routine writes a word to the specified address +: i2c_writeword ( scl devsel addrreg data ) + i2c_var ! i2c_var 2 i2c_writepage drop ; + +\ This routine writes a long to the specified address +: i2c_writelong ( scl devsel addrreg data ) + i2c_var ! i2c_var 4 i2c_writepage drop ; + +\ This routine returns a zero if the EEPROM is ready after a write +\ Otherwise it returns a non-zero value +: i2c_writewait ( scl devsel addrreg ) + 15 rshift 14 and or + over i2c_start + over >r i2c_write + r> i2c_stop +; + +\ This word will be run at startup +: startup + 1 30 lshift dup outa! dira! + pfthversion type cr +; + +\ Set up the cog config struct +: setupconfig + 496 cog@ \ Get config struct address from PAR + dup 16 + @ \ Get the address of the return stack + 4 + over 12 + ! \ Add four and set initial address of return stack + ['] interpret >body \ Get the address of the Forth interpreter + over 16 + @ ! \ Write it to the return stack + ['] startup >body \ Get the address of the startup word + swap ! \ Write it to the intial value of the program counter +; + +\ Save the hub RAM to EEPROM +: eesave + setupconfig + 28 i2c_init + 512 0 + do + 28 160 i 64 * dup 64 i2c_writepage drop + begin 28 160 0 i2c_writewait 0= until + i 7 and 7 = if [char] . emit then + loop +; diff --git a/pfth103_p2/init.fth b/pfth103_p2/init.fth new file mode 100755 index 0000000..da598ec --- /dev/null +++ b/pfth103_p2/init.fth @@ -0,0 +1,400 @@ +: link>flags 2 + ; +: immediate 81 last @ link>flags c! ; +: \ 100 word drop ; immediate + +\ The above lines implement the words to allow for "\" comments +\ All numbers are in hex at this point. + +\ DEFINE CELL SIZE +: cellsize 4 ; +: cellmask 3 ; +: compsize 2 ; +: compmask 1 ; + +\ BASIC STACK WORDS +: rot 2 roll ; +: over 1 pick ; +: 2dup over over ; +: 2drop drop drop ; +: 2swap 3 roll 3 roll ; +: 2over 3 pick 3 pick ; + +\ WORD HEADER ACCESSORS +: >does 2 + ; +: >body 4 + ; +: name>xt dup c@ + 4 + 0 4 - and ; +: link>name 3 + ; +: link>xt link>name name>xt ; +: link>does link>xt 2 + ; +: link>body link>xt 4 + ; + +\ DEFINE BASIC WORD BUILDERS +: source tib #tib @ ; +\ : compile, , ; +: ' 20 word find 0 = 0 = and ; +: _does r> dup >r 2 + last @ link>does w! ; +: _setjmp 0a last @ link>flags c! ; +: literal 0 compile, compile, ; immediate + last @ link>body dup @ swap 2 + w! \ Patch in address of _lit +: postpone ' compile, ; immediate +: ['] ' postpone literal ; immediate +: [compile] ' postpone literal ['] compile, compile, ; immediate +: does> [compile] _does [compile] exit ; immediate + +\ CONDITIONAL EXECUTION AND LOOPING +: if ['] _jz compile, here 2 allot ; immediate +: else ['] _jmp compile, here 2 + swap w! here 2 allot ; immediate +: then here swap w! ; immediate +: begin here ; immediate +: until ['] _jz compile, compile, ; immediate +: again ['] _jmp compile, compile, ; immediate +: while ['] _jz compile, here 2 allot ; immediate +: repeat ['] _jmp compile, here 2 + swap w! compile, ; immediate +: do ['] _lit compile, here 2 allot ['] drop compile, + ['] swap compile, ['] >r compile, ['] >r compile, here ; immediate +: ?do ['] 2dup compile, ['] > compile, ['] _jz compile, here 2 allot + ['] swap compile, ['] >r compile, ['] >r compile, here ; immediate +\ : _loop r> swap r> + r> dup >r swap dup >r > 0 = swap >r ; +: loop ['] _lit compile, 1 compile, ['] _loop compile, ['] _jz compile, compile, ['] r> compile, + ['] r> compile, here swap w! ['] 2drop compile, ; immediate +: +loop ['] _loop compile, ['] _jz compile, compile, ['] r> compile, + ['] r> compile, here swap w! ['] 2drop compile, ; immediate +: leave r> r> drop r> dup >r >r >r ; +: i r> r> dup >r swap >r ; +: j r> r> r> r> dup >r swap >r swap >r swap >r ; + +\ DEFINE >FLAGS AND >LINK +: >flags begin 1 - dup c@ 80 and until ; +: >link >flags 2 - ; + +\ DEFINE DEFER AND IS +\ Change code pointer from varfunc to deferfunc +: defer create last @ link>xt dup w@ 3 + swap w! ; +: is state @ + if [compile] >body ' >does postpone literal [compile] w! + else >body ' >does w! + then ; immediate + +\ REDEFINE REFILL AS A DEFERRED WORD +' refill +defer refill +is refill + +\ DEFINE "(" COMMENT WORD NOW THAT WE CAN LOOP +: ( begin + #tib @ >in @ + ?do tib i + c@ 29 = if i 1 + >in ! r> r> drop drop exit then loop + refill 0 = + until ; immediate + +( PAD AND PRINT SUPPORT ) +create pad 100 allot +create printptr 4 allot +: _d2a dup 0a < if 30 else 57 then + ; +: _a2d dup 30 < + if + drop 0 1 - + else + dup 39 > + if + dup 41 < + if + drop 0 1 - + else + dup 5a > + if + dup 61 < + if + drop 0 1 - + else + dup 7a > + if + drop 0 1 - + else + 57 - + then + then + else + 37 - + then + then + else + 30 - + then + then + dup base @ < 0 = + if + drop 0 1 - + then +; +: c!-- dup >r c! r> 1 - ; +: cprint printptr @ c! printptr @ 1 - printptr ! ; + +( DOUBLE WORDS ) +: s>d 0 pick 0 < ; +: m* * s>d ; +: um* * 0 ; +: d+ drop 1 roll drop + s>d ; +: d- drop 1 roll drop - s>d ; +: d* drop 1 roll drop * s>d ; +: d/ drop 1 roll drop / s>d ; +: dmod drop 1 roll drop mod s>d ; +: _u/ over over swap 1 rshift swap / dup + dup >r over * rot swap - swap < 1 + r> + ; +: u/ over 0 < if _u/ else / then ; +: ud/ drop 1 roll drop u/ 0 ; +: _umod swap dup 1 rshift 2 pick mod dup + swap 1 and + swap mod ; +: umod over 0 < if _umod else mod then ; +: udmod drop 1 roll drop umod 0 ; + +( CORE WORDS ) +: +! dup @ rot + swap ! ; +: /mod over over >r >r mod r> r> / ; +: [ state 0 ! ; +: ] state 1 ! ; +: r@ r> r> dup >r swap >r ; +: sm/rem >r 2dup r@ s>d d/ drop r> swap >r s>d dmod drop r> ; +: um/mod >r 2dup r@ s>d ud/ drop r> swap >r s>d udmod drop r> ; +: fm/mod over over xor 1 31 lshift and if sm/rem else sm/rem then ; ( TODO ) +: */mod >r m* r> sm/rem ; +: */ */mod swap drop ; +: <# pad ff + printptr ! ; +: hold cprint ; +: # drop dup base @ umod _d2a cprint base @ u/ 0 ; +: #s begin # over over or 0 = until ; +: #> drop drop printptr @ 1 + dup pad 100 + swap - ; +: sign 0 < if 2d hold then ; +: abs dup 0 < if 0 swap - then ; +: type 0 ?do dup c@ emit 1 + loop drop ; +: ._ dup abs 0 <# #s rot sign #> type ; +: . ._ 20 emit ; + +: >number dup 0 ?do >r dup c@ _a2d dup 0 < if drop r> leave else swap >r >r + base @ 0 d* r> 0 d+ r> 1 + r> 1 - then loop ; +: 0= 0 = ; +: 0< 0 < ; +: 1+ 1 + ; +: 1- 1 - ; +: 2! swap over ! cellsize + ! ; +: 2* dup + ; +: 2/ dup 80000000 and swap 1 rshift or ; +: 2@ dup cellsize + @ swap @ ; +: ?dup dup if dup then ; +: aligned cellmask + 0 cellsize - and ; +: align here aligned here - allot ; +: bl 20 ; +: c, here c! 1 allot ; +: cell+ cellsize + ; +: cells cellsize * ; +: char+ 1 + ; +: chars ; +\ : count dup char+ swap c@ ; +: char 20 word count 0= if drop 0 else c@ then ; +: [char] char postpone literal ; immediate +\ : constant create here ! cellsize allot does> @ ; +: constant create , last @ link>xt dup w@ 3 - swap w! ; +: cr 0a emit 0d emit ; +: decimal 0a base ! ; +: environment? drop drop 0 ; +: fill swap >r swap r> 0 ?do 2dup c! 1 + loop 2drop ; +: hex 10 base ! ; +: invert 0 1 - xor ; +: max 2dup < if swap then drop ; +: min 2dup > if swap then drop ; +\ : cmove >r swap r> 0 ?do 2dup c@ swap c! 1+ swap 1+ swap loop 2drop ; +: cmove> >r swap r> dup >r 1- dup >r + swap r> + swap r> ?do 2dup c@ swap c! + 1- swap 1- swap loop 2drop ; +: move r> 2dup > if r> cmove else r> cmove> then ; +: negate 0 swap - ; +: recurse last @ , ; immediate +: _lit" r> dup 1 + swap dup c@ dup rot + compsize + 0 compsize - and >r ; + 84 last @ link>flags c! ( Set STRING flag ) +: _compile" [char] " word count dup >r dup >r c, here r> cmove r> allot + compsize here - compmask and allot ; immediate +create s"buf 50 allot +: s" state @ if ['] _lit" compile, postpone _compile" else + [char] " word count >r s"buf r@ cmove s"buf r> then ; immediate +: ." postpone s" ['] type compile, ; immediate +: _abort" if type abort else drop drop then ; +\ : abort" postpone s" ['] _abort" compile, ; immediate +: abort" postpone s" ['] _abort" compile, ; +: space 20 emit ; +: spaces 0 ?do space loop ; +: u._ 0 <# #s #> type ; +: u. u._ 20 emit ; +: u< over over xor 1 31 lshift and if swap then < ; +: unloop r> r> r> drop drop >r ; +: variable create cellsize allot ; + +( CORE EXT ) +: 0<> 0= invert ; +: 0> 0 > ; +: 2>r r> rot >r swap >r >r ; +: 2r> r> r> r> rot >r swap ; +: 2r@ r> r> r> 2dup >r >r swap rot >r ; +: <> = 0= ; +: erase 0 ?do dup 0 swap ! 1 + loop drop ; +variable span +: expect accept span ! ; +: false 0 ; +: marker create last @ , does> @ dup dp ! @ last ! ; +: nip swap drop ; +: parse word count ; +: true 0 1 - ; +: tuck swap over ; +: to ' >body state @ if postpone literal [compile] ! else ! then ; immediate +\ : value create here ! cellsize allot does> @ ; +: value create , last @ link>xt dup w@ 3 - swap w! ; +: within over - >r - r> u< ; +: .r_ >r dup abs 0 <# #s rot sign #> dup r> swap - spaces type ; +: .r .r_ 20 emit ; +: u.r_ >r 0 <# #s #> dup r> swap - spaces type ; +: u.r .r_ 20 emit ; +: u> over over xor 80000000 and if swap then > ; +: unused 8000 here - ; +: case 0 ; immediate +: of ['] over compile, ['] = compile, + ['] _jz compile, here 4 allot ['] drop compile, ; immediate +: endof ['] _jmp compile, here 2 + swap w! here 2 allot ; immediate +: endcase ['] drop compile, begin ?dup while here swap w! repeat ; immediate +: c" ['] _lit" compile, postpone _compile" ['] drop compile, ['] 1- compile, ; immediate +: .( [char] ) word count type ; immediate +: :noname align here ['] words @ , [ ; + +( DOUBLE ) +: d= rot = rot rot = and ; +: d0= or 0 = ; +: 2constant create swap , , does> dup @ swap cellsize + @ ; + +( STRING ) +: blank 0 ?do dup bl swap c! 1+ loop drop ; +: -trailing dup 0 ?do 2dup + 1- c@ bl = if 1- else leave then loop ; +: /string dup >r - swap r> + swap ; + +( TOOLS ) +: ? @ . ; +: .s 3c emit depth ._ 3e emit 20 emit depth 0 ?do depth i - 1 - pick . loop ; +: dump 0 ?do i 0f and 0 = if cr dup . then dup c@ 3 .r 1 + loop drop cr ; +: forget 20 word find if >link dup dp ! w@ last ! else abort" ?" then ; +: .name dup link>name count type space ; +: ?newline dup >r link>name c@ dup rot + 1 + dup 4e > if cr else swap then drop r> ; +: words 0 last @ begin dup while ?newline .name w@ repeat 2drop ; + +( UTILITY ) +: at-xy 2 emit swap emit emit ; +: page 0 emit ; + +( VERSION STRING ) +: pfthversion s" pfth 1.03" ; + +create evalmode 0 , +0 value source-id +create srcstk0 30 allot +srcstk0 value srcstk + +: resetstack depth 0 < + if + begin depth while 0 repeat + else + begin depth while drop repeat + then +; + +: getnumber 2dup >r >r swap dup c@ [char] - = + if + swap + dup 1 < + if + 2drop 2drop r> r> 1 + else + swap 1 + swap 1 - + >number dup + if + 2drop 2drop r> r> 1 + else + 2drop drop negate 0 r> r> 2drop + then + then + else + swap + >number dup + if + 2drop 2drop r> r> 1 + else + 2drop drop 0 r> r> 2drop + then + then +; + +: compilenumber + dup ['] _lit compile, compile, + dup ffff 10 lshift and + if + 10 rshift + ['] _lit compile, compile, + ['] _lit compile, 10 compile, + ['] lshift compile, + ['] or compile, + else + drop + then +; + +: _interpret + begin + 20 word dup c@ + while + find dup + if + state @ = + if + compile, + else + execute + then + else + dup rot count getnumber + if + type ." ?" cr + else + state @ + if + compilenumber + then + then + then + repeat + drop +; + +: .savesrc ." _savesrc " srcstk0 . srcstk . cr ; +: .loadsrc ." _loadsrc " srcstk0 . srcstk . cr ; + +: _savesrc ( .savesrc ) tib srcstk ! #tib @ srcstk 4 + ! >in @ srcstk 8 + ! source-id srcstk 0c + ! srcstk 10 + to srcstk ; +: _loadsrc srcstk 10 - to srcstk ( .loadsrc ) srcstk @ to tib srcstk 4 + @ #tib ! srcstk 8 + @ >in ! srcstk 0c + @ to source-id ; +: evaluate _savesrc 0 1 - to source-id #tib ! to tib 0 >in ! _interpret _loadsrc ; + +( INTERPRETER ) +: interpret +begin + _interpret + depth 0 < + if + ." Stack Underflow" cr + resetstack + else + source-id 0 1 - = + if + _loadsrc + \ 0 to source-id + else + source-id 0= + if ." ok" cr then + refill + then + then +again +; + +decimal +interpret + diff --git a/pfth103_p2/license.txt b/pfth103_p2/license.txt new file mode 100755 index 0000000..f5b4c0e --- /dev/null +++ b/pfth103_p2/license.txt @@ -0,0 +1,22 @@ ++-------------------------------------------------------------------- +| TERMS OF USE: MIT License ++-------------------------------------------------------------------- +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++------------------------------------------------------------------ diff --git a/pfth103_p2/pfth.TXT b/pfth103_p2/pfth.TXT new file mode 100755 index 0000000..7304758 --- /dev/null +++ b/pfth103_p2/pfth.TXT @@ -0,0 +1 @@ +Object "pfth.spin" Interface: Program: 0 Longs Variable: 0 Longs \ No newline at end of file diff --git a/pfth103_p2/pfth.obj b/pfth103_p2/pfth.obj new file mode 100755 index 0000000..d1b94ac Binary files /dev/null and b/pfth103_p2/pfth.obj differ diff --git a/pfth103_p2/pfth.spin b/pfth103_p2/pfth.spin new file mode 100755 index 0000000..0442b04 --- /dev/null +++ b/pfth103_p2/pfth.spin @@ -0,0 +1,1606 @@ +{ +############################################################################ +# PFTH - This program implements a Forth interpreter. +# +# Copyright (c) 2012, 2013 Dave Hein +# MIT Licensed +############################################################################ +} +con + _clkmode = xtal1+pll16x + _clkfreq = 80_000_000 + + ' SD Pin Definitions + 'DO = 10 + 'CLK = 11 + 'DI = 9 + 'CS = 25 + + 'Q = 16 ' Object Offset + + FLAG_IMMEDIATE = 1 + FLAG_CORE = $10 | $80 + FLAG_LIT = $12 | $80 + FLAG_VAR = $20 | $80 + FLAG_DEF = $00 | $80 + FLAG_JMP = $0A | $80 + FLAG_SEMI = FLAG_CORE | FLAG_IMMEDIATE +{ +obj + 'spi : "mount" + +'******************************************************************************* +' This Spin code waits three seconds and then starts the Forth cog +'******************************************************************************* +pub main(argc, argv) + waitcnt(clkfreq+cnt) + 'spi.mount_explicit(@spi_vars, DO, CLK, DI, CS) + coginit(cogid, @forth, @pfthconfig) + +dat +pfthconfig long @xboot_1+Q ' Initial word to execute + long @stack+Q+16 ' Starting stack pointer + long @stack+Q+16 ' Empty stack pointer value + long @retstk+Q ' Starting return pointer + long @retstk+Q ' Empty return pointer value +stack long 0[100] ' Data stack +retstk long 0[100] ' Return stack + +'******************************************************************************* +' pfth cog code +'******************************************************************************* + org 0 +forth +parm mov parm, par +} + Q = 0 ' Object offset for the top object + 'rx_pin = 91 + 'tx_pin = 90 + rx_pin = 31 + tx_pin = 30 + +DAT + orgh $380 + org 0 + + ' Entry point for the Forth interpreter +forth 'mov pc, a_interp + 'or outc, tx_mask + 'or dirc, tx_mask + 'getcnt temp2 + 'add temp2, delay_time + 'waitcnt temp2, #0 + jmp #parm +parval long @pfthconfig +'tx_mask long 1 << (64 - TX_PIN) ' must be in dirc +delay_time long 80000000 * 2 + +parm mov parm, parval +parm1 rdlong pc, parm +parm2 add parm, #4 +parm3 rdlong stackptr, parm +parm4 add parm, #4 +temp rdlong stackptr0, parm +temp1 add parm, #4 +temp2 rdlong returnptr, parm +temp3 add parm, #4 +temp4 rdlong returnptr0, parm + jmp #innerloop ' Begin execution + +'******************************************************************************* +' Execute the words contained in the body of a word +' Changes parm, temp1 +'******************************************************************************* +execlistfunc add parm, #4 ' Get body from XT +innerloopcall wrlong pc, returnptr ' Push PC to return stack + add returnptr, #4 + mov pc, parm ' Set new value for PC + +'******************************************************************************* +' Get an execution token from the location pointed to by the program counter +' Increment the program counter, fetch the code pointer and jump to it +' Changes parm, temp1, pc +'******************************************************************************* +innerloop rdword parm, pc wz + if_z jmp #exitfunc + add pc, #2 + rdword temp1, parm + jmp temp1 + +pc long @xboot_1+Q ' Program Counter + +'******************************************************************************* +' Stop executing the current word, and return to the calling word +' No Changes +'******************************************************************************* +exitfunc sub returnptr, #4 + rdlong pc, returnptr + jmp #innerloop + +'******************************************************************************* +' Abort or quit execution, and return to the interpreter +' No Changes +'******************************************************************************* +abortfunc mov stackptr, stackptr0 +quitfunc mov returnptr, returnptr0 + add returnptr, #4 ' Use second entry return stack + rdlong pc, returnptr + jmp #innerloop + +'******************************************************************************* +' Push the value contained in the word's body onto the stack +' No changes +'******************************************************************************* +confunc add parm, #4 + rdlong parm1, parm + jmp #push_jmp + +'******************************************************************************* +' Push the address of the word's body onto the stack +' Execute the words pointed to by the does pointer, if non-zero +' No changes +'******************************************************************************* +varfunc mov parm1, parm + add parm1, #4 + call #push1 + +'******************************************************************************* +' Execute the words pointed to by the does pointer, if non-zero +' No changes +'******************************************************************************* +deferfunc add parm, #2 ' DOES> pointer + rdword parm, parm wz + if_z jmp #innerloop ' Done with varfunc + jmp #innerloopcall ' Execute DOES> code + +'******************************************************************************* +' Execute the word on the stack +' Changes parm, temp1 +'******************************************************************************* +executefunc sub stackptr, #4 + rdlong parm, stackptr + rdlong temp1, parm + jmp temp1 ' Execute code + +'******************************************************************************* +' Execute the PASM instruction on the TOS using the next value on the stack as +' the destination register data. Return the result on the stack. +' Changes parm1, parm2 +'******************************************************************************* +cogx1func call #pop2 + mov cogx1instr, parm2 + 'movd cogx1instr, #parm1 + nop +cogx1instr nop + jmp #push_jmp + +'******************************************************************************* +' Duplicate the top of stack +' Changes parm1 +'******************************************************************************* +dupfunc call #pop1 + call #push1 + jmp #push_jmp + +'******************************************************************************* +' Swap the top two items on the stack +' Changes parm1, parm2 +'******************************************************************************* +swapfunc call #pop2 + wrlong parm2, stackptr + add stackptr, #4 + jmp #push_jmp + +'******************************************************************************* +' Get the next word from the input buffer using the delimiter from the stack +' Changes parm, parm1, parm2, temp1, temp2 +'******************************************************************************* +wordfunc sub stackptr, #4 + rdlong parm, stackptr + call #word_del + mov temp1, #1 + shl temp1, #15 + sub temp1, parm2 + sub temp1, #1 + wrlong temp1, stackptr + add stackptr, #4 + wrbyte parm2, temp1 + cmps parm2, #0 wc, wz + if_c_or_z jmp #innerloop +:loop add temp1, #1 + rdbyte temp2, parm1 + add parm1, #1 + wrbyte temp2, temp1 + djnz parm2, @:loop + jmp #innerloop + +'******************************************************************************* +' Find the word specfied on the stack in the dictionary +' Changes parm1, parm2, temp4 +'******************************************************************************* +findfunc call #pop1 + mov temp4, parm1 + add parm1, #1 + rdbyte parm2, temp4 + call #findword + mov parm1, parm wz + if_z jmp #findfunc1 + call #link2xt + call #push1 + add parm, #2 ' Point to flag byte + rdbyte parm1, parm + and parm1, #1 ' Check immediate bit + shl parm1, #1 + sub parm1, #1 ' Return 1 if set, -1 if not + call #push1 + jmp #innerloop +findfunc1 mov parm1, temp4 + call #push1 + mov parm1, #0 + call #push1 + jmp #innerloop + +'******************************************************************************* +' Send the character from the stack to the output port +' Changes parm +'******************************************************************************* +emitfunc call #pop1 + mov parm, parm1 + call #putch + jmp #innerloop + +'******************************************************************************* +' Get a character from the input port and put it on the stack +' Changes parm, parm1 +'******************************************************************************* +getcharfunc call #getch + mov parm1, parm + jmp #push_jmp + +'******************************************************************************* +' Get a character from the files stored in memory and put it on the stack +' Changes parm1 +'******************************************************************************* +getfcharfunc rdbyte parm1, infileptr + add infileptr, #1 + jmp #push_jmp + +'******************************************************************************* +' Get an address and value from the stack, and store the value at the address +' No changes +'******************************************************************************* +storefunc call #pop2 + wrlong parm1, parm2 + jmp #innerloop + +'******************************************************************************* +' Fetch a value from the address specified on the stack, and put it on the stack +' Changes parm1 +'******************************************************************************* +fetchfunc call #pop1 + rdlong parm1, parm1 + jmp #push_jmp + +'******************************************************************************* +' Get an address and word from the stack, and store the word at the address +' No changes +'******************************************************************************* +wstorefunc call #pop2 + wrword parm1, parm2 + jmp #innerloop + +'******************************************************************************* +' Fetch a word from the address specified on the stack, and put it on the stack +' Changes parm1 +'******************************************************************************* +wfetchfunc call #pop1 + rdword parm1, parm1 + jmp #push_jmp + +'******************************************************************************* +' Get an address and byte from the stack, and store the byte at the address +' No changes +'******************************************************************************* +cstorefunc call #pop2 + wrbyte parm1, parm2 + jmp #innerloop + +'******************************************************************************* +' Fetch a byte from the address specified on the stack, and put it on the stack +' Changes parm1 +'******************************************************************************* +cfetchfunc call #pop1 + rdbyte parm1, parm1 + jmp #push_jmp + +'******************************************************************************* +' Add two values from the stack, and write the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +plusfunc call #pop2 + add parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Subtract two values from the stack, and write the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +minusfunc call #pop2 + sub parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Multiply two values from the stack, and write the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +multfunc call #pop2 + call #multiply + jmp #push_jmp + +'******************************************************************************* +' Divide two values from the stack, and write the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +dividefunc call #pop2 + call #divide + mov parm1, parm2 + test parm3, #1 wc + if_c neg parm1, parm1 + jmp #push_jmp + +'******************************************************************************* +' Compute the modulus from two values from the stack, and write the result back +' to the stack +' Changes parm1, parm2 +'******************************************************************************* +modfunc call #pop2 + call #divide + test parm3, #2 wc + if_c neg parm1, parm1 + jmp #push_jmp + +'******************************************************************************* +' Compare two values from the stack to determine if the second one is less than +' the first one, and write the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +lessfunc call #pop2 + cmps parm1, parm2 wc + if_c neg parm1, #1 + if_nc mov parm1, #0 + jmp #push_jmp + +'******************************************************************************* +' Compare two values from the stack to determine if they are equal, and write +' the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +equalfunc call #pop2 + cmp parm1, parm2 wz + if_z neg parm1, #1 + if_nz mov parm1, #0 + jmp #push_jmp + +'******************************************************************************* +' Compare two values from the stack to determine if the second one is greater +' than the first one, and write the result back to the stack +' Changes parm1, parm2 +'******************************************************************************* +greaterfunc call #pop2 + cmps parm1, parm2 wc, wz + if_nz_and_nc neg parm1, #1 + if_z_or_c mov parm1, #0 + jmp #push_jmp + +'******************************************************************************* +' Compute the logical AND of two values from the stack, and write the result +' back to the stack +' Changes parm1, parm2 +'******************************************************************************* +andfunc call #pop2 + and parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Compute the logical OR of two values from the stack, and write the result +' back to the stack +' Changes parm1, parm2 +'******************************************************************************* +orfunc call #pop2 + or parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Compute the logical XOR of two values from the stack, and write the result +' back to the stack +' Changes parm1, parm2 +'******************************************************************************* +xorfunc call #pop2 + xor parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Right-shift the second value on the stack by the number of bits specified by +' the first value on the stack, and write the result to the stack +' Changes parm1, parm2 +'******************************************************************************* +rshiftfunc call #pop2 + shr parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Left-shift the second value on the stack by the number of bits specified by +' the first value on the stack, and write the result to the stack +' Changes parm1, parm2 +'******************************************************************************* +lshiftfunc call #pop2 + shl parm1, parm2 + jmp #push_jmp + +'******************************************************************************* +' Push the stack depth to the stack +' Changes parm1 +'******************************************************************************* +depthfunc mov parm1, stackptr + sub parm1, stackptr0 + sar parm1, #2 + jmp #push_jmp + +'******************************************************************************* +' Drop the top value from the stack +' No changes +'******************************************************************************* +dropfunc sub stackptr, #4 + jmp #innerloop + +'******************************************************************************* +' Use the value on top of the stack as an index to another value in the stack, +' and write its value to the stack +' No changes +'******************************************************************************* +pickfunc call #pop1 + call #indexstack + jmp #push_jmp + +'******************************************************************************* +' Use the value on top of the stack as and index to remove another value from +' the stack, and place it at the top of the stack. +' Changes temp1, temp2, temp3, temp4 +'******************************************************************************* +rollfunc call #pop1 + cmp parm1, #0 wc, wz + if_c_or_z jmp #innerloop + mov temp3, parm1 + call #indexstack + mov temp2, temp1 +:loop add temp2, #4 + rdlong temp4, temp2 + wrlong temp4, temp1 + add temp1, #4 + djnz temp3, @:loop + wrlong parm1, temp1 + jmp #innerloop + +'******************************************************************************* +' Pop the value from the top of the stack, and push it onto the return stack. +' No changes +'******************************************************************************* +torfunc call #pop1 + wrlong parm1, returnptr + add returnptr, #4 + jmp #innerloop + +'******************************************************************************* +' Pop the value from the top of the return stack and push it to the stack. +' Changes parm1 +'******************************************************************************* +fromrfunc sub returnptr, #4 + rdlong parm1, returnptr + jmp #push_jmp + +'******************************************************************************* +' Push the value on the stack pointed to by the PC and increment the PC +' Changes parm1 +'******************************************************************************* +_litfunc rdword parm1, pc + add pc, #2 + jmp #push_jmp + +'******************************************************************************* +' Convert the string described by the address and length on the top of the +' stack to a hex number, and push it to the stack +' Changes parm1 +'******************************************************************************* +_gethexfunc call #pop2 + call #gethex + mov parm1, parm + jmp #push_jmp + +'******************************************************************************* +' Create a variable, and add it to the dictionary +' Changes parm3 +'******************************************************************************* +createfunc mov parm3, #varfunc + mov parm4, #FLAG_VAR + call #create + jmp #innerloop + +'******************************************************************************* +' Create an executable word, and add it to the dictionary. Set the compile +' state to -1 +' Changes parm3, temp1 +'******************************************************************************* +colonfunc mov parm3, #execlistfunc + mov parm4, #FLAG_DEF + call #create + if_z jmp #innerloop + neg temp1, #1 + wrlong temp1, a_state + jmp #innerloop + +'******************************************************************************* +' Compile a zero into memory indicating the end of an executable word, and set +' the compile flag to zero +' Changes temp1, temp2 +'******************************************************************************* +semicolonfunc mov temp1, #0 + wrlong temp1, a_state + rdlong temp2, a_dp + wrword temp1, temp2 + add temp2, #2 + wrlong temp2, a_dp + jmp #innerloop + +'******************************************************************************* +' Fetch a value from the specified cog address, and put it on the stack +' the compile flag to zero +' Changes parm1 +'******************************************************************************* +cogfetchfunc call #pop1 + 'movs cogfetch1, parm1 + nop +cogfetch1 mov parm1, 0-0 + jmp #push_jmp + +'******************************************************************************* +' Get a cog address and value from the stack, and store the value at the address +' the compile flag to zero +' Changes parm1, parm2 +'******************************************************************************* +cogstorefunc call #pop2 + 'movd cogstore1, parm2 + nop +cogstore1 'mov 0-0, parm1 + jmp #innerloop + + +'******************************************************************************* +' Print out an 8-digit hex number to the output port. +' Changes parm +'******************************************************************************* +dotxfunc mov parm, #"$" + call #putch + call #pop1 + call #printhex + mov parm, #" " + call #putch + jmp #innerloop + +'******************************************************************************* +' If top of stack is zero, jump to address contained in location at current PC. +' Otherwise, increment the PC +' Changes parm1 +'******************************************************************************* +_jzfunc call #pop1 + if_z rdword pc, pc + if_nz add pc, #2 + jmp #innerloop + +'******************************************************************************* +' Copy bytes from the source to the destination +' Changes parm1 +'******************************************************************************* +cmovefunc sub stackptr, #4 + rdlong parm3, stackptr + call #pop2 + cmps parm3, #0 wz, wc + if_c_or_z jmp #innerloop +:loop rdbyte temp1, parm1 + add parm1, #1 + wrbyte temp1, parm2 + add parm2, #1 + djnz parm3, @:loop + jmp #innerloop + +'******************************************************************************* +' Perform the increment and compare for the loop word +' Changes parm1, parm2, parm3 +'******************************************************************************* +_loopfunc call #pop1 ' Get increment + sub returnptr, #8 + rdlong parm3, returnptr ' Get upper limit + add returnptr, #4 + rdlong parm2, returnptr ' Get index + add parm1, parm2 ' index + increment + wrlong parm1, returnptr ' Push index back + add returnptr, #4 + cmps parm1, parm3 wc + if_nc neg parm1, #1 + if_c mov parm1, #0 + jmp #push_jmp + +'******************************************************************************* +' The following code implements the basic functions used by the kernel words +'******************************************************************************* + +'******************************************************************************* +' Create a word entry in the dictionary +' Changes parm, parm1, parm2, temp1, temp2 +'******************************************************************************* +create mov parm, #" " + call #word_del + if_z jmp #create_ret + rdlong temp1, a_dp ' Align DP + add temp1, #3 + and temp1, minus4 + rdlong temp2, a_last + wrword temp2, temp1 ' Write the link pointer + wrlong temp1, a_last ' Update LAST + add temp1, #2 + + wrbyte parm4, temp1 ' Write the flag + add temp1, #1 + wrbyte parm2, temp1 ' Write the length + add temp1, #1 + cmps parm2, #0 wc, wz + if_c_or_z jmp #create_done +:loop rdbyte temp2, parm1 ' Copy the name + add parm1, #1 + wrbyte temp2, temp1 + add temp1, #1 wz + djnz parm2, @:loop + +create_done mov temp2, #0 ' Pad with 0's to align +:loop1 test temp1, #3 wz + if_z jmp #create_aligned + wrbyte temp2, temp1 + add temp1, #1 + jmp #:loop1 + +create_aligned wrword parm3, temp1 ' Write the code pointer + add temp1, #2 + wrword temp2, temp1 ' Write the DOES> pointer + add temp1, #2 wz ' Clear zero flag + + wrlong temp1, a_dp +create_ret ret + +'******************************************************************************* +' Get one character from the input port. +' Input none +' Changes parm, temp, temp1, temp2 +' Output parm +'******************************************************************************* +{ +getch mov parm, ina + and parm, inbit wz + if_nz jmp #getch + mov temp2, cnt + mov temp, bitcycles + shr temp, #1 + add temp2, temp + mov temp1, #10 +:loop waitcnt temp2, bitcycles + mov temp, ina + and temp, inbit + ror parm, #1 + or parm, temp + djnz temp1, #:loop + ror parm, #31 - 8 + and parm, #255 +getch_ret ret + +inbit long $80000000 +} +getch getp #RX_PIN wz + if_nz jmp #getch + getcnt temp2 + mov temp3, bitcycles + shr temp3, #1 + add temp2, temp3 + mov temp1, #10 + mov parm, #0 +:loop waitcnt temp2, bitcycles + ror parm, #1 + getp #RX_PIN wc + if_c or parm, #1 + djnz temp1, @:loop + rol parm, #8 + and parm, #255 + ret +bitcycles long 80_000_000 / 115_200 + +'******************************************************************************* +' Send one character to the output port. +' Input parm +' Changes parm, temp1, temp2 +' Output none +'******************************************************************************* +{ +putch rdlong temp1, a_verbose wz + if_z jmp putch_ret + or parm, #$100 + shl parm, #1 + mov temp1, #10 + mov temp2, bitcycles + add temp2, cnt +:loop shr parm, #1 wc + if_c or outa, outbit + if_nc andn outa, outbit + waitcnt temp2, bitcycles + djnz temp1, #:loop +putch_ret ret + +outbit long $40000000 +} +putch rdlong temp1, a_verbose wz + if_z ret + or parm, stopbits + shl parm, #1 + mov temp1, #11 + getcnt temp2 + add temp2, bitcycles +:loop ror parm, #1 wc + setpc #TX_PIN + waitcnt temp2, bitcycles + djnz temp1, @:loop + ret +stopbits long $300 + +'******************************************************************************* +' Skip the specified character in the input buffer +' Input parm +' Changes temp, temp1 +' Output none +'******************************************************************************* +skipchar cmps temp1, temp2 wc + if_nc jmp #skipchar_ret + rdlong temp, a_tib + add temp, temp1 + rdbyte temp, temp + cmp temp, parm wz + if_nz jmp #skipchar_ret + add temp1, #1 + jmp #skipchar +skipchar_ret ret + +'******************************************************************************* +' Find the next occurance of the specified character in the input buffer +' Input parm +' Changes temp, temp1 +' Output none +'******************************************************************************* +findchar cmps temp1, temp2 wc + if_nc jmp #findchar_ret + rdlong temp, a_tib + add temp, temp1 + rdbyte temp, temp + cmp temp, parm wz + if_z jmp #findchar_ret + add temp1, #1 + jmp #findchar +findchar_ret ret + +'******************************************************************************* +' Find the next word in the input buffer delimited by the specified character +' Input parm +' Changes parm1, parm2, temp1, temp2 +' Output none +'******************************************************************************* +word_del + rdlong temp1, a_inputidx + rdlong temp2, a_inputlen + call #skipchar + mov parm1, temp1 + call #findchar + mov parm2, temp1 + sub parm2, parm1 wz + rdlong temp, a_tib + add parm1, temp + cmps temp1, temp2 wc + if_c add temp1, #1 + wrlong temp1, a_inputidx +word_del_ret ret + +'******************************************************************************* +' Find the specified word in the dictionary +' Input parm1, parm2 +' Changes parm, parm3, parm4 +' Output parm +'******************************************************************************* +findword rdlong parm, a_last wz + if_z jmp #findword_ret +:loop mov parm3, parm + add parm3, #3 + rdbyte parm4, parm3 + add parm3, #1 + call #compare + if_z jmp #findword_ret + rdword parm, parm wz + if_nz jmp #:loop +findword_ret ret + +'******************************************************************************* +' Do a case insensitive comparison of two character strings +' Input parm1, parm2, parm3, parm4 +' Changes parm3, parm4, temp, temp1, temp2 +' Outut Z +'******************************************************************************* +compare cmps parm2, #1 wc, wz + if_c jmp #compare_ret + cmp parm2, parm4 wz + if_nz jmp #compare_ret + mov temp, parm1 +:loop rdbyte temp1, temp + call #toupper + mov temp2, temp1 + rdbyte temp1, parm3 + call #toupper + cmp temp1, temp2 wz + if_nz jmp #compare_ret + add temp, #1 + add parm3, #1 + djnz parm4, @:loop +compare_ret ret + +'******************************************************************************* +' Convert a character to uppercase +' Input temp1 +' Changes temp1 +' Ouput temp1 +'******************************************************************************* +toupper cmp temp1, #"a" wc + if_c jmp #toupper_ret + cmp temp1, #"z" wc, wz + if_nc_and_nz jmp #toupper_ret + sub temp1, #"a" - "A" +toupper_ret ret + + +'******************************************************************************* +' Print an 8-digit hex value to the output port +' Input parm1 +' Changes parm, parm1, parm2 +' Output none +'******************************************************************************* +printhex mov parm2, #8 +:loop rol parm1, #4 + mov parm, #15 + and parm, parm1 + add parm, a_hexstr + rdbyte parm, parm + call #putch + djnz parm2, @:loop +printhex_ret ret + + +'******************************************************************************* +' Convert a string to a hex number +' Input parm1, parm2 +' Changes parm, temp, temp1, temp2 +' Output parm +'******************************************************************************* +gethex mov parm, #0 + cmps parm2, #0 wc, wz + if_c_or_z jmp #gethex_ret + mov temp1, parm1 + mov temp2, parm2 +:loop rdbyte temp, temp1 + add temp1, #1 + sub temp, #"0" + cmps temp, #10 wc + if_nc sub temp, #"a"-"0"-10 + shl parm, #4 + add parm, temp + djnz temp2, @:loop +gethex_ret ret + +'******************************************************************************* +' Push a value onto the data stack +' Input parm1 +' No changes +' Output none +'******************************************************************************* +push1 wrlong parm1, stackptr + add stackptr, #4 +push_ret ret + +'******************************************************************************* +' Push a value onto the data stack and jump to the innerloop +' Input parm1 +' No changes +' Output none +'******************************************************************************* +push_jmp wrlong parm1, stackptr + add stackptr, #4 + jmp #innerloop + +'******************************************************************************* +' Pop two values off of the data stack +' Input none +' Changes parm1, parm2 +' Output parm1, parm2 +'******************************************************************************* +pop2 sub stackptr, #4 + rdlong parm2, stackptr + +'******************************************************************************* +' Pop one value off of the data stack +' Input none +' Changes parm1 +' Ouput parm1 +'******************************************************************************* +pop1 sub stackptr, #4 + rdlong parm1, stackptr wz +pop_ret +pop2_ret ret + +'******************************************************************************* +' Read a value on the stack based on an index number +' Changes parm1, temp1 +'******************************************************************************* +indexstack neg temp1, parm1 + shl temp1, #2 + sub temp1, #4 + add temp1, stackptr + rdlong parm1, temp1 +indexstack_ret ret + +'******************************************************************************* +' Compute the XT from the address of the link +' Input: parm1 +' Output: parm1 +' Changes: temp1 +'******************************************************************************* +link2xt mov temp1, parm1 + add temp1, #3 + rdbyte parm1, temp1 ' Get name length + add parm1, temp1 + add parm1, #4 + and parm1, minus4 ' Align +link2xt_ret ret + +'******************************************************************************* +' Multiply two 32-bit numbers +' Changes parm2, temp1, temp2 +'******************************************************************************* +multiply mov temp1, #0 + mov temp2, #32 + shr parm1, #1 wc +mmul if_c add temp1, parm2 wc + rcr temp1, #1 wc + rcr parm1, #1 wc + djnz temp2, @mmul +multiply_ret ret + +'******************************************************************************* +' Divide two 32-bit numbers producing a quotient and a remainder +' Changes parm1, parm2, parm3, temp1, temp2 +'******************************************************************************* +divide mov temp2, #32 + mov temp1, #0 + abs parm1, parm1 wc + muxc parm3, #%11 + abs parm2, parm2 wc,wz + if_c xor parm3, #%01 +' if_nz jmp #mdiv +' mov parm1, #0 +' jmp divide_ret +mdiv shr parm2, #1 wc,wz + rcr temp1, #1 + if_nz djnz temp2, @mdiv +mdiv2 cmpsub parm1, temp1 wc + rcl parm2, #1 + shr temp1, #1 + djnz temp2, @mdiv2 +divide_ret ret + +'******************************************************************************* +' These are working registers. The parm registers are generally used to pass +' parameters from one routine to another, and the temp registers are used as +' temporary storage within a routine. +'******************************************************************************* + +'******************************************************************************* +' Addresses of variables in the dictionary, and the hex table +'******************************************************************************* +a_hexstr long @hexstr+Q +a_last long @last+Q +a_state long @state+Q +a_dp long @dp+Q +a_tib long @tib+Q +a_verbose long @verbose+Q +a_inputidx long @greaterin+Q +a_inputlen long @poundtib+Q + +'******************************************************************************* +' The data and return stack pointers, and their base addresses +'******************************************************************************* +'stackptr long 0 +'stackptr0 long 0 +'returnptr long 0 +'returnptr0 long 0 +stackptr long @stack+16 +stackptr0 long @stack+16 +returnptr long @retstk +returnptr0 long @retstk + +'******************************************************************************* +' The input file pointer used during initialization +'******************************************************************************* +infileptr long @infile+Q + +'******************************************************************************* +' Constants +'******************************************************************************* +minus4 long -4 + + fit $1f0 + + orgh + +pfthconfig long @xboot_1+Q ' Initial word to execute + long @stack+Q+16 ' Starting stack pointer + long @stack+Q+16 ' Empty stack pointer value + long @retstk+Q ' Starting return pointer + long @retstk+Q ' Empty return pointer value +stack long 0[100] ' Data stack +retstk long 0[100] ' Return stack + +'******************************************************************************* +' Input buffer and hex table +'******************************************************************************* +hexstr byte "0123456789abcdef" +inputbuf byte 0[200] + +'******************************************************************************* +' This is the beginning of the dictionary. The kernel words are specified below +'******************************************************************************* +exit_L word 0 + byte FLAG_CORE, 4, "exit" + long +exit_X word exitfunc, 0 + +quit_L word @exit_L+Q + byte FLAG_CORE, 4, "quit" + long +quit_X word quitfunc, 0 + +abort_L word @quit_L+Q + byte FLAG_CORE, 5, "abort" + long +abort_X word abortfunc, 0 + +execute_L word @abort_L+Q + byte FLAG_CORE, 7, "execute" + long +execute_X word executefunc, 0 + +word_L word @execute_L+Q + byte FLAG_CORE, 4, "word" + long +word_X word wordfunc, 0 + +find_L word @word_L+Q + byte FLAG_CORE, 4, "find" + long +find_X word findfunc, 0 + +getchar_L word @find_L+Q + byte FLAG_CORE, 7, "getchar" + long +getchar_X word getcharfunc, 0 + +getfchar_L word @getchar_L+Q + byte FLAG_CORE, 8, "getfchar" + long +getfchar_X word getfcharfunc, 0 + +key_L word @getfchar_L+Q + byte FLAG_CORE, 3, "key" + long +key_X word deferfunc, @key_B+Q +key_B word @getfchar_X+Q, 0 +'key_B word @getchar_X+Q, 0 + +create_L word @key_L+Q + byte FLAG_CORE, 6, "create" + long +create_X word createfunc, 0 + +_lit_L word @create_L+Q + byte FLAG_LIT, 4, "_lit" + long +_lit_X word _litfunc, 0 + +_gethex_L word @_lit_L+Q + byte FLAG_CORE, 7, "_gethex" + long +_gethex_X word _gethexfunc, 0 + +emit_L word @_gethex_L+Q + byte FLAG_CORE, 4, "emit" + long +emit_X word emitfunc, 0 + +store_L word @emit_L+Q + byte FLAG_CORE, 1, "!" + long +store_X word storefunc, 0 + +fetch_L word @store_L+Q + byte FLAG_CORE, 1, "@" + long +fetch_X word fetchfunc, 0 + +wstore_L word @fetch_L+Q + byte FLAG_CORE, 2, "w!" + long +wstore_X word wstorefunc, 0 + +wfetch_L word @wstore_L+Q + byte FLAG_CORE, 2, "w@" + long +wfetch_X word wfetchfunc, 0 + +cstore_L word @wfetch_L+Q + byte FLAG_CORE, 2, "c!" + long +cstore_X word cstorefunc, 0 + +cfetch_L word @cstore_L+Q + byte FLAG_CORE, 2, "c@" + long +cfetch_X word cfetchfunc, 0 + +plus_L word @cfetch_L+Q + byte FLAG_CORE, 1, "+" + long +plus_X word plusfunc, 0 + +minus_L word @plus_L+Q + byte FLAG_CORE, 1, "-" + long +minus_X word minusfunc, 0 + +multiply_L word @minus_L+Q + byte FLAG_CORE, 1, "*" + long +multiply_X word multfunc, 0 + +divide_L word @multiply_L+Q + byte FLAG_CORE, 1, "/" + long +divide_X word dividefunc, 0 + +mod_L word @divide_L+Q + byte FLAG_CORE, 3, "mod" + long +mod_X word modfunc, 0 + +and_L word @mod_L+Q + byte FLAG_CORE, 3, "and" + long +and_X word andfunc, 0 + +or_L word @and_L+Q + byte FLAG_CORE, 2, "or" + long +or_X word orfunc, 0 + +xor_L word @or_L+Q + byte FLAG_CORE, 3, "xor" + long +xor_X word xorfunc, 0 + +less_L word @xor_L+Q + byte FLAG_CORE, 1, "<" + long +less_X word lessfunc, 0 + +equal_L word @less_L+Q + byte FLAG_CORE, 1, "=" + long +equal_X word equalfunc, 0 + +greater_L word @equal_L+Q + byte FLAG_CORE, 1, ">" + long +greater_X word greaterfunc, 0 + +rshift_L word @greater_L+Q + byte FLAG_CORE, 6, "rshift" + long +rshift_X word rshiftfunc, 0 + +lshift_L word @rshift_L+Q + byte FLAG_CORE, 6, "lshift" + long +lshift_X word lshiftfunc, 0 + +depth_L word @lshift_L+Q + byte FLAG_CORE, 5, "depth" + long +depth_X word depthfunc, 0 + +tib_L word @depth_L+Q + byte FLAG_VAR, 3, "tib" + long +tib_X word varfunc, @tib+Q+4 +tib long @inputbuf+Q + word @fetch_X+Q, 0 + long + +poundtib_L word @tib_L+Q + byte FLAG_VAR, 4, "#tib" + long +poundtib_X word varfunc, 0 +poundtib long 0 + +greaterin_L word @poundtib_L+Q + byte FLAG_VAR, 3, ">in" + long +greaterin_X word varfunc, 0 +greaterin long 0 + +dp_L word @greaterin_L+Q + byte FLAG_VAR, 2, "dp" + long +dp_X word varfunc, 0 +dp long @_here+Q + +last_L word @dp_L+Q + byte FLAG_VAR, 4, "last" + long +last_X word varfunc, 0 +last long @_last+Q + +state_L word @last_L+Q + byte FLAG_VAR, 5, "state" + long +state_X word varfunc, 0 +state long 0 + +base_L word @state_L+Q + byte FLAG_VAR, 4, "base" + long +base_X word varfunc, 0 +base long 16 + +verbose_L word @base_L+Q + byte FLAG_VAR, 7, "verbose" + long +verbose_X word varfunc, 0 +verbose long 0 + +forth_L word @verbose_L+Q + byte FLAG_VAR, 5, "forth" + long +forth_X word varfunc, 0 + long @forth+Q + +drop_L word @forth_L+Q + byte FLAG_CORE, 4, "drop" + long +drop_X word dropfunc, 0 + +dup_L word @drop_L+Q + byte FLAG_CORE, 3, "dup" + long +dup_X word dupfunc, 0 + +swap_L word @dup_L+Q + byte FLAG_CORE, 4, "swap" + long +swap_X word swapfunc, 0 + +pick_L word @swap_L+Q + byte FLAG_CORE, 4, "pick" + long +pick_X word pickfunc, 0 + +roll_L word @pick_L+Q + byte FLAG_CORE, 4, "roll" + long +roll_X word rollfunc, 0 + +tor_L word @roll_L+Q + byte FLAG_CORE, 2, ">r" + long +tor_X word torfunc, 0 + +fromr_L word @tor_L+Q + byte FLAG_CORE, 2, "r>" + long +fromr_X word fromrfunc, 0 + +colon_L word @fromr_L+Q + byte FLAG_CORE, 1, ":" + long +colon_X word colonfunc, 0 + +semicolon_L word @colon_L+Q + byte FLAG_SEMI, 1, ";" + long +semicolon_X word semicolonfunc, 0 + +cogfetch_L word @semicolon_L+Q + byte FLAG_CORE, 4, "cog@" + long +cogfetch_X word cogfetchfunc, 0 + +cogstore_L word @cogfetch_L+Q + byte FLAG_CORE, 4, "cog!" + long +cogstore_X word cogstorefunc, 0 + +cogx1_L word @cogstore_L+Q + byte FLAG_CORE, 5, "cogx1" + long +cogx1_X word cogx1func, 0 + +_jz_L word @cogx1_L+Q + byte FLAG_JMP, 3, "_jz" + long +_jz_X word _jzfunc, 0 + +cmove_L word @_jz_L+Q + byte FLAG_CORE, 5, "cmove" + long +cmove_X word cmovefunc, 0 + +dotx_L word @cmove_L+Q + byte FLAG_CORE, 2, ".x" + long +dotx_X word dotxfunc, 0 + +'******************************************************************************* +' SPI/SD Variables +'******************************************************************************* +spi_vars_L word @dotx_L+Q + byte FLAG_VAR, 8, "spi_vars" + long +spi_vars_X word varfunc, 0 +spi_vars long 0 ' SPI_engine_cog + long 0 ' SPI_command + long 0 ' SPI_block_index + long 0 ' SPI_buffer_address + long 0 ' SD_rootdir + long 0 ' SD_filesystem + long 0 ' SD_clustershift + long 0 ' SD_dataregion + long 0 ' SD_fat1 + long 0 ' SD_sectorsperfat + long 0 ' SD_currdir + +argc_L word @spi_vars_L+Q + byte FLAG_VAR, 4, "argc" + long +argc_X word confunc, 0 +argc_B long 0 + +argv_L word @argc_L+Q + byte FLAG_VAR, 4, "argv" + long +argv_X word confunc, 0 +argv_B long 0 + +hostcwd_L word @argv_L+Q + byte FLAG_VAR, 7, "hostcwd" + long +hostcwd_X word confunc, 0 +hostcwd_B long 0 + +'******************************************************************************* +' A small number of compiled words follow below. These are used by the boot +' interpreter. +'******************************************************************************* + ' : here dp @ ; +here_L word @hostcwd_L+Q + byte FLAG_DEF, 4, "here" + long +here_X word execlistfunc, 0 + word @dp_X+Q, @fetch_X+Q, 0 + long + + ' : allot dp @ + dp ! ; +allot_L word @here_L+Q + byte FLAG_DEF, 5, "allot" + long +allot_X word execlistfunc, 0 + word @dp_X+Q, @fetch_X+Q, @plus_X+Q, @dp_X+Q, @store_X+Q, 0 + long + + ' : , here ! 4 allot ; +comma_L word @allot_L+Q + byte FLAG_DEF, 1, "," + long +comma_X word execlistfunc, 0 + word @here_X+Q, @store_X+Q, @_lit_X+Q, 4, @allot_X+Q, 0 + long + + ' : _jmp r> @ >r ; +_jmp_L word @comma_L+Q + byte FLAG_JMP, 4, "_jmp" + long +_jmp_X word execlistfunc, 0 + word @fromr_X+Q, @wfetch_X+Q, @tor_X+Q, 0 + long + + ' : count 0 pick 1 + 1 roll c@ ; +count_L word @_jmp_L+Q + byte FLAG_DEF, 5, "count" + long +count_X word execlistfunc, 0 + word @_lit_X+Q, 0, @pick_X+Q, @_lit_X+Q, 1, @plus_X+Q, @_lit_X+Q, 1, @roll_X+Q, @cfetch_X+Q, 0 + long + + ' : accept ( addr size -- num ) \ Accept a string from the input source +accept_L word @count_L+Q + byte FLAG_DEF, 6, "accept" + long +accept_X word execlistfunc, 0 + ' >r dup + word @tor_X+Q, @dup_X+Q + ' r> dup 1 < _jz _accept4 +accept_1 word @fromr_X+Q, @dup_X+Q, @_lit_X+Q, 1, @less_X+Q, @_jz_X+Q, @accept_4+Q + ' drop swap - exit + word @drop_X+Q, @swap_X+Q, @minus_X+Q, @exit_X+Q + ' >r key +accept_4 word @tor_X+Q, @key_X+Q + ' dup 0d = over 0a = or + word @dup_X+Q, @_lit_X+Q, $0d, @equal_X+Q, @_lit_X+Q, 1, @pick_X+Q, @_lit_X+Q, $0a, @equal_X+Q, @or_X+Q + ' _jz _accept2 + word @_jz_X+Q, @accept_2+Q + ' cr drop swap - + word @_lit_X+Q, 13, @emit_X+Q, @_lit_X+Q, 10, @emit_X+Q, @drop_X+Q, @swap_X+Q, @minus_X+Q + ' r> drop exit + word @fromr_X+Q, @drop_X+Q, @exit_X+Q + ' dup 8 = _jz _accept3 +accept_2 word @dup_X+Q, @_lit_X+Q, 8, @equal_X+Q, @_jz_X+Q, @accept_3+Q + ' drop over over - _jz _accept1 + word @drop_X+Q, @_lit_X+Q, 1, @pick_X+Q, @_lit_X+Q, 1, @pick_X+Q, @minus_X+Q, @_jz_X+Q, @accept_1+Q + ' 1 - r> 1 + >r + word @_lit_X+Q, 1, @minus_X+Q, @fromr_X+Q, @_lit_X+Q, 1, @plus_X+Q, @tor_X+Q + ' 8 emit bl emit 8 emit _jmp _accept1 + word @_lit_X+Q, 8, @emit_X+Q, @_lit_X+Q, 32, @emit_X+Q, @_lit_X+Q, 8, @emit_X+Q, @_jmp_X+Q, @accept_1+Q + ' dup emit over c! 1 + +accept_3 word @dup_X+Q, @emit_X+Q, @_lit_X+Q, 1, @pick_X+Q, @cstore_X+Q, @_lit_X+Q, 1, @plus_X+Q + ' r> 1 - >r _jmp _accept1 + word @fromr_X+Q, @_lit_X+Q, 1, @minus_X+Q, @tor_X+Q, @_jmp_X+Q, @accept_1+Q, 0 + long + + ' : refill tib 200 accept #tib ! 0 >in ! ; +refill_L word @accept_L+Q + byte FLAG_DEF, 6, "refill" + long +refill_X word execlistfunc, 0 + word @tib_X+Q, @_lit_X+Q, 200, @accept_X+Q, @poundtib_X+Q, @store_X+Q, @_lit_X+Q, 0, @greaterin_X+Q, @store_X+Q, 0 + long + + ' : compile, here w! 2 allot ; +compcomma_L word @refill_L+Q + byte FLAG_DEF, 8, "compile," + long +compcomma_X word execlistfunc, 0 + word @here_X+Q, @wstore_X+Q, @_lit_X+Q, 2, @allot_X+Q, 0 + long + +'******************************************************************************* +' The boot interpreter follows below. +'******************************************************************************* + ' : xboot ( This word runs a simple interpreter ) +xboot_L word @compcomma_L+Q + byte FLAG_DEF, 5, "xboot" + long +xboot_X word execlistfunc, 0 + + ' 20 word 0 pick c@ _jz _xboot2 ( Get word, refill if empty ) +xboot_1 word @_lit_X+Q, $20, @word_X+Q, @_lit_X+Q, 0, @pick_X+Q, @cfetch_X+Q, @_jz_X+Q, @xboot_2+Q + + ' find 0 pick _jz _xboot3 ( Find word, get number if not found ) + word @find_X+Q, @_lit_X+Q, 0, @pick_X+Q, @_jz_X+Q, @xboot_3+Q + + ' state @ = _jz _xboot4 ( Go execute if not compile mode or immediate ) + word @state_X+Q, @fetch_X+Q, @equal_X+Q, @_jz_X+Q, @xboot_4+Q + + ' compile, _jmp _xboot1 ( Otherwise, compile and loop again ) + word @compcomma_X+Q, @_jmp_X+Q, @xboot_1+Q + + ' execute _jmp _xboot1 ( Execute and loop again ) +xboot_4 word @execute_X+Q, @_jmp_X+Q, @xboot_1+Q + + ' drop count _gethex ( Get number ) +xboot_3 word @drop_X+Q, @count_X+Q, @_gethex_X+Q + + ' state @ _jz _xboot1 ( Loop again if not compile mode ) + word @state_X+Q, @fetch_X+Q, @_jz_X+Q, @xboot_1+Q + + ' ['] _lit , , _jmp _xboot1 ( Otherwise, compile number and loop again ) + word @_lit_X+Q, @_lit_X+Q, @compcomma_X+Q, @compcomma_X+Q, @_jmp_X+Q, @xboot_1+Q + + ' drop refill _jmp _xboot1 ( Refill and loop again ) +xboot_2 word @drop_X+Q, @refill_X+Q, @_lit_X+Q, 13, @emit_X+Q, @_jmp_X+Q, @xboot_1+Q, 0 + long + +switch_L word @xboot_L+Q + byte FLAG_DEF, 6, "switch" + long +switch_X word execlistfunc, 0 + word @_lit_X+Q, @getchar_X+Q, @_lit_X+Q, @key_B+Q, @store_X+Q, 0 + long + +_last long + +_loop_L word @switch_L+Q + byte FLAG_CORE, 5, "_loop" + long +_loop_X word _loopfunc, 0 + +_here long + +'******************************************************************************* +' The Forth source files follow below. They will be compiled into the +' dictionary, which will over-write the source data. Some padding space is +' included to ensure that we don't over-write the source data before it is +' compiled. +'******************************************************************************* + long 0[100] +infile byte "1 verbose !", 13 + file "init.fth" + file "comus.fth" + 'file "see.fth" + 'file "propwords.fth" + 'file "bufser.fth" + 'file "i2c.fth" + 'file "fds.fth" + 'file "time.fth" + 'file "toggle.fth" + 'file "primes.fth" + 'byte 13, " 1 verbose !", 13 + 'byte " .s ", 13 + 'file "chess.fth" + +'******************************************************************************* +' Enable serial output, print version string and switch to serial input +'******************************************************************************* + byte 13 + byte " 1 verbose !" + byte " pfthversion type cr" + byte " switch", 13 + + +{ ++-------------------------------------------------------------------- +| TERMS OF USE: MIT License ++-------------------------------------------------------------------- +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++------------------------------------------------------------------ +} \ No newline at end of file diff --git a/pfth103_p2/primes.fth b/pfth103_p2/primes.fth new file mode 100755 index 0000000..03d9864 --- /dev/null +++ b/pfth103_p2/primes.fth @@ -0,0 +1,62 @@ +\ primes.4th +\ +\ Example code for kForth +\ Copyright (c) 1998 Creative Consulting for Research and Education +\ + +\ Test for a prime number. Return the largest divisor (< n ) +\ and a flag indicating whether the number is prime or not. + +: ?prime ( n -- m flag | is n a prime number? ) +\ if flag is false (0), m is the largest divisor of n + abs + dup 3 > \ is n > 3 ? + if + abs + dup 2 /mod + swap 0= + if \ is n divisible by 2 ? + nip false + else + 1- \ check for divisibility starting + begin \ with n/2 - 1 and counting down + 2dup mod + over 1 > + and + while + 1- + repeat + nip + dup 1 <= + then + else + dup 1 > IF drop 1 true ELSE false THEN + then +; + +: test_prime ( n -- | test for prime number and display result ) + ?prime + if + ." is a prime number" drop + else + ." is NOT prime. Its largest divisor is " . + then + cr +; + +: list_primes ( n -- | list all the prime numbers from 2 to n ) + abs + dup 0> + if + 1+ 2 do + i ?prime + if + i . cr + then + drop + loop + else + drop + then +; + diff --git a/pfth103_p2/propwords.fth b/pfth103_p2/propwords.fth new file mode 100755 index 0000000..884462c --- /dev/null +++ b/pfth103_p2/propwords.fth @@ -0,0 +1,40 @@ +( PROP WORDS) +hex + +( REGISTER ACCESS ) +: cnt@ 1f1 cog@ ; +: ina@ 1f2 cog@ ; +: outa@ 1f4 cog@ ; +: outa! 1f4 cog! ; +: dira@ 1f6 cog@ ; +: dira! 1f6 cog! ; +: clkfreq@ 0 @ ; + +( BIT SETTING AND CLEARING ) +: dirasetbit dira@ or dira! ; +: diraclrbit invert dira@ and dira! ; +: outasetbit outa@ or outa! ; +: outaclrbit invert outa@ and outa! ; + +( HUBOPS ) +: cogid ( ... cogid ) 0 0cfc0001 cogx1 ; +: locknew ( ... locknum ) 0 0cfc0004 cogx1 ; +: lockret ( locknum ... ) 0cfc0005 cogx1 drop ; +: cogstop ( cognum ... ) 0c7c0003 cogx1 drop ; +: coginit ( codeptr dataptr cognum ... cognum ) + >r 0e lshift or 2 lshift r> or 0ffc0002 cogx1 ; +: cognew ( codeptr dataptr ... cognum ) 8 coginit ; +: waitcnt ( count ... count ) f8fc0000 cogx1 ; +: reboot 80 0cfc0000 cogx1 ; + +decimal + +( ANS UTILITY ) +: ms ( msec ... ) cnt@ swap clkfreq@ 1000 / * + waitcnt drop ; + +( ANS TOOLS EXT ) +: bye reboot ; + +( ENABLE SERIAL OUTPUT ) +1 30 lshift dup outa! dira! + diff --git a/pfth103_p2/rc4.fth b/pfth103_p2/rc4.fth new file mode 100755 index 0000000..d974dcc --- /dev/null +++ b/pfth103_p2/rc4.fth @@ -0,0 +1,42 @@ +0 value ii 0 value jj +0 value KeyAddr 0 value KeyLen +create SArray 256 allot \ state array of 256 bytes +: KeyArray KeyLen mod KeyAddr ; + +: get_byte + c@ ; +: set_byte + c! ; +: as_byte 255 and ; +: reset_ij 0 TO ii 0 TO jj ; +: i_update 1 + as_byte TO ii ; +: j_update ii SArray get_byte + as_byte TO jj ; +: swap_s_ij + jj SArray get_byte + ii SArray get_byte jj SArray set_byte + ii SArray set_byte +; + +: rc4_init ( KeyAddr KeyLen -- ) + 256 min TO KeyLen TO KeyAddr + 256 0 DO i i SArray set_byte LOOP + reset_ij + BEGIN + ii KeyArray get_byte jj + j_update + swap_s_ij + ii 255 < WHILE + ii i_update + REPEAT + reset_ij +; +: rc4_byte + ii i_update jj j_update + swap_s_ij + ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor +; + +hex +create AKey 61 c, 8A c, 63 c, D2 c, FB c, +\ create AKey 97 c, 8A c, 99 c, D2 c, FB c, +: test cr 0 DO rc4_byte . LOOP cr ; +AKey 5 rc4_init +2C F9 4C EE DC 5 test \ output should be: F1 38 29 C9 DE + diff --git a/pfth103_p2/rc4time.fth b/pfth103_p2/rc4time.fth new file mode 100755 index 0000000..243ec57 --- /dev/null +++ b/pfth103_p2/rc4time.fth @@ -0,0 +1,49 @@ +0 value ii 0 value jj +0 value KeyAddr 0 value KeyLen +create SArray 256 allot \ state array of 256 bytes +create Results 100 allot +: KeyArray KeyLen mod KeyAddr ; + +: get_byte + c@ ; +: set_byte + c! ; +: as_byte 255 and ; +: reset_ij 0 TO ii 0 TO jj ; +: i_update 1 + as_byte TO ii ; +: j_update ii SArray get_byte + as_byte TO jj ; +: swap_s_ij + jj SArray get_byte + ii SArray get_byte jj SArray set_byte + ii SArray set_byte +; + +: rc4_init ( KeyAddr KeyLen -- ) + 256 min TO KeyLen TO KeyAddr + 256 0 DO i i SArray set_byte LOOP + reset_ij + BEGIN + ii KeyArray get_byte jj + j_update + swap_s_ij + ii 255 < WHILE + ii i_update + REPEAT + reset_ij +; +: rc4_byte + ii i_update jj j_update + swap_s_ij + ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor +; + +\ : cnt@ 0 ; + +hex +create AKey 61 c, 8a c, 63 c, d2 c, fb c, +\ create AKey 97 c, 8a c, 99 c, d2 c, fb c, +: test 0 DO rc4_byte Results i + c! LOOP ; +: test1 cr 0 do Results i + c@ . loop cr ; +: time hex cnt@ +AKey 5 rc4_init +2c f9 4c ee dc 5 test \ output should be: f1 38 29 c9 de +cnt@ 5 test1 swap - 13880 / decimal . ." msec" cr ; +decimal + diff --git a/pfth103_p2/readme.txt b/pfth103_p2/readme.txt new file mode 100755 index 0000000..01ee924 --- /dev/null +++ b/pfth103_p2/readme.txt @@ -0,0 +1,244 @@ + pfth Version 1.03 + November 8, 2013 + Dave Hein + (with additions from G. Herzog) + +INTRODUCTION +------------ + +pfth is an ANS Forth interpreter that runs on the Propeller. It is written in +PASM and Forth, and it can be built using the Prop Tool or BST. pfth +implements all 133 of the ANS Forth core words, and 38 of the 45 core ext +words. pfth will run on any Propeller board that supports the standard serial +interface. The default settings of the serial port are 115200 baud, 8 bits, no +parity and 1 stop bit. + +After loading and communications is established, use 'words' to verify that the +display is correct. The CR word is defined to emit both a carriage return and +a line feed. If your terminal displays an extra line you can either disable +the linefeed character on your terminal, or re-define CR to only emit a +carriage return. + + +VERSIONS OF SPIN FILES +---------------------- + +There are four versions of pfth. + +The first version can be used to build stand-alone Forth applications. It is +in pfth.spin. In this version, Forth programs are included using the Spin FILE +directive. + +A second version interfaces to an SD card and can execute Forth programs on +the SD card. This version is in sdpfth.spin. The program is set up for the C3 +card, but it can be modified to support other cards. + +The third version is named ospfth.spin, and runs under the Spinix operating +system. When Spinix starts up pfth it provides information about the SD pins, +the current working directory and a parameter list. The OS version of pfth +uses this information to initialize the SD card driver and change to the +working directory. It includes the file given by the parameter list. + +The final version is called chess.spin, and implements a chess program. After +the program is loaded type "chess" to start playing. A move is entered by +typing the source and destination postions separated by a "-". As an example, +the move "D2-D4" will move the white queen's pawn two spaces ahead. + + +LEXICON +------- + +pfth has over 50 kernel words, with most of them from the ANS core word set. +The source code for pfth is contained in pfth.spin, init.fth and other Forth +programs included at the end of pfth.spin. + +Two of the non-standard words implemented by pfth are cog@ and cog!. These are +are used to read and write cog memory locations. Their main purpose is to +access the Prop registers, such as CNT, INA and OUTA. + +Another non-standard word is cogx1, which is used to execute native Prop +instructions. The TOS contains the Prop instruction, and the next value on the +stack is used for the destination register value. The result of the execution +of the instruction is returned on the stack. + +Some other non-standard words are _lit, _gethex, _jz and .x. + +_lit is used to encode literal values. +_gethex is used during the boot phase to convert numeric strings to hex values. +_jz implements a jump-on-zero primitive. +.x is used for debug purposes, and it prints values as 8-digit hex numbers. + +Some of the kernel words are shown below. + +Interpreter Words Math and Logical Words Memory Access +----------------- ---------------------- ------------- +evaluate + ! +execute - @ +find * c! +word / c@ +refill mod +create and Console I/O +: or ----------- +; xor emit + < key + = accept +Program Termination > +------------------- lshift Primitive Words +abort rshift --------------- +exit _lit +quit Variables _gethex + --------- _jz +Stack Operations #tib .x +---------------- tib +drop >in Propeller Words +pick base --------------- +roll dp cog! +>r last cog@ +r> state cogx1 +depth +swap +dup + + +pfth also contains a small number of pre-compiled Forth words written +in Forth. These words are here, allot, ",", _jmp and count. The definition +of these words is as follows. + +: here dp @ ; +: allot dp @ + dp ! ; +: , here ! 4 allot ; +: _jmp r> @ >r ; +: count 0 pick 1 + 1 roll c@ ; + + +AT START UP +----------- + +When pfth starts up, it runs a small boot interpreter that compiles +the ANS dictionary contained in init.fth. This file is included in the +PASM binary image using the PASM FILE directive. Other Forth source files +may be included after init.fth to add additional words and to implement a +specific application. + +The boot interpreter can only handle 16-bit hex numbers, so pfth is in the hex +mode when first starting up. The boot interpreter has no error handling +capability, and is only used to build the initial dictionary. The boot +interpreter uses a limited vocabulary consisting of the following 20 +kernel words. + + dp state _lit _gethex : ; c@ @ ! + = pick roll drop + r> >r word find execute refill + +The boot interpreter is shown below in a pseudo-Forth language. The +labels (label1), (label2), etc. are actually encoded as PASM labels, but +they are shown symbolically in the code below. + +: xboot +(label1) + 20 word 0 pick c@ _jz (label2) ( Get word, refill if empty ) + find 0 pick _jz (label3) ( Find word, get number if not found ) + state @ = _jz (label4) ( Go execute if not compile mode or immediate ) + , _jmp (label1) ( Otherwise, compile and loop again ) +(label4) + execute _jmp (label1) ( Execute and loop again ) +(label3) + drop count _gethex ( Get number ) + state @ _jz (label1) ( Loop again if not compile mode ) + _lit _lit , , _jmp (label1) ( Otherwise, compile number and loop again ) +(label2) + drop refill _jmp (label1) ( Refill and loop again ) +; + +The boot interpreter compiles init.fth, which then runs the main interpreter. +The main interpreter performs some error handling by checking for undefined +words and stack underflows. It also handles negative numbers and numbers in +any base. + + +SOURCE PROGRAMS +--------------- + +There are a number of additional Forth source programs included in this +distribution that can be run by pfth. Open and read these as text files to +learn more details. + +comus.fth - provides a several useful non-standard words that are commonly + used. + +starting.fth - contains samples of code from the "Starting Forth" tutorial. + +rc4time.fth - implements the RC4 code included in the Wikipedia Forth entry. + It also displays the time required to run the RC4 code. + +i2c.fth - is a Forth implementation of Mike Green's basic_i2c_driver from + the OBEX. + +fds.fth - implementes some of the functions from the FullDuplexSerial + driver. It uses the binary PASM code from FullDuplexSerial. + +toggle.fth - will start up a cog running the Forth interpreter. It toggles + P15, but it can easily be modified to toggle another pin. + +ted.fth - a simple line-oriented text editor based on the ED text editor. + +linux.fth - implements some basic linux commands, such as ls, cat, rm and cp. + + +STARTING FORTH COGS +------------------- + +Forth cogs are started with cognew or coginit by specifying the Forth cog image +as the execution pointer and a 5-long structure as the data pointer. The +5-long structure is defined as follow + +First long: Address of the body of a word that will be executed on startup +Second long: Initial value of the stack pointer +Third long: Address of the beginning of the stack +Fourth long: Initial value of the return stack pointer +Fifth long: Address of the beginning the the return stack + + +CELL SIZE +--------- + +The cell size for pfth is 32 bits. The words !, @ and "," words access 32-bit +values that are 32-bit aligned. Additional words are provide for smaller unit +access, such as w! and w@ for word access, and c! and c@ for byte access. + +The compiled list cell size is 16 bits. The compile, word must be used when +compiling execution tokens into a list rather than just using the "," word. + + +DICTIONARY ENTRY FORMAT +----------------------- + +The format for the pfth dictionary entry is shown below. The beginning of a +word entry and its body are long-aligned. The link pointer contains the +address of the previous word in the dictionary. + +The flags byte contains various flag bits that indicate if the word is an +immediate word, a literal number or string, or a jump word. The name length +byte and the name string specify the name of the word. It is followed by +padding bytes that ensure long alignment. + +The code pointer contains the cog address of the PASM code that is to be +executed. The execution token for a word points to this field. The does> +pointer contains the hub address of a list of execution tokens that is to be +called. + +The body is a variable length field that contains the contents of a variable or +the list of execution tokens for a compiled word. The list for a compiled word +consists of one execution token per word, and is terminated by a zero-valued +word. + + Offset Content Size + ------ ------- ---- + 0 Link Pointer word + 2 Flags byte + 3 Name Length byte + 4 Name String Len bytes + 4+Len Padding (-Len) & 3 bytes + 4+(Len+3)&(-4) Code Pointer word + 6+(Len+3)&(-4) DOES> Pointer word + 8+(Len+3)&(-4) Body Variable + diff --git a/pfth103_p2/see.fth b/pfth103_p2/see.fth new file mode 100755 index 0000000..da7ee86 --- /dev/null +++ b/pfth103_p2/see.fth @@ -0,0 +1,65 @@ +: cond.name ( link ) + dup link>flags c@ dup 2 and ( link flag literal ) + if + 8 and + if + .name + then + else + 4 and + if + [char] s emit [char] " emit bl emit + else + .name + then + then +; + +: seefunc ( xt ) + >body ( listptr ) + begin + dup w@ ( listptr xt ) + while + dup w@ ( listptr xt ) + >link .name link>flags c@ dup 2 and ( listptr flags literal ) + if + 8 and ( listptr flags jump ) + if + 2 + dup dup w@ swap - 2 - 2 / . + else + 2 + dup w@ . + then + else + 4 and ( listptr string ) + if + 2 + dup count type [char] " emit space + dup c@ + 0 2 - and + then + then + compsize + ( listptr+=compsize) + repeat + drop +; + +: see + ' dup ( xt xt ) + if + dup >flags c@ dup 16 and ( xt flags kernel ) + if + drop + drop + ." Kernel Word" + else + 32 and + if + drop + ." Variable" + else + seefunc + then + then + else + drop + ." ?" + then +; diff --git a/pfth103_p2/serial.fth b/pfth103_p2/serial.fth new file mode 100755 index 0000000..8580527 --- /dev/null +++ b/pfth103_p2/serial.fth @@ -0,0 +1,20 @@ +: waitcnt begin dup cnt@ - 0< until ; + +: putch 256 or dup + clkfreq@ 9600 / + 11 >r + cnt@ + begin + r> 1- dup >r + while + rot dup + 30 lshift + outa! + 1 rshift + swap rot dup rot + + waitcnt + repeat + r> 2drop 2drop +; + +: test cnt@ 65 putch cnt@ swap - 80 / . ; + diff --git a/pfth103_p2/starting.fth b/pfth103_p2/starting.fth new file mode 100755 index 0000000..d2cc9c3 --- /dev/null +++ b/pfth103_p2/starting.fth @@ -0,0 +1,65 @@ +: STAR 42 EMIT ; +: MARGIN CR 30 SPACES ; +: BLIP MARGIN STAR ; +: STARS 0 DO STAR LOOP ; +: BAR MARGIN 5 STARS ; +: F BAR BLIP BAR BLIP BLIP CR ; +: MULT CR 11 1 DO DUP I * . LOOP DROP ; +: TABLE CR 11 1 DO I MULT LOOP ; +: TABLE1 CR 11 1 DO 11 1 DO I J * . LOOP CR LOOP ; +: DUB 32767 1 DO I . I +LOOP ; +: GREET ." Hello, I speak Forth " ; +: GIFT ." chocolate" ; +: GIVER ." Mum" ; +: THANKS CR ." Dear " GIVER ." ," + CR ." Thanks for the " GIFT ." . " ; +: EGGSIZE DUP 18 < IF ." reject " ELSE + DUP 21 < IF ." small " ELSE + DUP 24 < IF ." medium " ELSE + DUP 27 < IF ." large " ELSE + DUP 30 < IF ." extra large " ELSE + ." error " + THEN THEN THEN THEN THEN DROP ; +: FALSE 0 ; +: TRUE -1 ; +: TEST IF ." non-" THEN ." zero " ; +: /CHECK ?DUP IF / THEN ; +: UNCOUNT DROP 1 - ; +: max-int -1 1 rshift ; +: min-int max-int negate 1 - ; +: max-uint -1 ; +: OUTPUT-TEST + ." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR + 41 BL DO I EMIT LOOP CR + 61 41 DO I EMIT LOOP CR + 127 61 DO I EMIT LOOP CR + ." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR + 9 1+ 0 DO I . LOOP CR + ." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR + 57 1+ 48 DO I 0 SPACES EMIT LOOP CR + ." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR + 71 1+ 65 DO I EMIT SPACE LOOP CR + ." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR + 5 1+ 0 DO I 48 + EMIT 2 SPACES LOOP CR + ." YOU SHOULD SEE TWO SEPARATE LINES:" CR + ." LINE 1" CR ." LINE 2" CR + ." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR + ." SIGNED: " MIN-INT . MAX-INT . CR + ." UNSIGNED: " 0 . MAX-UINT U. CR + ; + +output-test +f +10 mult +table +table1 +dub +greet +thanks cr +17 eggsize cr +22 eggsize cr +25 eggsize cr +28 eggsize cr +32 eggsize cr +0 test cr +1 test cr diff --git a/pfth103_p2/time.fth b/pfth103_p2/time.fth new file mode 100755 index 0000000..ac3f498 --- /dev/null +++ b/pfth103_p2/time.fth @@ -0,0 +1,2 @@ +: TIME CNT@ 100000 BEGIN 1 - DUP 0 = UNTIL DROP CNT@ SWAP - 8000 / . ; + diff --git a/pfth103_p2/toggle.fth b/pfth103_p2/toggle.fth new file mode 100755 index 0000000..724dcee --- /dev/null +++ b/pfth103_p2/toggle.fth @@ -0,0 +1,33 @@ +\ ############################################################################ +\ # toggle.fth - This program starts up a Forth cog that toggles P15 +\ # +\ # Copyright (c) 2012 Dave Hein +\ # MIT Licensed +\ ############################################################################ + +create cogstack 80 allot \ Allocate data stack space +create cogreturn 80 allot \ Allocate return stack space +create delaycnt 80000000 , \ This variable controls the blink rate + +hex +\ This word toggles bit P15 every "delaycnt" cycles +: toggle + 8000 dirasetbit cnt@ \ Set P15 for output and get CNT + begin + delaycnt @ + waitcnt \ Wait "delaycnt" cycles + 8000 outasetbit \ Set P15 + delaycnt @ + waitcnt \ Wait "delaycnt" cycles + 8000 outaclrbit \ Clear P15 + again ; \ Repeat forever +decimal + +create cogconfig \ Forth cog config structure + ' toggle >body , \ Get execution token for TOGGLE + cogstack , \ Initial value of stack ptr + cogstack , \ Empty value for stack ptr + cogreturn , \ Initial value of return ptr + cogreturn , \ Empty value for return ptr + +\ This word starts a cog running the TOGGLE word +: starttoggle forth @ cogconfig cognew ; + diff --git a/rom.h b/rom.h new file mode 100755 index 0000000..5b70b8e --- /dev/null +++ b/rom.h @@ -0,0 +1,2756 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +static unsigned char romdata[32768] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x40, 0x55, 0x55, 0xff, 0x40, 0x55, 0x15, + 0xff, 0x40, 0x55, 0x05, 0xff, 0x40, 0x55, 0x01, 0xff, 0x40, 0x55, 0x00, + 0xff, 0x40, 0x15, 0x00, 0xff, 0x40, 0x05, 0x00, 0xff, 0x40, 0x01, 0x00, + 0xff, 0x40, 0x00, 0x00, 0xff, 0x40, 0x00, 0x00, 0xff, 0x40, 0x01, 0x00, + 0xff, 0x40, 0x05, 0x00, 0xff, 0x40, 0x15, 0x00, 0xff, 0x40, 0x55, 0x00, + 0xff, 0x40, 0x55, 0x01, 0xff, 0x40, 0x55, 0x05, 0xff, 0x40, 0x55, 0x15, + 0xff, 0x40, 0x55, 0x55, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xaa, 0xaa, 0xaa, 0xbf, 0xaa, 0xaa, 0xaa, + 0xaf, 0xaa, 0xaa, 0xaa, 0xab, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x08, 0x00, 0x00, 0x14, 0x28, 0x00, 0x00, 0x15, 0xa8, 0x00, + 0x40, 0x15, 0xa8, 0x02, 0xf8, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x3f, + 0xfc, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0x1f, 0x40, 0x15, 0xa8, 0x02, + 0x00, 0x15, 0xa8, 0x00, 0x00, 0x14, 0x28, 0x00, 0x00, 0x10, 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, 0xe0, 0x0b, 0x00, 0x00, 0xf0, 0x0f, 0x00, + 0x00, 0xf4, 0x1f, 0x00, 0x00, 0xf5, 0x5f, 0x00, 0x40, 0xf5, 0x5f, 0x01, + 0x50, 0xf5, 0x5f, 0x05, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, + 0xa0, 0xfa, 0xaf, 0x0a, 0x80, 0xfa, 0xaf, 0x02, 0x00, 0xfa, 0xaf, 0x00, + 0x00, 0xf8, 0x2f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xd0, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, + 0xa0, 0x0a, 0x40, 0x15, 0xa0, 0x2a, 0x50, 0x15, 0xa0, 0xaa, 0x54, 0x15, + 0xa0, 0xaa, 0x57, 0x15, 0xa0, 0xea, 0x5f, 0x15, 0xa0, 0xfa, 0x7f, 0x15, + 0xa0, 0xfe, 0xff, 0x15, 0xa0, 0xff, 0xff, 0x17, 0xe0, 0xff, 0xff, 0x1f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xe0, 0xff, 0xff, 0x1f, + 0xa0, 0xff, 0xff, 0x17, 0xa0, 0xfe, 0xff, 0x15, 0xa0, 0xfa, 0x7f, 0x15, + 0xa0, 0xea, 0x5f, 0x15, 0xa0, 0xaa, 0x57, 0x15, 0xa0, 0xaa, 0x54, 0x15, + 0xa0, 0x2a, 0x50, 0x15, 0xa0, 0x0a, 0x40, 0x15, 0x80, 0x02, 0x00, 0x05, + 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, 0xbf, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, 0xab, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0x55, 0x55, 0x01, 0xaa, 0x54, 0x55, 0x01, 0xaa, 0x50, 0x55, 0x01, 0xaa, + 0x40, 0x55, 0x01, 0xaa, 0x00, 0x55, 0x01, 0xaa, 0x00, 0x54, 0x01, 0xaa, + 0x00, 0x50, 0x01, 0xaa, 0x00, 0x40, 0x01, 0xaa, 0x00, 0x00, 0x01, 0xaa, + 0x00, 0x00, 0x01, 0xaa, 0x00, 0x40, 0x01, 0xaa, 0x00, 0x50, 0x01, 0xaa, + 0x00, 0x54, 0x01, 0xaa, 0x00, 0x55, 0x01, 0xaa, 0x40, 0x55, 0x01, 0xaa, + 0x50, 0x55, 0x01, 0xaa, 0x54, 0x55, 0x01, 0xaa, 0x55, 0x55, 0x01, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, + 0x50, 0x55, 0x55, 0x15, 0x50, 0x55, 0x55, 0x15, 0x50, 0x55, 0x55, 0x15, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x55, 0x15, + 0x50, 0x55, 0x55, 0x15, 0x50, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x40, 0x55, 0x55, 0x01, + 0x50, 0x55, 0x55, 0x05, 0x50, 0x55, 0x55, 0x05, 0x50, 0xf5, 0x5f, 0x05, + 0x50, 0xff, 0xff, 0x05, 0xd0, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x2f, 0xf8, 0xff, 0xff, 0x2f, + 0xf8, 0xff, 0xff, 0x2f, 0xf8, 0xff, 0xff, 0x2f, 0xf0, 0xff, 0xff, 0x0f, + 0xf0, 0xff, 0xff, 0x0f, 0xd0, 0xff, 0xff, 0x07, 0x50, 0xff, 0xff, 0x05, + 0x50, 0xf5, 0x5f, 0x05, 0x50, 0x55, 0x55, 0x05, 0x50, 0x55, 0x55, 0x05, + 0x40, 0x55, 0x55, 0x01, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x01, 0x00, 0xa0, 0xea, 0xab, 0x2a, 0xa8, 0xfa, 0xaf, 0x2a, + 0xa8, 0xfa, 0xaf, 0x0a, 0x88, 0x5e, 0xb5, 0x02, 0x80, 0x5e, 0xb5, 0x02, + 0x80, 0x1f, 0xf4, 0x02, 0x80, 0x1f, 0xf4, 0x02, 0xc0, 0x0f, 0xf0, 0x03, + 0xc0, 0x0f, 0xf0, 0x03, 0xd0, 0x0b, 0xe0, 0x07, 0xd0, 0x0b, 0xe0, 0x07, + 0xd4, 0x0a, 0xa0, 0x17, 0xd4, 0x5f, 0xf5, 0x37, 0xf5, 0x5f, 0xf5, 0x7f, + 0xf5, 0x57, 0xd5, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x2a, 0x00, + 0xd4, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x0f, 0xe0, 0x5f, 0xf5, 0x1f, + 0xa8, 0x17, 0x80, 0x3e, 0xa8, 0x54, 0x00, 0x2a, 0xa8, 0x50, 0x01, 0x2a, + 0xa8, 0x40, 0x05, 0x2a, 0xa8, 0x00, 0x15, 0x2a, 0xa0, 0x42, 0x85, 0x0a, + 0xa0, 0x52, 0x81, 0x0a, 0x80, 0x5e, 0xa0, 0x02, 0x00, 0x3f, 0xa8, 0x14, + 0xe8, 0x7f, 0xfd, 0x3f, 0xf8, 0x7f, 0xfd, 0x2f, 0xfc, 0x7f, 0xfd, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x2a, + 0x00, 0x00, 0xa8, 0x2a, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0x55, 0xa8, 0x14, + 0x40, 0x55, 0xa9, 0x14, 0xf0, 0x5f, 0xad, 0x15, 0xf0, 0x4b, 0xfd, 0x15, + 0xf0, 0x2a, 0xfd, 0x05, 0x50, 0x2a, 0xfc, 0x01, 0x00, 0xaa, 0xa8, 0x00, + 0x00, 0xfd, 0xa8, 0x14, 0x40, 0xfd, 0xab, 0x14, 0x50, 0xf5, 0xaf, 0x15, + 0x50, 0xe1, 0xff, 0x15, 0x50, 0x80, 0xff, 0x05, 0x50, 0x80, 0xfe, 0x01, + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xa8, 0x00, + 0x00, 0x00, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x40, 0x15, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x50, 0x05, 0x14, 0x00, 0x50, 0x05, 0x14, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x55, 0x01, + 0x00, 0x40, 0x55, 0xa1, 0x00, 0x00, 0x80, 0xaa, 0x00, 0x00, 0xaa, 0xaa, + 0x00, 0xa8, 0xaa, 0x0a, 0xa0, 0xaa, 0x2a, 0x00, 0xaa, 0xaa, 0x02, 0x00, + 0xaa, 0x82, 0x02, 0x00, 0x0a, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc0, 0x03, 0xa8, + 0x00, 0xc0, 0x03, 0xa8, 0x00, 0xc0, 0x03, 0x28, 0x00, 0xc0, 0x03, 0x28, + 0x00, 0xc0, 0x03, 0x28, 0x00, 0xc0, 0x03, 0x28, 0x00, 0xc0, 0x03, 0x28, + 0x00, 0xc0, 0x03, 0x28, 0x00, 0xc0, 0x03, 0x28, 0x00, 0xc0, 0x03, 0x28, + 0x00, 0xc0, 0x03, 0x28, 0x00, 0xc0, 0x03, 0x28, 0x55, 0xd5, 0x57, 0x7d, + 0xff, 0xff, 0x57, 0x7d, 0xbe, 0xaa, 0x02, 0x3c, 0x54, 0x80, 0x02, 0x3d, + 0x50, 0x80, 0x02, 0x2d, 0x50, 0x81, 0x42, 0x2d, 0x40, 0x81, 0x42, 0x29, + 0x40, 0x85, 0x52, 0x29, 0x00, 0x85, 0x52, 0x28, 0x00, 0x95, 0x56, 0x28, + 0x00, 0x94, 0x16, 0x28, 0x00, 0xd4, 0x17, 0x28, 0x00, 0xd0, 0x07, 0x28, + 0x00, 0xd0, 0x07, 0x28, 0x00, 0xc0, 0x03, 0xa8, 0x00, 0xc0, 0x03, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0xaa, 0xea, 0x03, 0x54, 0xaa, 0xea, 0x03, 0x54, + 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, + 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, + 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, 0x50, 0x45, 0x01, 0x14, + 0x54, 0x55, 0x01, 0x14, 0x15, 0x54, 0x01, 0x14, 0x05, 0x50, 0x01, 0x14, + 0x05, 0x50, 0x01, 0x14, 0x15, 0x54, 0x01, 0x14, 0x54, 0x55, 0x01, 0x14, + 0x50, 0x45, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, + 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, + 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, 0x00, 0x40, 0x01, 0x14, + 0xaa, 0xea, 0x03, 0x54, 0xaa, 0xea, 0x03, 0x54, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0xcf, 0x00, 0x2a, 0x00, 0xff, + 0x00, 0xa8, 0x00, 0xff, 0x00, 0xa0, 0x02, 0x3f, 0x00, 0x80, 0x02, 0x0f, + 0x00, 0x0a, 0x00, 0x0f, 0x55, 0x7f, 0x55, 0x0f, 0x55, 0xfd, 0x55, 0x0f, + 0x00, 0xa0, 0x02, 0x0f, 0x00, 0x80, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xcf, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x20, 0xf0, 0x03, 0x00, + 0xa0, 0xfc, 0x00, 0x00, 0xa0, 0x3f, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, + 0xf0, 0x2b, 0x00, 0x00, 0xfc, 0xaa, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0xfc, 0x40, 0x00, 0x00, 0xf0, 0x53, 0x00, 0x00, 0xc0, 0x5f, 0x00, 0x00, + 0x00, 0x7f, 0x00, 0x00, 0x40, 0xfd, 0x00, 0x00, 0x50, 0xf5, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x05, 0x40, 0x05, 0x50, 0x15, 0x50, 0x15, 0x50, 0x15, 0x50, 0x15, + 0x50, 0x15, 0x50, 0x15, 0x40, 0x05, 0x40, 0x05, 0x40, 0x2f, 0xe0, 0x07, + 0x40, 0x2b, 0xe0, 0x03, 0x00, 0x2a, 0xa0, 0x02, 0x00, 0x2a, 0xa0, 0x02, + 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, + 0x00, 0x2a, 0xa0, 0x02, 0x00, 0x2a, 0xa0, 0x02, 0x00, 0x2a, 0xa0, 0x02, + 0x00, 0x2a, 0xa0, 0x02, 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, + 0xa0, 0xaa, 0xaa, 0x2a, 0x00, 0x2a, 0xa0, 0x02, 0x00, 0x2a, 0xa0, 0x02, + 0x00, 0x2a, 0xa0, 0x02, 0x00, 0x2a, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x05, 0x00, 0x80, 0x6a, 0x85, 0x0a, 0xa0, 0xea, 0x85, 0x0a, + 0xa0, 0xf4, 0xf5, 0x02, 0xe0, 0xf5, 0xf5, 0x07, 0xf0, 0xff, 0xfd, 0x15, + 0xd0, 0x2f, 0xa8, 0x15, 0x50, 0x01, 0x2a, 0x00, 0x50, 0x55, 0x2b, 0x00, + 0x40, 0xd5, 0x5f, 0x01, 0x00, 0xd5, 0x5f, 0x05, 0x00, 0xa0, 0x57, 0x15, + 0x00, 0xa0, 0x02, 0x15, 0x50, 0xa9, 0xe0, 0x1f, 0x50, 0xfd, 0xfd, 0x3f, + 0x40, 0x7f, 0x7d, 0x2d, 0x00, 0x7e, 0x7d, 0x28, 0x80, 0x4a, 0xad, 0x2a, + 0x80, 0x4a, 0xa5, 0x0a, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa0, 0x02, 0x00, + 0x00, 0xf0, 0x17, 0x00, 0x00, 0xf4, 0x55, 0x00, 0x00, 0x55, 0x54, 0x01, + 0x00, 0x15, 0x50, 0x01, 0x00, 0x15, 0x50, 0x01, 0x00, 0x55, 0x54, 0x01, + 0x00, 0x54, 0x55, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x54, 0x05, 0x00, + 0x00, 0x55, 0x15, 0x04, 0x40, 0x15, 0x15, 0x15, 0x40, 0x05, 0x54, 0x15, + 0x50, 0x01, 0x50, 0x05, 0x50, 0x01, 0x50, 0x01, 0x50, 0x05, 0x54, 0x05, + 0x40, 0x55, 0x55, 0x15, 0x40, 0x55, 0x15, 0x15, 0x00, 0x54, 0x01, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x40, 0x01, 0x80, 0x2a, 0x50, 0x05, 0x80, 0x2a, 0x50, 0x05, + 0x00, 0xaa, 0x54, 0x01, 0x00, 0xa8, 0x54, 0x00, 0x00, 0xa8, 0x57, 0x00, + 0x00, 0xa0, 0x17, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xd0, 0x2f, 0x00, 0x00, 0x50, 0x2b, 0x00, + 0x00, 0x50, 0x2b, 0x00, 0x00, 0x50, 0x2b, 0x00, 0x00, 0x50, 0x2b, 0x00, + 0x00, 0x50, 0x2b, 0x00, 0x00, 0x50, 0x2b, 0x00, 0x00, 0xd0, 0x2f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xe0, 0x1f, 0x00, + 0x00, 0xa0, 0x17, 0x00, 0x00, 0xa8, 0x57, 0x00, 0x00, 0xa8, 0x54, 0x00, + 0x00, 0xaa, 0x54, 0x01, 0x80, 0x2a, 0x50, 0x05, 0x80, 0x2a, 0x50, 0x05, + 0x00, 0x0a, 0x40, 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, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x40, 0xc1, 0x0f, 0x05, 0x50, 0xc5, 0x4f, 0x15, 0x40, 0xd5, 0x5f, 0x05, + 0xa0, 0xff, 0xff, 0x2b, 0xa0, 0xfe, 0xff, 0x2a, 0xa0, 0xff, 0xff, 0x2b, + 0x40, 0xd5, 0x5f, 0x05, 0x50, 0xc5, 0x4f, 0x15, 0x40, 0xc1, 0x0f, 0x05, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0xaa, 0x2a, + 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x01, 0x00, 0x00, 0x54, 0x05, 0x00, 0x00, 0x54, 0x05, 0x00, + 0x00, 0x54, 0x05, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x40, 0x05, 0x00, + 0x00, 0x50, 0x01, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x80, 0x0a, + 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, + 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x2a, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x80, 0x0a, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa8, 0x00, 0x00, + 0x00, 0xa8, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x7a, 0x01, 0x00, + 0x80, 0x5e, 0x05, 0x00, 0x80, 0x5e, 0x05, 0x00, 0xa0, 0x56, 0x05, 0x00, + 0xa0, 0x52, 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, 0xd0, 0x1f, 0x00, + 0x00, 0xf5, 0x5f, 0x01, 0x40, 0xfd, 0x5f, 0x05, 0x40, 0xaf, 0x5e, 0x05, + 0xd0, 0xab, 0x1e, 0x15, 0xf0, 0x8b, 0x1f, 0x15, 0xf0, 0x83, 0x1f, 0x15, + 0x50, 0x81, 0x0f, 0x15, 0x50, 0x81, 0x0f, 0x15, 0x50, 0x81, 0x0f, 0x15, + 0x50, 0xc1, 0x0f, 0x15, 0x50, 0xc1, 0x0f, 0x15, 0x50, 0xc1, 0x0b, 0x15, + 0x50, 0xc1, 0x0b, 0x15, 0x50, 0xc1, 0x0b, 0x15, 0x50, 0xd1, 0x0b, 0x15, + 0x50, 0xd1, 0x0b, 0x15, 0x50, 0xd1, 0x0a, 0x15, 0x40, 0xd5, 0x4a, 0x05, + 0xe0, 0xff, 0xff, 0x2f, 0xa0, 0xff, 0xff, 0x2b, 0xa0, 0xfa, 0xbf, 0x2a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0xc0, 0x0f, 0x00, 0xa0, 0xfa, 0x0f, 0x00, 0xa0, 0xff, 0x03, + 0x00, 0xe0, 0xff, 0x0a, 0x00, 0x54, 0x85, 0x0a, 0x00, 0x55, 0x01, 0x2a, + 0x40, 0x15, 0x00, 0x2a, 0x40, 0x05, 0x00, 0x2a, 0xf0, 0x07, 0x00, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0xd0, 0x0b, 0x80, 0x0a, 0xd0, 0xff, 0xff, 0x1f, + 0x50, 0xff, 0xff, 0x17, 0x50, 0xf5, 0x7f, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0xea, 0xaf, 0x0a, 0xa0, 0xea, 0xaf, 0x0a, 0xa0, 0xfa, 0xab, 0x0a, + 0xa0, 0x52, 0x01, 0x00, 0xa0, 0x52, 0x01, 0x00, 0xa0, 0x56, 0x00, 0x00, + 0xa0, 0x56, 0x00, 0x00, 0xa0, 0x56, 0x00, 0x00, 0xa0, 0xb7, 0x2a, 0x00, + 0xa0, 0xbf, 0xfe, 0x02, 0xa0, 0xbf, 0xfe, 0x0a, 0xe0, 0x07, 0xd4, 0x0a, + 0x40, 0x05, 0x54, 0x2a, 0x40, 0x05, 0x54, 0x2a, 0x50, 0x55, 0x55, 0x3f, + 0x50, 0x55, 0x55, 0x3f, 0xf0, 0x57, 0x55, 0x3f, 0xa0, 0x02, 0x54, 0x2a, + 0x80, 0x0a, 0xd4, 0x0a, 0x80, 0xaa, 0xfe, 0x0a, 0x00, 0xaa, 0xfe, 0x02, + 0x00, 0xa0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xfa, 0xbf, 0x2a, + 0xa0, 0xff, 0xff, 0x2b, 0xe0, 0xff, 0xff, 0x2f, 0x40, 0x05, 0x40, 0x2f, + 0x50, 0x01, 0x80, 0x1f, 0x50, 0x01, 0x80, 0x1f, 0x50, 0x01, 0x80, 0x0a, + 0x50, 0x01, 0xa0, 0x02, 0x50, 0x51, 0xb5, 0x02, 0x50, 0x55, 0xf5, 0x03, + 0x50, 0x55, 0xfd, 0x05, 0x50, 0x05, 0xe8, 0x05, 0x50, 0x01, 0xa8, 0x15, + 0x50, 0x01, 0x2a, 0x15, 0x50, 0x01, 0x2a, 0x15, 0x50, 0x01, 0x2a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x40, 0x85, 0x4a, 0x05, + 0x40, 0xf5, 0x57, 0x05, 0x00, 0xf5, 0x57, 0x01, 0x00, 0xf0, 0x17, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xe0, 0x07, 0x40, 0x2f, 0xe0, 0x57, 0x55, 0x2f, 0x80, 0x5f, 0xd5, 0x2b, + 0xc0, 0xff, 0xff, 0x2f, 0x40, 0xaf, 0xea, 0x2f, 0x50, 0xa1, 0x2a, 0x3f, + 0x50, 0x01, 0x00, 0x3f, 0x50, 0x01, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0xff, 0xff, 0x0f, + 0x00, 0xff, 0xff, 0x03, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x54, 0x05, 0x00, + 0x00, 0x54, 0x05, 0x00, 0x00, 0xf4, 0x07, 0x00, 0x00, 0xf8, 0x0b, 0x00, + 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa0, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, + 0x00, 0x54, 0x05, 0x00, 0x00, 0x54, 0x05, 0x00, 0x00, 0xf4, 0x07, 0x00, + 0x00, 0xf8, 0x0b, 0x00, 0x00, 0xa8, 0x0a, 0x00, 0x00, 0xa8, 0x0a, 0x00, + 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0xa0, 0x02, 0x00, + 0x00, 0xa8, 0x02, 0x00, 0x00, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x50, 0x15, + 0xa0, 0xaa, 0xff, 0x2f, 0xa0, 0xfa, 0xff, 0x2a, 0xa0, 0xff, 0xaf, 0x2a, + 0x50, 0x55, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x50, 0x55, 0x00, 0x00, + 0xa0, 0xff, 0xaf, 0x2a, 0xa0, 0xfa, 0xff, 0x2a, 0xa0, 0xaa, 0xff, 0x2f, + 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x2a, 0x00, 0x00, 0xaa, 0xaa, 0x02, + 0x80, 0xaa, 0xaa, 0x0a, 0x80, 0x0a, 0x80, 0x0a, 0xa0, 0x02, 0x00, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0x50, 0x15, 0x00, 0x2a, 0x40, 0x55, 0x81, 0x0a, + 0x00, 0x54, 0xb5, 0x0a, 0x00, 0x40, 0xfd, 0x03, 0x00, 0x00, 0xfe, 0x15, + 0x00, 0x00, 0x6a, 0x15, 0x00, 0x80, 0x5e, 0x15, 0x00, 0xc0, 0x5f, 0x01, + 0x00, 0xd4, 0x1f, 0x00, 0x40, 0x55, 0x01, 0x00, 0x50, 0x15, 0x00, 0x00, + 0x50, 0x81, 0x0a, 0x00, 0x00, 0xa0, 0x2a, 0x00, 0x00, 0xa0, 0x2a, 0x00, + 0x00, 0xa0, 0x2a, 0x00, 0x00, 0x80, 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, 0xa0, 0x2a, 0x00, 0x00, 0xaa, 0xaa, 0x02, 0x80, 0xea, 0xbf, 0x0a, + 0x80, 0x5e, 0xd5, 0x0b, 0xa0, 0x57, 0x55, 0x2f, 0xe0, 0x17, 0x40, 0x2f, + 0xe0, 0x07, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3e, 0xf0, 0x43, 0x55, 0x3e, + 0xf0, 0xfa, 0xff, 0x3e, 0xf0, 0xfa, 0xfa, 0x3e, 0xf0, 0xfa, 0xfa, 0x3e, + 0xf0, 0x52, 0x55, 0x3f, 0xf0, 0x43, 0x45, 0x2f, 0xf0, 0x03, 0x00, 0x2a, + 0xe0, 0x07, 0x00, 0x3e, 0xe0, 0x17, 0x00, 0x3f, 0xa0, 0x57, 0x55, 0x2f, + 0xa0, 0x56, 0x55, 0x2b, 0xa0, 0x42, 0x15, 0x2a, 0xa0, 0x02, 0x00, 0x2a, + 0xa0, 0x02, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf5, 0x3f, 0x00, + 0x50, 0xff, 0xff, 0x03, 0xd0, 0xff, 0xff, 0x0f, 0xd0, 0x0b, 0xc0, 0x0f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x40, 0x05, 0xf0, 0x57, 0x55, 0x05, + 0xf0, 0x57, 0x55, 0x01, 0xf0, 0x57, 0x55, 0x05, 0xf0, 0x03, 0x40, 0x05, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xd0, 0x0b, 0xc0, 0x0f, + 0xd0, 0xff, 0xff, 0x0f, 0x50, 0xff, 0xff, 0x03, 0x50, 0xf5, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xbf, 0x2a, 0xf0, 0xff, 0xff, 0x2b, + 0xf0, 0xff, 0xff, 0x2f, 0xf0, 0x03, 0x40, 0x05, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0xab, 0x2a, 0x15, 0xf0, 0xab, 0x2a, 0x15, + 0xf0, 0xab, 0x2a, 0x15, 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x40, 0x05, 0xf0, 0xff, 0xff, 0x2f, + 0xf0, 0xff, 0xff, 0x2b, 0xf0, 0xff, 0xbf, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0xf5, 0x7f, 0x15, 0x50, 0xff, 0xff, 0x17, 0xd0, 0xff, 0xff, 0x1f, + 0xd0, 0x0b, 0x80, 0x0a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0x57, 0x15, 0x00, 0xf0, 0x57, 0x15, 0x00, 0xf0, 0x57, 0x15, 0x00, + 0xf0, 0x03, 0xa0, 0x2a, 0xf0, 0x03, 0xa0, 0x2a, 0xf0, 0x03, 0xa0, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, + 0xd0, 0x0b, 0x80, 0x2a, 0xd0, 0xab, 0xaa, 0x2a, 0x50, 0xab, 0xaa, 0x2a, + 0x50, 0xa1, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xab, 0xaa, 0x1f, + 0xd0, 0xab, 0xaa, 0x1f, 0xd0, 0xab, 0xaa, 0x1f, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x50, 0xd5, 0x5f, 0x15, + 0x50, 0xd5, 0x5f, 0x15, 0x50, 0xd5, 0x5f, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0xd0, 0xab, 0xaa, 0x1f, 0xd0, 0xab, 0xaa, 0x1f, 0xd0, 0xab, 0xaa, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x3f, 0xa0, 0x02, 0x80, 0x3f, + 0xa0, 0x02, 0xa0, 0x1f, 0xa0, 0x02, 0xa8, 0x17, 0xa0, 0x02, 0xaa, 0x15, + 0xa0, 0x82, 0x2a, 0x15, 0xa0, 0xa2, 0x0a, 0x15, 0xa0, 0xaa, 0x02, 0x15, + 0xa0, 0xaa, 0x00, 0x15, 0xa0, 0x2a, 0x00, 0x15, 0xa0, 0x0a, 0x00, 0x15, + 0xa0, 0x0a, 0x00, 0x15, 0xa0, 0x2a, 0x00, 0x15, 0xa0, 0xaa, 0x00, 0x15, + 0xf0, 0xab, 0x02, 0x15, 0xf0, 0xa3, 0x0a, 0x15, 0xf0, 0x83, 0x2a, 0x15, + 0xf0, 0x03, 0xaa, 0x15, 0xe0, 0x07, 0xe8, 0x07, 0xe0, 0x57, 0xf5, 0x0f, + 0xa0, 0x57, 0xd5, 0x2b, 0xa0, 0x52, 0x15, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x0b, 0x80, 0x2a, + 0xf0, 0x0b, 0x80, 0x2a, 0xf0, 0x2b, 0xa0, 0x2a, 0xf0, 0x2b, 0xa0, 0x2a, + 0xf0, 0xab, 0xa8, 0x2a, 0xf0, 0xab, 0xa8, 0x2a, 0xf0, 0xa3, 0x2a, 0x2a, + 0xf0, 0xa3, 0x2a, 0x2a, 0xf0, 0x83, 0x0a, 0x2a, 0xf0, 0x83, 0x0a, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x57, 0x55, 0x3f, 0xf0, 0x57, 0x55, 0x3f, + 0xf0, 0x57, 0x55, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0x2a, 0x15, + 0x50, 0xab, 0xaa, 0x17, 0xd0, 0xaf, 0xaa, 0x1f, 0xd0, 0x0f, 0x80, 0x1f, + 0xf0, 0x17, 0x00, 0x3f, 0xf0, 0x17, 0x00, 0x3f, 0xf0, 0x57, 0x00, 0x3f, + 0xf0, 0x57, 0x00, 0x3f, 0xf0, 0x53, 0x01, 0x3f, 0xf0, 0x53, 0x01, 0x3f, + 0xf0, 0x43, 0x05, 0x3f, 0xf0, 0x43, 0x05, 0x3f, 0xf0, 0x03, 0x15, 0x3f, + 0xf0, 0x03, 0x15, 0x3f, 0xf0, 0x03, 0x54, 0x3f, 0xf0, 0x03, 0x54, 0x3f, + 0xf0, 0x03, 0x50, 0x3f, 0xf0, 0x03, 0x50, 0x3f, 0xd0, 0x0b, 0xc0, 0x1f, + 0xd0, 0xab, 0xea, 0x1f, 0x50, 0xab, 0xaa, 0x17, 0x50, 0xa1, 0x2a, 0x15, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0xf5, 0x3f, 0x00, 0x50, 0xff, 0xff, 0x03, + 0xd0, 0xff, 0xff, 0x0f, 0xd0, 0x0b, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x40, 0x2f, 0xf0, 0x57, 0x55, 0x2f, 0xf0, 0x57, 0x55, 0x2b, + 0xf0, 0x57, 0x15, 0x2a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, + 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x03, 0x00, 0x2a, 0xf0, 0x83, 0x0a, 0x2a, + 0xf0, 0x83, 0x0a, 0x2a, 0xd0, 0x8b, 0x8a, 0x0a, 0xd0, 0xab, 0xaa, 0x0a, + 0x50, 0xab, 0xaa, 0x02, 0x50, 0xa1, 0xaa, 0x00, 0x00, 0x00, 0xa8, 0x02, + 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0xf5, 0x3f, 0x00, 0x50, 0xff, 0xff, 0x03, 0xd0, 0xff, 0xff, 0x0f, + 0xd0, 0x0b, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x15, 0xd0, 0x0b, 0x00, 0x15, 0xd0, 0x2b, 0x40, 0x05, + 0x50, 0xff, 0x57, 0x05, 0x50, 0xfd, 0x5f, 0x01, 0x50, 0xd5, 0xff, 0x00, + 0x50, 0x01, 0xfe, 0x03, 0x50, 0x01, 0xf0, 0x0f, 0x50, 0x01, 0xc0, 0x0f, + 0x50, 0x01, 0x40, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xd0, 0x0b, 0x80, 0x1f, 0xd0, 0xab, 0xaa, 0x1f, 0x50, 0xab, 0xaa, 0x17, + 0x50, 0xa1, 0x2a, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x57, 0x55, 0x3f, + 0xf0, 0x57, 0x55, 0x3f, 0xf0, 0x57, 0x55, 0x3f, 0xa0, 0x42, 0x05, 0x2a, + 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, + 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, + 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, + 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, + 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, 0x80, 0x4a, 0x85, 0x0a, + 0x80, 0xea, 0xaf, 0x0a, 0x00, 0xea, 0xaf, 0x02, 0x00, 0xe0, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xe0, 0x07, 0x40, 0x2f, 0xe0, 0x07, 0x40, 0x2f, + 0xe0, 0x07, 0x40, 0x2f, 0xe0, 0x07, 0x40, 0x2f, 0xa0, 0x17, 0x50, 0x2b, + 0xa0, 0x17, 0x50, 0x2b, 0xa0, 0x97, 0x5a, 0x2b, 0xa0, 0x97, 0x5a, 0x2b, + 0xa0, 0xf6, 0x7e, 0x2a, 0xa0, 0xf6, 0x7e, 0x2a, 0xa0, 0xfe, 0xfe, 0x2a, + 0xa0, 0xfe, 0xfc, 0x2a, 0xa0, 0xfa, 0xbd, 0x2a, 0xa0, 0x7a, 0xb5, 0x2a, + 0xa0, 0x7a, 0xb5, 0x2a, 0xa0, 0x5a, 0x95, 0x2a, 0xa0, 0x4a, 0x85, 0x2a, + 0xa0, 0x42, 0x05, 0x2a, 0xa0, 0x42, 0x05, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x0f, 0xc0, 0x3f, + 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0x3f, 0xf0, 0x0f, 0x00, 0x3f, 0xf0, 0x03, + 0x00, 0xff, 0xfc, 0x03, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0xff, 0x00, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xd0, 0x1f, 0x00, + 0x00, 0xd0, 0x1f, 0x00, 0x00, 0xd4, 0x5f, 0x00, 0x00, 0xd4, 0x5e, 0x00, + 0x00, 0xd5, 0x5e, 0x01, 0x00, 0x95, 0x5a, 0x01, 0x40, 0x95, 0x5a, 0x05, + 0x40, 0x85, 0x4a, 0x05, 0x50, 0x85, 0x4a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x0a, + 0x00, 0xa8, 0xaa, 0x0a, 0x00, 0xa8, 0xaa, 0x0a, 0x50, 0xfd, 0x55, 0x05, + 0x50, 0xfd, 0x55, 0x05, 0x50, 0xfd, 0x55, 0x05, 0x00, 0xa8, 0x50, 0x01, + 0x00, 0xa8, 0x50, 0x01, 0x00, 0xa8, 0x54, 0x00, 0x00, 0xa8, 0x54, 0x00, + 0x00, 0xa8, 0x15, 0x00, 0x00, 0xa8, 0x15, 0x00, 0x00, 0xe8, 0x05, 0x00, + 0x00, 0xe8, 0x05, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf8, 0x01, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, + 0x00, 0xbd, 0x00, 0x00, 0x40, 0xad, 0x00, 0x00, 0x40, 0xad, 0x00, 0x00, + 0x50, 0xfd, 0x55, 0x05, 0x50, 0xfd, 0x55, 0x05, 0x50, 0xfd, 0x55, 0x05, + 0x00, 0xa8, 0xaa, 0x0a, 0x00, 0xa8, 0xaa, 0x0a, 0x00, 0xa8, 0xaa, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0x00, 0x80, 0xaa, 0xaa, 0x00, + 0x80, 0xaa, 0xaa, 0x00, 0x50, 0x01, 0xa8, 0x00, 0x50, 0x01, 0xa8, 0x00, + 0x40, 0x05, 0xa8, 0x00, 0x40, 0x05, 0xa8, 0x00, 0x00, 0x15, 0xa8, 0x00, + 0x00, 0x15, 0xa8, 0x00, 0x00, 0x54, 0xa8, 0x00, 0x00, 0x54, 0xa8, 0x00, + 0x00, 0x50, 0xa9, 0x00, 0x00, 0x50, 0xa9, 0x00, 0x00, 0x40, 0xad, 0x00, + 0x00, 0x40, 0xad, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xbd, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x01, + 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xe8, 0x05, 0x00, 0x00, 0xe8, 0x05, + 0x00, 0x00, 0xa8, 0x15, 0x00, 0x00, 0xa8, 0x15, 0x80, 0xaa, 0xaa, 0x00, + 0x80, 0xaa, 0xaa, 0x00, 0x80, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x40, 0x05, 0x00, + 0x00, 0x50, 0x15, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x54, 0x54, 0x00, + 0x00, 0x54, 0x54, 0x00, 0x00, 0x15, 0x50, 0x01, 0x00, 0x15, 0x50, 0x01, + 0x40, 0x05, 0x40, 0x05, 0x40, 0x05, 0x40, 0x05, 0x50, 0x01, 0x00, 0x15, + 0x50, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0xf5, 0xaa, 0x00, 0x00, 0xff, 0xab, 0x0a, + 0x80, 0xfe, 0xaf, 0x2a, 0x80, 0x52, 0x95, 0x2a, 0x00, 0x40, 0x55, 0x2a, + 0x00, 0xa8, 0x7f, 0x2a, 0x80, 0xaa, 0xbe, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, + 0xa0, 0x02, 0x00, 0x2a, 0xa0, 0x00, 0x00, 0x2a, 0xa0, 0x02, 0x80, 0x2a, + 0xa0, 0xaa, 0xaa, 0x2a, 0x80, 0xaa, 0xaa, 0x2a, 0x00, 0xa8, 0x2a, 0x2a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0xf1, 0x3f, 0x00, 0x50, 0xff, 0xff, 0x03, 0xd0, 0xff, 0xff, 0x0f, + 0xd0, 0x0f, 0xc0, 0x2f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0x03, 0x00, 0x3f, 0xd0, 0x0f, 0xc0, 0x2f, 0xd0, 0xff, 0xff, 0x0f, + 0x50, 0xff, 0xff, 0x03, 0x50, 0xf1, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0xf0, 0x3f, 0x15, + 0x00, 0xff, 0xff, 0x17, 0xc0, 0xff, 0xff, 0x1f, 0xc0, 0x0f, 0xc0, 0x1f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0xab, 0xaa, 0x3f, 0xf0, 0xab, 0xaa, 0x3f, + 0xf0, 0xab, 0xaa, 0x3f, 0xf0, 0x03, 0x00, 0x15, 0xf0, 0x03, 0x00, 0x15, + 0xc0, 0x0f, 0x40, 0x3f, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x1f, + 0x00, 0xf0, 0xbf, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x15, + 0x00, 0x00, 0x55, 0x15, 0x00, 0x40, 0x55, 0x15, 0x00, 0x40, 0x05, 0x00, + 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, + 0x00, 0x50, 0x01, 0x00, 0x50, 0xf5, 0x7f, 0x3f, 0x50, 0xff, 0xff, 0x3f, + 0xd0, 0xff, 0xff, 0x3f, 0x80, 0x5a, 0x81, 0x2a, 0xa0, 0x52, 0x01, 0x2a, + 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, + 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, 0x80, 0x5a, 0x81, 0x2a, + 0x80, 0xfa, 0xab, 0x2a, 0x00, 0xfa, 0xab, 0x2a, 0x00, 0xf0, 0x2b, 0x2a, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0xaa, 0xaa, 0x0a, + 0x00, 0xaa, 0xaa, 0x02, 0x00, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0x81, 0x02, 0x00, 0x50, 0xa1, 0x0a, 0x00, 0x50, 0xa1, 0x0a, 0x00, + 0x50, 0x81, 0x02, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0xfb, 0x1f, 0x00, 0x50, 0xff, 0x5f, 0x01, 0x50, 0xff, 0x5f, 0x05, + 0x50, 0x85, 0x4a, 0x05, 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0xd0, 0xab, 0xaa, 0x1f, + 0xd0, 0xab, 0xaa, 0x1f, 0xd0, 0xab, 0xaa, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x05, 0x00, + 0xa0, 0x42, 0x15, 0x00, 0xa0, 0x42, 0x15, 0x00, 0xa0, 0x02, 0x05, 0x00, + 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x56, 0x15, 0x2a, + 0xa0, 0x56, 0x95, 0x2a, 0xa0, 0x56, 0xb5, 0x0a, 0xa0, 0x02, 0xbd, 0x02, + 0xa0, 0x02, 0xbf, 0x00, 0xa0, 0xaa, 0x3f, 0x00, 0xa0, 0xaa, 0x1f, 0x00, + 0xa0, 0xaa, 0x1f, 0x00, 0xa0, 0xaa, 0x3f, 0x00, 0xa0, 0x02, 0xbf, 0x00, + 0xa0, 0x02, 0xbd, 0x02, 0xa0, 0x02, 0xb5, 0x0a, 0xa0, 0x02, 0x95, 0x2a, + 0xa0, 0x02, 0x15, 0x2a, 0x00, 0x00, 0x15, 0x00, 0x00, 0x40, 0x05, 0x00, + 0x50, 0x55, 0x05, 0x00, 0x50, 0x55, 0x01, 0x00, 0x50, 0x15, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x05, 0x00, + 0x00, 0x55, 0x05, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x40, 0x05, 0x00, + 0x00, 0x40, 0x05, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x40, 0x05, 0x00, + 0x00, 0x40, 0x05, 0x00, 0xa0, 0xe2, 0xa7, 0x02, 0xa0, 0xea, 0xaf, 0x0a, + 0xa0, 0xea, 0xaf, 0x0a, 0xa0, 0xca, 0x2f, 0x2a, 0xa0, 0xc2, 0x0f, 0x2a, + 0xa0, 0xc2, 0x0f, 0x2a, 0xa0, 0xc2, 0x0f, 0x2a, 0xa0, 0xc2, 0x0f, 0x2a, + 0xa0, 0xc2, 0x0f, 0x2a, 0xa0, 0xc2, 0x0f, 0x2a, 0xa0, 0xc2, 0x0f, 0x2a, + 0xe0, 0xd7, 0x5f, 0x2f, 0xe0, 0xd7, 0x5f, 0x2f, 0xe0, 0xd7, 0x5f, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0xf1, 0x3f, 0x00, 0x50, 0xff, 0xff, 0x03, 0xd0, 0xff, 0xff, 0x0f, + 0xd0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xd0, 0x0b, 0x80, 0x1f, 0xd0, 0xab, 0xaa, 0x1f, + 0x50, 0xab, 0xaa, 0x17, 0x50, 0xa1, 0x2a, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0x3f, 0x2a, + 0x50, 0xff, 0xff, 0x2b, 0xd0, 0xff, 0xff, 0x2f, 0xd0, 0x0f, 0xc0, 0x2f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xd0, 0x0f, 0xc0, 0x2f, 0xd0, 0xff, 0xff, 0x2f, 0x50, 0xff, 0xff, 0x2b, + 0x50, 0xf1, 0x3f, 0x2a, 0x50, 0x01, 0x00, 0x2a, 0x50, 0x01, 0x00, 0x2a, + 0x50, 0x01, 0x00, 0x2a, 0x50, 0x01, 0x00, 0x2a, 0x50, 0x01, 0x00, 0x2a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0xf9, 0xbf, 0x00, 0xd0, 0xff, 0xff, 0x0b, + 0xf0, 0xff, 0xff, 0x2f, 0xf0, 0x0f, 0x40, 0x3f, 0xf0, 0x03, 0x00, 0x15, + 0xf0, 0xab, 0x02, 0x00, 0xd0, 0xab, 0xaa, 0x02, 0x50, 0xab, 0xaa, 0x0a, + 0x50, 0x01, 0xaa, 0x2a, 0x50, 0x01, 0x00, 0x2a, 0xf0, 0x03, 0x80, 0x2a, + 0xf0, 0xab, 0xaa, 0x2a, 0xd0, 0xab, 0xaa, 0x0a, 0x50, 0xa9, 0xaa, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, + 0xf0, 0x57, 0x55, 0x3f, 0xf0, 0x57, 0x55, 0x3f, 0xf0, 0x57, 0x55, 0x3f, + 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, + 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, 0xa0, 0x52, 0x01, 0x2a, + 0xa0, 0x52, 0x01, 0x2a, 0x80, 0x4a, 0x85, 0x2a, 0x80, 0xea, 0xff, 0x3f, + 0x00, 0xaa, 0xff, 0x3f, 0x00, 0xa0, 0x7a, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x07, 0x40, 0x3f, 0xf0, 0x07, 0x40, 0x3f, + 0xe0, 0x17, 0x50, 0x2f, 0xe0, 0x97, 0x5a, 0x2f, 0xa0, 0xd7, 0x5e, 0x2b, + 0xa0, 0xd7, 0x5e, 0x2b, 0xa0, 0xd6, 0x5f, 0x2a, 0xa0, 0xd6, 0x5f, 0x2a, + 0xa0, 0xf2, 0x3f, 0x2a, 0xa0, 0xfa, 0xbf, 0x2a, 0x80, 0xea, 0xad, 0x0a, + 0x00, 0x6a, 0xa5, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0x00, 0x3e, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x07, 0x40, 0x3f, 0xe0, 0x17, 0x50, 0x2f, 0xa0, 0x57, 0x54, 0x2b, + 0xa0, 0x56, 0x55, 0x2a, 0xa0, 0x52, 0x15, 0x2a, 0xa0, 0x52, 0x15, 0x2a, + 0xa0, 0x56, 0x55, 0x2a, 0xa0, 0x57, 0x54, 0x2b, 0xc0, 0x1f, 0xd0, 0x2f, + 0xd0, 0xaf, 0xea, 0x3f, 0x50, 0xab, 0xaa, 0x3f, 0x50, 0xa0, 0x2a, 0x3e, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0xaa, 0xaa, 0x0a, + 0x00, 0xaa, 0xaa, 0x02, 0x00, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0xa0, 0x0a, + 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xaa, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x80, 0x2a, 0x00, + 0x50, 0xd5, 0x5f, 0x15, 0x50, 0xf5, 0x5f, 0x15, 0x50, 0xfd, 0x57, 0x15, + 0x00, 0xa8, 0x52, 0x05, 0x00, 0xa0, 0x5e, 0x01, 0x00, 0x80, 0x5f, 0x00, + 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x50, 0x2f, 0x00, 0x00, 0x54, 0x2b, 0x00, + 0x00, 0x55, 0x2a, 0x00, 0x40, 0x15, 0x2a, 0x00, 0x50, 0x55, 0x7f, 0x15, + 0x50, 0x55, 0xff, 0x15, 0x50, 0x55, 0xfd, 0x15, 0x00, 0x00, 0xa8, 0x02, + 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x4a, 0x05, 0x00, 0x80, 0x6a, 0x05, 0x00, 0x00, 0xea, 0x05, 0x00, + 0x00, 0xe8, 0x05, 0x00, 0x00, 0xe8, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, + 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, + 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x2f, 0x00, 0x00, 0x40, 0xaf, 0x00, 0x00, 0x40, 0xaf, 0x00, + 0x00, 0xc0, 0x2f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xe0, 0x0f, 0x00, + 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, + 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe8, 0x07, 0x00, + 0x00, 0xe8, 0x05, 0x00, 0x00, 0xea, 0x05, 0x00, 0x80, 0x6a, 0x05, 0x00, + 0x80, 0x4a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa8, 0x80, 0xa0, + 0x0a, 0x2a, 0xa0, 0xa0, 0x0a, 0x0a, 0xa8, 0xa0, 0x0a, 0x02, 0x2a, 0xa0, + 0x0a, 0x80, 0x0a, 0xa0, 0x0a, 0xa0, 0x02, 0xa0, 0x0a, 0xa8, 0x80, 0xa0, + 0x0a, 0x2a, 0xa0, 0xa0, 0x0a, 0x0a, 0xa8, 0xa0, 0x0a, 0x02, 0x2a, 0xa0, + 0x0a, 0x80, 0x0a, 0xa0, 0x0a, 0xf5, 0x02, 0xb4, 0x4a, 0xfd, 0x81, 0xb4, + 0x5a, 0x7f, 0xa5, 0xb5, 0x5a, 0x4b, 0xfd, 0xb5, 0x5a, 0x02, 0x7f, 0xa5, + 0x5a, 0x80, 0x5e, 0xa1, 0x0a, 0xa0, 0x02, 0xa0, 0x0a, 0xa8, 0x80, 0xa0, + 0x0a, 0x2a, 0xa0, 0xa0, 0x0a, 0x0a, 0xa8, 0xa0, 0x0a, 0x02, 0x2a, 0xa0, + 0x0a, 0x80, 0x0a, 0xa0, 0x0a, 0xa0, 0x02, 0xa0, 0x0a, 0xa8, 0x80, 0xa0, + 0x0a, 0x2a, 0xa0, 0xa0, 0x0a, 0x0a, 0xa8, 0xa0, 0x0a, 0x02, 0x2a, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x40, 0x55, 0x55, 0x05, 0x50, 0x55, + 0x00, 0x05, 0x50, 0x00, 0x00, 0x15, 0x54, 0x00, 0x00, 0x14, 0x14, 0x00, + 0x00, 0x14, 0x14, 0x00, 0x00, 0x54, 0x15, 0x00, 0x00, 0x50, 0x05, 0x00, + 0x00, 0x50, 0x05, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x50, 0x05, 0x00, + 0x00, 0x50, 0x05, 0x00, 0x00, 0x54, 0x15, 0x00, 0x00, 0x14, 0x14, 0x00, + 0x00, 0x14, 0x14, 0x00, 0x00, 0x15, 0x54, 0x00, 0x00, 0x05, 0x50, 0x00, + 0xff, 0xaf, 0xfa, 0xff, 0xff, 0xab, 0xea, 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, 0xc0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, + 0x00, 0x3f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xff, 0xaf, 0xaa, 0xaa, + 0xff, 0xab, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x02, 0x00, 0x00, + 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, + 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, + 0x00, 0x80, 0x56, 0x55, 0x00, 0x80, 0x57, 0x55, 0x00, 0x80, 0x0f, 0x00, + 0x00, 0x40, 0x0f, 0x00, 0x00, 0x40, 0x0b, 0x00, 0x00, 0x40, 0x2b, 0x00, + 0x00, 0x40, 0x29, 0x00, 0x00, 0x40, 0x29, 0x00, 0x00, 0x50, 0xa9, 0x00, + 0x00, 0x50, 0xa0, 0x00, 0x55, 0x55, 0xa0, 0xaa, 0x55, 0x15, 0x80, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 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, 0xff, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, + 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa0, 0x00, + 0x00, 0x00, 0xa0, 0xaa, 0x00, 0x00, 0x80, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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, 0x17, 0x00, 0x00, 0xff, 0x5f, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, + 0x00, 0x7a, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, + 0x00, 0xe8, 0x01, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xe0, 0x05, 0x00, + 0x00, 0xa0, 0x07, 0x00, 0x00, 0x80, 0x57, 0x55, 0x00, 0x80, 0x56, 0x55, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa0, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xff, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x54, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40, 0x05, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0xff, 0xaf, 0xaa, 0xaa, 0xff, 0xab, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x55, 0x15, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x05, 0x00, 0xaa, 0x2a, 0x55, 0x55, + 0xaa, 0xaa, 0x55, 0x55, 0x00, 0xe0, 0x05, 0x00, 0x00, 0xe0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00, 0xd0, 0x02, 0x00, + 0x00, 0xd0, 0x02, 0x00, 0x00, 0xd4, 0x0a, 0x00, 0x00, 0x14, 0x0a, 0x00, + 0x55, 0x15, 0xaa, 0xaa, 0x55, 0x05, 0xa8, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0x2d, 0x00, + 0x00, 0x40, 0x2f, 0x00, 0x00, 0x40, 0x0b, 0x00, 0x00, 0x40, 0x0b, 0x00, + 0x00, 0xc0, 0x0b, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xd0, 0x03, 0x00, + 0x00, 0xf0, 0x02, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xbf, 0x00, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa8, 0xaa, + 0x00, 0x00, 0xa0, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x55, 0xd5, 0x57, 0x55, 0x55, 0xd5, 0x57, 0x55, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xe0, 0x0b, 0x00, 0x00, 0xe8, 0x2b, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xe8, 0x2b, 0x00, 0x00, 0xe0, 0x0b, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xaa, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x55, 0xfd, 0xbf, 0xaa, + 0x55, 0xfd, 0xbf, 0xaa, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf0, 0x0f, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xf0, 0x0f, 0x00, + 0x00, 0xfc, 0x3f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xd5, 0xab, 0xaa, + 0x55, 0xd5, 0xab, 0xaa, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x50, 0x05, 0x00, + 0x00, 0x54, 0x15, 0x00, 0x00, 0x55, 0x55, 0x00, 0x40, 0x45, 0x51, 0x01, + 0x50, 0xe1, 0x43, 0x05, 0x54, 0xe8, 0x0b, 0x15, 0x14, 0xe8, 0x0b, 0x14, + 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00, + 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xe8, 0x0b, 0x00, + 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe8, 0x0b, 0x00, + 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe8, 0x0b, 0x00, + 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe8, 0x0b, 0x00, 0x00, 0xe8, 0x0b, 0x00, + 0x00, 0xe0, 0x03, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x2b, 0x00, + 0x00, 0xe0, 0xab, 0x02, 0x00, 0xe8, 0xab, 0x0a, 0x00, 0xe8, 0x81, 0x0a, + 0x00, 0x6a, 0x01, 0x0a, 0x00, 0x6a, 0x01, 0x00, 0x00, 0x6a, 0x01, 0x00, + 0x00, 0xe8, 0x01, 0x00, 0x00, 0xe8, 0x01, 0x00, 0x80, 0xea, 0xab, 0x00, + 0xa0, 0xea, 0xab, 0x00, 0xa0, 0xea, 0x2b, 0x00, 0x00, 0xe8, 0x01, 0x00, + 0x00, 0xe8, 0x01, 0x00, 0x00, 0xe8, 0x01, 0x00, 0x00, 0x6a, 0x01, 0x00, + 0x00, 0x6a, 0x01, 0x00, 0x80, 0x4a, 0x01, 0x00, 0x80, 0xea, 0x03, 0x2a, + 0xb4, 0xea, 0xab, 0x3e, 0xf4, 0xea, 0xab, 0x3f, 0xf0, 0x4b, 0xe9, 0x0f, + 0x40, 0x45, 0x51, 0x01, 0x00, 0x55, 0x55, 0x00, 0x00, 0x54, 0x15, 0x00, + 0x00, 0x50, 0x05, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x54, 0x2f, 0xa0, 0x42, 0x55, 0x3f, + 0xa0, 0x5a, 0xd5, 0x3f, 0x80, 0x5a, 0x81, 0x1e, 0x80, 0x7e, 0xa0, 0x0a, + 0x00, 0x7e, 0xa0, 0x02, 0x40, 0xff, 0xfd, 0x03, 0x50, 0xfd, 0xfd, 0x01, + 0xf0, 0xff, 0xff, 0x2a, 0xa0, 0xbf, 0xaa, 0x2a, 0xa0, 0xbf, 0xaa, 0x2a, + 0x40, 0xd5, 0x5f, 0x01, 0x50, 0xd5, 0x5f, 0x01, 0xf0, 0xff, 0xff, 0x2a, + 0xa0, 0xbf, 0xaa, 0x2a, 0xa0, 0xbf, 0xaa, 0x2a, 0x00, 0xd4, 0x0a, 0x00, + 0x00, 0xd4, 0x0a, 0x00, 0x00, 0xd0, 0x0b, 0x14, 0x00, 0xd0, 0x5f, 0x15, + 0x00, 0xc0, 0x5f, 0x15, 0x00, 0x80, 0x5e, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x05, 0x00, 0x00, 0xa0, 0x15, 0x00, 0x00, 0xa0, 0x55, 0x00, + 0x00, 0xa0, 0x55, 0x01, 0x00, 0xa0, 0x45, 0x05, 0x00, 0xa0, 0x05, 0x15, + 0x00, 0xa0, 0x05, 0x54, 0x02, 0xa0, 0x05, 0x50, 0x0a, 0xa0, 0x05, 0x40, + 0x2a, 0xa0, 0x05, 0x00, 0xa8, 0xa0, 0x05, 0x00, 0xa0, 0xa2, 0x05, 0x00, + 0x80, 0xaa, 0x05, 0x00, 0x55, 0xff, 0xaf, 0xaa, 0x55, 0xff, 0xaf, 0xaa, + 0x80, 0xaa, 0x05, 0x00, 0xa0, 0xa2, 0x05, 0x00, 0xa8, 0xa0, 0x05, 0x00, + 0x2a, 0xa0, 0x05, 0x00, 0x0a, 0xa0, 0x05, 0x40, 0x02, 0xa0, 0x05, 0x50, + 0x00, 0xa0, 0x05, 0x54, 0x00, 0xa0, 0x05, 0x15, 0x00, 0xa0, 0x45, 0x05, + 0x00, 0xa0, 0x55, 0x01, 0x00, 0xa0, 0x55, 0x00, 0x00, 0xa0, 0x15, 0x00, + 0x00, 0xa0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x50, + 0x00, 0x50, 0x00, 0x54, 0x00, 0x50, 0x00, 0x15, 0x00, 0x50, 0x40, 0x05, + 0x00, 0x50, 0x40, 0x01, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x54, + 0x0b, 0x50, 0x00, 0x15, 0x2f, 0x50, 0x40, 0x05, 0xbd, 0x50, 0x40, 0x01, + 0xf4, 0x52, 0x00, 0x00, 0xd0, 0x5b, 0x00, 0x00, 0x40, 0x7f, 0x00, 0x00, + 0x00, 0xfd, 0xff, 0xff, 0x00, 0xfd, 0xff, 0xff, 0x40, 0x7f, 0x00, 0x00, + 0xd0, 0x5b, 0x00, 0x00, 0xf4, 0x52, 0x00, 0x00, 0xbd, 0x50, 0x00, 0x00, + 0x2f, 0x50, 0x00, 0x00, 0x0b, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, + 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, + 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x50, + 0x00, 0x0a, 0xa0, 0x54, 0x00, 0x0a, 0xa0, 0x15, 0x00, 0x0a, 0xe0, 0x05, + 0x00, 0x0a, 0xf0, 0x01, 0x00, 0x0a, 0xf4, 0x00, 0xff, 0x5f, 0xb5, 0xaa, + 0xff, 0x5f, 0xb5, 0xaa, 0x00, 0x0a, 0xf4, 0x00, 0x00, 0x0a, 0xf0, 0x01, + 0x00, 0x0a, 0xe0, 0x05, 0x00, 0x0a, 0xa0, 0x15, 0x00, 0x0a, 0xa0, 0x54, + 0x00, 0x0a, 0xa0, 0x50, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, + 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, + 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0xaa, 0xaa, 0xfa, 0xff, 0xaa, 0xaa, 0xfa, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xfa, 0xff, 0xaa, 0xaa, 0xfa, 0xff, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x5f, 0x05, 0x00, 0x00, 0x5f, 0x05, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a, 0x00, 0x00, 0x00, + 0x5f, 0x05, 0x00, 0x00, 0x5f, 0x05, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0a, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x54, 0x15, 0x00, + 0x00, 0x95, 0x5e, 0x00, 0x00, 0x85, 0x5a, 0x00, 0x00, 0x85, 0x5a, 0x00, + 0x00, 0x95, 0x5e, 0x00, 0x00, 0xd4, 0x1f, 0x00, 0xa0, 0xfa, 0xaf, 0x2a, + 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, 0x00, 0x80, 0x0a, 0x00, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x80, 0x0a, 0x00, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 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, 0xc0, 0xff, 0x03, 0x00, 0xc0, 0xc3, 0x03, 0x00, + 0x00, 0xc0, 0x03, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xfc, 0x02, 0x00, + 0x00, 0x95, 0x02, 0x00, 0xc0, 0x87, 0x02, 0x00, 0xc0, 0xff, 0x03, 0x00, + 0x40, 0xff, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x50, 0xa0, 0x02, 0x00, 0x7a, 0xa0, 0x02, 0x00, 0x7a, + 0xf5, 0x57, 0x55, 0x7f, 0xf5, 0x57, 0x55, 0x7f, 0xa0, 0x02, 0x00, 0x7a, + 0xa0, 0x02, 0x00, 0x7a, 0xa0, 0x02, 0x00, 0x7a, 0xa0, 0x02, 0x00, 0x7a, + 0xa0, 0x02, 0x00, 0x7a, 0xa0, 0x02, 0x00, 0x7a, 0xa0, 0x0a, 0x80, 0x2a, + 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xaa, 0xaa, 0x2a, 0xa0, 0xa2, 0x2a, 0x2a, + 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, + 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x40, 0x55, 0x00, + 0x00, 0x40, 0x55, 0x05, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x54, + 0x40, 0x55, 0x01, 0x50, 0x54, 0x55, 0x15, 0x54, 0x55, 0x00, 0x55, 0x15, + 0x05, 0x00, 0x50, 0x15, 0xd5, 0x0a, 0xfd, 0x1f, 0xf4, 0xff, 0xbf, 0xfe, + 0xe8, 0xfd, 0x0b, 0xf8, 0x28, 0xa0, 0x02, 0xf0, 0x6a, 0xf5, 0x03, 0xf0, + 0x5e, 0xfd, 0x1f, 0xfc, 0x5f, 0x28, 0x5f, 0x3d, 0x0f, 0x2a, 0x7a, 0x3f, + 0x5f, 0x0a, 0x7d, 0x1f, 0x54, 0x5f, 0x3d, 0x5e, 0x40, 0x5f, 0x29, 0x5a, + 0x00, 0x0a, 0x28, 0x5a, 0x40, 0x7f, 0x2b, 0x7a, 0x54, 0x7d, 0x1f, 0x7c, + 0x55, 0xa8, 0x5f, 0xbd, 0x05, 0xa0, 0x52, 0xb5, 0x55, 0x00, 0x55, 0x15, + 0x54, 0x55, 0x15, 0x54, 0x40, 0x55, 0x01, 0x50, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x40, 0x15, 0x00, 0x40, 0x55, 0x05, 0x00, 0x40, 0x55, 0x00, + 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x80, 0x2a, 0x00, 0x00, 0x80, 0x2a, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, + 0x54, 0x2d, 0x54, 0x00, 0x55, 0x7d, 0x55, 0x01, 0x85, 0xfe, 0x47, 0x05, + 0x81, 0xfa, 0x03, 0x05, 0x01, 0x50, 0x01, 0x15, 0x05, 0x54, 0x05, 0x14, + 0x05, 0x14, 0x05, 0x14, 0x15, 0x15, 0x15, 0x54, 0x14, 0x05, 0x14, 0x54, + 0x14, 0x05, 0x14, 0x00, 0x14, 0x05, 0x14, 0x00, 0x14, 0x05, 0x14, 0x00, + 0x15, 0x15, 0x15, 0x00, 0x05, 0x14, 0x05, 0x00, 0x05, 0x54, 0x05, 0x00, + 0x01, 0x50, 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, 0x50, 0x0a, 0x00, 0x00, 0x54, 0x2a, 0x00, 0x00, 0x15, 0xa8, 0x00, + 0x40, 0x05, 0xa0, 0x02, 0x50, 0x01, 0x80, 0x0a, 0x54, 0x00, 0x00, 0x2a, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x2a, + 0x50, 0x01, 0x80, 0x0a, 0x40, 0x05, 0xa0, 0x02, 0x00, 0x15, 0xa8, 0x00, + 0x00, 0x54, 0x2a, 0x00, 0x00, 0x50, 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, 0x40, 0x05, 0x00, + 0x00, 0x40, 0x55, 0x01, 0x00, 0x00, 0x50, 0x55, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x00, 0x50, 0x55, 0x00, 0x50, 0x55, 0x01, 0x40, 0x55, 0x05, 0x00, + 0x55, 0x05, 0x00, 0x00, 0xb5, 0x02, 0x00, 0x2a, 0xf5, 0x07, 0x00, 0x2a, + 0xe0, 0x57, 0x05, 0x2a, 0x28, 0x5a, 0xd5, 0xa3, 0x28, 0x0a, 0xd0, 0xf7, + 0x28, 0x0a, 0x80, 0xf6, 0x0a, 0x28, 0xf0, 0xd5, 0x0a, 0x78, 0xf5, 0x81, + 0x4a, 0x7d, 0xa5, 0x80, 0x55, 0x2d, 0xa0, 0x80, 0x15, 0xa0, 0x28, 0x00, + 0x55, 0xa5, 0x28, 0x00, 0x40, 0xf5, 0x2d, 0x00, 0x00, 0xd0, 0x5f, 0x01, + 0x00, 0x80, 0x5a, 0x55, 0x00, 0x80, 0x0a, 0x54, 0x00, 0x00, 0x50, 0x55, + 0x00, 0x50, 0x55, 0x01, 0x40, 0x55, 0x05, 0x00, 0x55, 0x05, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x40, 0x55, 0x01, 0x00, + 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0xa0, 0x2a, 0x00, 0x00, 0xa0, 0x2a, 0x00, + 0x00, 0xf0, 0x2b, 0x00, 0x00, 0xd0, 0x0b, 0x00, 0x00, 0x50, 0x01, 0x00, + 0x00, 0x14, 0x05, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x00, 0x94, 0x0f, 0x00, + 0x01, 0x85, 0x1e, 0x00, 0x01, 0xa5, 0x16, 0x50, 0x01, 0xad, 0x16, 0x50, + 0x01, 0xaf, 0x14, 0x50, 0xc5, 0x2b, 0x50, 0x14, 0xc5, 0x0b, 0x50, 0x14, + 0xe5, 0x03, 0x50, 0x14, 0xf4, 0x02, 0x40, 0x2f, 0xf4, 0x02, 0x40, 0x2f, + 0xd4, 0x0a, 0xc0, 0x0f, 0x80, 0xaa, 0xaa, 0x0a, 0x00, 0xaa, 0xaa, 0x02, + 0x00, 0xa0, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x00, + 0x00, 0x50, 0xa9, 0x00, 0x00, 0x40, 0x2f, 0x00, 0x00, 0x80, 0x1f, 0x00, + 0x00, 0x80, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0xfa, 0x95, 0x02, + 0x80, 0xfe, 0xd6, 0x02, 0x80, 0x97, 0xfa, 0x03, 0x80, 0x07, 0xea, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, + 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0xb4, 0x7a, 0x00, 0x00, 0x7d, 0xf4, 0x01, + 0x00, 0x7d, 0xf4, 0x01, 0x00, 0xb4, 0x7a, 0x00, 0x00, 0x80, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x15, + 0x00, 0xff, 0xff, 0x17, 0xc0, 0xff, 0xff, 0x1f, 0xc0, 0x0f, 0x95, 0x0a, + 0xf0, 0x03, 0x15, 0x2a, 0xf0, 0x03, 0x15, 0x2a, 0xf0, 0x03, 0x15, 0x00, + 0xf0, 0x03, 0x15, 0x00, 0xf0, 0x03, 0x15, 0x00, 0xf0, 0x03, 0x55, 0x05, + 0xf0, 0x03, 0x55, 0x05, 0xf0, 0x57, 0x55, 0x05, 0xf0, 0x57, 0x15, 0x00, + 0xf0, 0x57, 0x15, 0x00, 0xf0, 0x03, 0x15, 0x00, 0xf0, 0x03, 0x15, 0x00, + 0xf0, 0x03, 0x15, 0x2a, 0xf0, 0x03, 0x15, 0x2a, 0xd0, 0x0b, 0x95, 0x0a, + 0xd0, 0xab, 0xff, 0x1f, 0x50, 0xab, 0xff, 0x17, 0x50, 0xa1, 0x7f, 0x15, + 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa8, 0x00, + 0x00, 0x80, 0xaa, 0x00, 0x00, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x00, 0x00, 0x50, 0x2b, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xa0, 0x17, 0x00, 0x00, 0xa0, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x3f, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x05, 0x00, 0x00, 0x78, 0xb5, 0x00, 0x00, 0xfe, 0xfc, 0x02, + 0x00, 0xbf, 0xf8, 0x03, 0x00, 0x2d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, + 0xf0, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x00, + 0x00, 0x50, 0x2b, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xa0, 0x17, 0x00, + 0x00, 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x0f, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 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, 0x40, 0x05, 0x00, 0x00, 0x78, 0xb5, 0x00, + 0x00, 0xfe, 0xfc, 0x02, 0x00, 0xbf, 0xf8, 0x03, 0x00, 0x2d, 0xe0, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 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, 0x00, 0x00, 0xaa, 0x80, 0x02, 0x80, 0xaa, 0x82, 0x02, + 0xd0, 0xd7, 0xbf, 0x02, 0xd0, 0x57, 0xff, 0x01, 0x50, 0x55, 0x55, 0x05, + 0x50, 0x01, 0x40, 0x05, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x0b, 0x00, 0x3f, + 0xf0, 0x2b, 0x00, 0x3f, 0xf0, 0xab, 0x00, 0x3f, 0xf0, 0xab, 0x02, 0x3f, + 0xf4, 0xf7, 0x0b, 0x3f, 0xf4, 0xd7, 0x2b, 0x3f, 0xf4, 0x57, 0xab, 0x3f, + 0xf0, 0x03, 0xa8, 0x3f, 0xf0, 0x03, 0xa0, 0x3f, 0xf0, 0x03, 0x80, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x40, 0x2f, 0xf0, 0x57, 0x55, 0x2f, 0xf0, 0x57, 0x55, 0x2b, + 0xf0, 0x57, 0x15, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x00, + 0x00, 0x50, 0x2b, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xa0, 0x17, 0x00, + 0x00, 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x0f, + 0xc0, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x03, 0x00, 0xf0, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0xfa, 0x95, 0x02, + 0x80, 0xfe, 0xd6, 0x02, 0x80, 0x97, 0xfa, 0x03, 0x80, 0x07, 0xea, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, + 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0xff, 0xff, 0x0f, + 0x00, 0xff, 0xff, 0x03, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x50, 0x00, 0x00, 0x55, 0x54, 0x01, + 0x00, 0x55, 0x54, 0x01, 0x00, 0x14, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0x80, 0x57, 0x55, 0x0b, + 0xe0, 0x5f, 0xd5, 0x2f, 0xe0, 0x2f, 0xe0, 0x2f, 0xd0, 0xab, 0xa8, 0x1f, + 0x50, 0xab, 0xaa, 0x17, 0x50, 0xa9, 0xaa, 0x15, 0x50, 0xa1, 0x2a, 0x15, + 0x50, 0xa9, 0xaa, 0x15, 0x50, 0xab, 0xaa, 0x17, 0xd0, 0xab, 0xa8, 0x1f, + 0xf0, 0x2b, 0xa0, 0x3f, 0xf0, 0x0b, 0x80, 0x3f, 0xd0, 0x03, 0x00, 0x1f, + 0x40, 0x05, 0x40, 0x05, 0x40, 0x55, 0x55, 0x05, 0x00, 0x55, 0x55, 0x01, + 0x00, 0x50, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x50, 0x3f, 0x14, + 0x00, 0x55, 0x7d, 0x15, 0x40, 0x55, 0x55, 0x15, 0x40, 0x05, 0x40, 0x05, + 0xf0, 0x03, 0x50, 0x3f, 0xf0, 0x03, 0x50, 0x3f, 0xf0, 0x03, 0x54, 0x3f, + 0xf0, 0x03, 0x54, 0x3f, 0xf0, 0x03, 0x15, 0x3f, 0xf0, 0x03, 0x15, 0x3f, + 0xf0, 0x43, 0x05, 0x3f, 0xf0, 0x43, 0x05, 0x3f, 0xf0, 0x53, 0x01, 0x3f, + 0xf0, 0x53, 0x01, 0x3f, 0xf0, 0x57, 0x00, 0x3f, 0xf0, 0x57, 0x00, 0x3f, + 0xf0, 0x17, 0x00, 0x3f, 0xf0, 0x17, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x0f, + 0xd0, 0xff, 0xff, 0x0f, 0x50, 0xff, 0xff, 0x03, 0x50, 0xf0, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1e, 0x00, 0x00, 0xa0, 0x3f, 0x00, + 0x00, 0xe8, 0xad, 0x00, 0x00, 0x7a, 0xa1, 0x02, 0x00, 0x5a, 0x80, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0xff, 0xff, 0x0f, + 0x00, 0xff, 0xff, 0x03, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x14, 0x7a, 0x00, 0x00, 0xd5, 0x5e, 0x01, + 0x00, 0xf5, 0x56, 0x01, 0x00, 0xb4, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x0b, 0x80, 0x3f, 0xd0, 0x0b, 0x80, 0x1f, 0xd0, 0x2b, 0xa0, 0x1f, + 0x50, 0x2b, 0xa0, 0x17, 0x50, 0xab, 0xa8, 0x17, 0x50, 0xa9, 0xa8, 0x15, + 0x50, 0xa9, 0xaa, 0x15, 0x50, 0xa1, 0x2a, 0x15, 0x50, 0xa1, 0x2a, 0x15, + 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x40, 0x85, 0x4a, 0x05, 0x40, 0xd5, 0x5f, 0x05, 0x00, 0xd5, 0x5f, 0x01, + 0x00, 0xd0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0x0a, 0x00, + 0x50, 0xab, 0xaa, 0x00, 0xd0, 0xab, 0xaa, 0x02, 0xd0, 0x0b, 0xa0, 0x02, + 0xf0, 0x57, 0x95, 0x0a, 0xf0, 0x57, 0xd5, 0x0b, 0xf0, 0x57, 0xd5, 0x0f, + 0xf0, 0x03, 0xe0, 0x07, 0xf0, 0x83, 0xaa, 0x17, 0xf0, 0x83, 0xaa, 0x15, + 0xf0, 0x83, 0xaa, 0x17, 0xf0, 0x03, 0xa0, 0x1f, 0xf0, 0x03, 0x80, 0x1f, + 0xf0, 0x03, 0x80, 0x3f, 0xf0, 0x03, 0x40, 0x2f, 0xf0, 0x57, 0x55, 0x2f, + 0xf0, 0x57, 0x55, 0x2b, 0xf0, 0x57, 0x15, 0x2a, 0xf0, 0x03, 0x80, 0x0a, + 0xf0, 0x83, 0xaa, 0x0a, 0xf0, 0x83, 0xaa, 0x02, 0xf0, 0x83, 0x2a, 0x00, + 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, + 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x00, + 0x00, 0x50, 0xa9, 0x00, 0x00, 0x40, 0x2f, 0x00, 0x00, 0x80, 0x1f, 0x00, + 0x00, 0x80, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x3f, + 0xc0, 0x03, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0xfc, 0x3f, 0x3f, + 0xc0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x00, 0x00, 0x3f, 0xf0, 0x03, 0xc0, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xfc, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0xfa, 0x95, 0x02, + 0x80, 0xfe, 0xd6, 0x02, 0x80, 0x97, 0xfa, 0x03, 0x80, 0x07, 0xea, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, + 0x00, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x3f, 0xc0, 0x03, 0xc0, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0xfc, 0x3f, 0x3f, 0xc0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x3f, + 0xf0, 0x03, 0xc0, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xc0, 0xff, 0xff, 0x3f, + 0x00, 0xfc, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 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, 0x00, 0x00, 0x94, 0x7a, 0x00, 0x00, 0xf5, 0xf4, 0x01, + 0x00, 0xf5, 0xf4, 0x01, 0x00, 0x94, 0x7a, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xff, 0xff, 0x0f, + 0xc0, 0xff, 0xff, 0x3f, 0xc0, 0x03, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0xfc, 0x3f, 0x3f, 0xc0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x3f, 0xf0, 0x03, 0xc0, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xfc, 0x3f, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb4, 0x6a, 0x01, 0x00, 0xff, 0xfb, 0x07, 0xc0, 0xff, 0xff, 0x1f, + 0xc0, 0x5b, 0x95, 0x3f, 0xa0, 0x42, 0x05, 0x3e, 0xa0, 0x47, 0x55, 0x15, + 0xe0, 0x57, 0x55, 0x15, 0xf0, 0x57, 0x55, 0x15, 0xf0, 0x43, 0x05, 0x00, + 0xf0, 0x42, 0x05, 0x2a, 0xd0, 0x5b, 0x95, 0x3e, 0xd0, 0xff, 0xff, 0x1f, + 0x40, 0xff, 0xff, 0x17, 0x00, 0xe5, 0x6f, 0x05, 0x00, 0x00, 0xa8, 0x00, + 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x80, 0xaa, 0x00, + 0x00, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x00, 0x00, 0x50, 0x2b, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xa0, 0x17, 0x00, 0x00, 0xa0, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, + 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, + 0xc0, 0x0f, 0x00, 0x3f, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x0f, + 0x00, 0xf0, 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, 0x40, 0x05, 0x00, 0x00, 0x78, 0xb5, 0x00, 0x00, 0xfe, 0xfc, 0x02, + 0x00, 0xbf, 0xf8, 0x03, 0x00, 0x2d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x3f, + 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xf0, 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, 0x94, 0x02, 0x00, + 0x00, 0xf4, 0x02, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x6a, 0x05, 0x00, + 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x5e, 0x2d, 0x00, + 0x80, 0x3f, 0xbf, 0x00, 0xc0, 0x2f, 0xfe, 0x00, 0x40, 0x0b, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, + 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xc0, 0x0f, 0x00, + 0x00, 0xc0, 0x0f, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0xff, 0xff, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x55, 0x01, 0x15, + 0x00, 0x55, 0x55, 0x05, 0x00, 0xff, 0xd5, 0x03, 0x80, 0xaa, 0xd6, 0x03, + 0x80, 0x82, 0xff, 0x07, 0x80, 0x42, 0xef, 0x05, 0x00, 0x40, 0x41, 0x05, + 0x00, 0x00, 0x00, 0x15, 0xa0, 0xf2, 0x3f, 0x15, 0xa0, 0xff, 0xff, 0x17, + 0xe0, 0xff, 0xff, 0x1f, 0xe0, 0x0f, 0xc0, 0x1f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xe0, 0x07, 0x40, 0x2f, + 0xe0, 0x57, 0x55, 0x2f, 0xa0, 0x57, 0x55, 0x2b, 0xa0, 0x52, 0x15, 0x2a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x00, + 0x00, 0x50, 0x2b, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xa0, 0x17, 0x00, + 0x00, 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, + 0xc0, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0xff, 0xff, 0x0f, + 0x00, 0xff, 0xff, 0x03, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0xfa, 0x95, 0x02, + 0x80, 0xfe, 0xd6, 0x02, 0x80, 0x97, 0xfa, 0x03, 0x80, 0x07, 0xea, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, + 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x03, + 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x50, 0x00, 0x00, 0xd5, 0x5e, 0x01, + 0x00, 0xf5, 0x7e, 0x01, 0x00, 0xb4, 0x7a, 0x00, 0x00, 0xa0, 0x2a, 0x00, + 0x00, 0x80, 0x0a, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x55, 0x55, 0x01, + 0xe0, 0xff, 0xff, 0x2f, 0xe0, 0xaf, 0xea, 0x2f, 0xf0, 0xab, 0xaa, 0x3f, + 0x50, 0x01, 0x00, 0x15, 0x50, 0x01, 0x00, 0x15, 0x50, 0x81, 0x0a, 0x15, + 0x50, 0xa1, 0x2a, 0x15, 0x50, 0xa1, 0x2a, 0x15, 0x40, 0xa5, 0x6a, 0x05, + 0x40, 0xd5, 0x5f, 0x05, 0x00, 0x55, 0x55, 0x01, 0x00, 0x50, 0x15, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, + 0x00, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x2a, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x52, 0x15, 0x3e, 0xa0, 0x57, 0x55, 0x3f, 0xe0, 0x57, 0x55, 0x3f, + 0xe0, 0x07, 0x50, 0x2f, 0xf0, 0x03, 0x54, 0x3f, 0xf0, 0x03, 0x55, 0x3f, + 0xf0, 0x43, 0x15, 0x3f, 0xf0, 0x53, 0x05, 0x3f, 0xf0, 0x57, 0x01, 0x3f, + 0xf0, 0x57, 0x00, 0x3f, 0xc0, 0x1f, 0xc0, 0x2f, 0xd0, 0xff, 0xff, 0x2f, + 0x50, 0xff, 0xff, 0x2b, 0x50, 0xf0, 0x3f, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1e, 0x00, 0x00, 0xa0, 0x3f, 0x00, + 0x00, 0xe8, 0xad, 0x00, 0x00, 0x7a, 0xa1, 0x02, 0x00, 0x5a, 0x80, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xc0, 0x0f, 0xc0, 0x3f, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x3f, + 0x00, 0xf0, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x14, 0x7a, 0x00, 0x00, 0xd5, 0x5e, 0x01, + 0x00, 0xf5, 0x56, 0x01, 0x00, 0xb4, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, + 0xf0, 0x03, 0x00, 0x3f, 0xf0, 0x03, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x3f, + 0xc0, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xf0, 0x3f, 0x3f, + 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x80, 0x0a, 0x00, 0xa8, 0xaa, 0x0a, + 0x00, 0xa8, 0xaa, 0x02, 0x00, 0xa8, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0xd0, 0x0b, 0x80, 0x0a, + 0xf0, 0x7b, 0xb5, 0x2a, 0xf8, 0xf5, 0x7d, 0xa9, 0x78, 0xd5, 0x5f, 0xa5, + 0x78, 0x85, 0x4a, 0xa5, 0xf8, 0xa1, 0x28, 0xbd, 0xf0, 0x2b, 0xa0, 0x3f, + 0xd0, 0x0b, 0x80, 0x1f, 0x50, 0x01, 0x00, 0x15, 0x50, 0x01, 0x00, 0x15, + 0x50, 0x01, 0x00, 0x15, 0x50, 0x05, 0x40, 0x05, 0x50, 0x55, 0x55, 0x05, + 0x50, 0x55, 0x55, 0x01, 0x50, 0x51, 0x15, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x5c, 0x00, 0x8a, 0x00, + 0xb8, 0x00, 0xe7, 0x00, 0x15, 0x01, 0x43, 0x01, 0x71, 0x01, 0x9f, 0x01, + 0xcd, 0x01, 0xfa, 0x01, 0x28, 0x02, 0x56, 0x02, 0x84, 0x02, 0xb2, 0x02, + 0xe0, 0x02, 0x0e, 0x03, 0x3b, 0x03, 0x69, 0x03, 0x97, 0x03, 0xc5, 0x03, + 0xf2, 0x03, 0x20, 0x04, 0x4e, 0x04, 0x7b, 0x04, 0xa9, 0x04, 0xd6, 0x04, + 0x04, 0x05, 0x31, 0x05, 0x5f, 0x05, 0x8c, 0x05, 0xba, 0x05, 0xe7, 0x05, + 0x15, 0x06, 0x42, 0x06, 0x70, 0x06, 0x9d, 0x06, 0xca, 0x06, 0xf8, 0x06, + 0x25, 0x07, 0x52, 0x07, 0x7f, 0x07, 0xad, 0x07, 0xda, 0x07, 0x07, 0x08, + 0x34, 0x08, 0x61, 0x08, 0x8e, 0x08, 0xbc, 0x08, 0xe9, 0x08, 0x16, 0x09, + 0x43, 0x09, 0x70, 0x09, 0x9d, 0x09, 0xca, 0x09, 0xf7, 0x09, 0x24, 0x0a, + 0x50, 0x0a, 0x7d, 0x0a, 0xaa, 0x0a, 0xd7, 0x0a, 0x04, 0x0b, 0x31, 0x0b, + 0x5d, 0x0b, 0x8a, 0x0b, 0xb7, 0x0b, 0xe4, 0x0b, 0x10, 0x0c, 0x3d, 0x0c, + 0x6a, 0x0c, 0x96, 0x0c, 0xc3, 0x0c, 0xef, 0x0c, 0x1c, 0x0d, 0x49, 0x0d, + 0x75, 0x0d, 0xa2, 0x0d, 0xce, 0x0d, 0xfb, 0x0d, 0x27, 0x0e, 0x53, 0x0e, + 0x80, 0x0e, 0xac, 0x0e, 0xd9, 0x0e, 0x05, 0x0f, 0x31, 0x0f, 0x5d, 0x0f, + 0x8a, 0x0f, 0xb6, 0x0f, 0xe2, 0x0f, 0x0e, 0x10, 0x3b, 0x10, 0x67, 0x10, + 0x93, 0x10, 0xbf, 0x10, 0xeb, 0x10, 0x17, 0x11, 0x43, 0x11, 0x6f, 0x11, + 0x9b, 0x11, 0xc7, 0x11, 0xf3, 0x11, 0x1f, 0x12, 0x4b, 0x12, 0x77, 0x12, + 0xa3, 0x12, 0xcf, 0x12, 0xfb, 0x12, 0x27, 0x13, 0x53, 0x13, 0x7e, 0x13, + 0xaa, 0x13, 0xd6, 0x13, 0x02, 0x14, 0x2d, 0x14, 0x59, 0x14, 0x85, 0x14, + 0xb0, 0x14, 0xdc, 0x14, 0x08, 0x15, 0x33, 0x15, 0x5f, 0x15, 0x8a, 0x15, + 0xb6, 0x15, 0xe2, 0x15, 0x0d, 0x16, 0x39, 0x16, 0x64, 0x16, 0x8f, 0x16, + 0xbb, 0x16, 0xe6, 0x16, 0x12, 0x17, 0x3d, 0x17, 0x68, 0x17, 0x94, 0x17, + 0xbf, 0x17, 0xea, 0x17, 0x15, 0x18, 0x41, 0x18, 0x6c, 0x18, 0x97, 0x18, + 0xc2, 0x18, 0xed, 0x18, 0x19, 0x19, 0x44, 0x19, 0x6f, 0x19, 0x9a, 0x19, + 0xc5, 0x19, 0xf0, 0x19, 0x1b, 0x1a, 0x46, 0x1a, 0x71, 0x1a, 0x9c, 0x1a, + 0xc7, 0x1a, 0xf2, 0x1a, 0x1d, 0x1b, 0x48, 0x1b, 0x73, 0x1b, 0x9d, 0x1b, + 0xc8, 0x1b, 0xf3, 0x1b, 0x1e, 0x1c, 0x49, 0x1c, 0x73, 0x1c, 0x9e, 0x1c, + 0xc9, 0x1c, 0xf4, 0x1c, 0x1e, 0x1d, 0x49, 0x1d, 0x74, 0x1d, 0x9e, 0x1d, + 0xc9, 0x1d, 0xf3, 0x1d, 0x1e, 0x1e, 0x48, 0x1e, 0x73, 0x1e, 0x9d, 0x1e, + 0xc8, 0x1e, 0xf2, 0x1e, 0x1d, 0x1f, 0x47, 0x1f, 0x72, 0x1f, 0x9c, 0x1f, + 0xc6, 0x1f, 0xf1, 0x1f, 0x1b, 0x20, 0x45, 0x20, 0x70, 0x20, 0x9a, 0x20, + 0xc4, 0x20, 0xee, 0x20, 0x19, 0x21, 0x43, 0x21, 0x6d, 0x21, 0x97, 0x21, + 0xc1, 0x21, 0xec, 0x21, 0x16, 0x22, 0x40, 0x22, 0x6a, 0x22, 0x94, 0x22, + 0xbe, 0x22, 0xe8, 0x22, 0x12, 0x23, 0x3c, 0x23, 0x66, 0x23, 0x90, 0x23, + 0xba, 0x23, 0xe4, 0x23, 0x0d, 0x24, 0x37, 0x24, 0x61, 0x24, 0x8b, 0x24, + 0xb5, 0x24, 0xdf, 0x24, 0x08, 0x25, 0x32, 0x25, 0x5c, 0x25, 0x86, 0x25, + 0xaf, 0x25, 0xd9, 0x25, 0x03, 0x26, 0x2c, 0x26, 0x56, 0x26, 0x7f, 0x26, + 0xa9, 0x26, 0xd3, 0x26, 0xfc, 0x26, 0x26, 0x27, 0x4f, 0x27, 0x79, 0x27, + 0xa2, 0x27, 0xcc, 0x27, 0xf5, 0x27, 0x1e, 0x28, 0x48, 0x28, 0x71, 0x28, + 0x9b, 0x28, 0xc4, 0x28, 0xed, 0x28, 0x17, 0x29, 0x40, 0x29, 0x69, 0x29, + 0x92, 0x29, 0xbc, 0x29, 0xe5, 0x29, 0x0e, 0x2a, 0x37, 0x2a, 0x61, 0x2a, + 0x8a, 0x2a, 0xb3, 0x2a, 0xdc, 0x2a, 0x05, 0x2b, 0x2e, 0x2b, 0x57, 0x2b, + 0x80, 0x2b, 0xa9, 0x2b, 0xd2, 0x2b, 0xfb, 0x2b, 0x24, 0x2c, 0x4d, 0x2c, + 0x76, 0x2c, 0x9f, 0x2c, 0xc8, 0x2c, 0xf1, 0x2c, 0x1a, 0x2d, 0x43, 0x2d, + 0x6b, 0x2d, 0x94, 0x2d, 0xbd, 0x2d, 0xe6, 0x2d, 0x0f, 0x2e, 0x37, 0x2e, + 0x60, 0x2e, 0x89, 0x2e, 0xb1, 0x2e, 0xda, 0x2e, 0x03, 0x2f, 0x2b, 0x2f, + 0x54, 0x2f, 0x7d, 0x2f, 0xa5, 0x2f, 0xce, 0x2f, 0xf6, 0x2f, 0x1f, 0x30, + 0x47, 0x30, 0x70, 0x30, 0x98, 0x30, 0xc1, 0x30, 0xe9, 0x30, 0x12, 0x31, + 0x3a, 0x31, 0x62, 0x31, 0x8b, 0x31, 0xb3, 0x31, 0xdc, 0x31, 0x04, 0x32, + 0x2c, 0x32, 0x55, 0x32, 0x7d, 0x32, 0xa5, 0x32, 0xcd, 0x32, 0xf6, 0x32, + 0x1e, 0x33, 0x46, 0x33, 0x6e, 0x33, 0x96, 0x33, 0xbe, 0x33, 0xe7, 0x33, + 0x0f, 0x34, 0x37, 0x34, 0x5f, 0x34, 0x87, 0x34, 0xaf, 0x34, 0xd7, 0x34, + 0xff, 0x34, 0x27, 0x35, 0x4f, 0x35, 0x77, 0x35, 0x9f, 0x35, 0xc7, 0x35, + 0xef, 0x35, 0x16, 0x36, 0x3e, 0x36, 0x66, 0x36, 0x8e, 0x36, 0xb6, 0x36, + 0xde, 0x36, 0x05, 0x37, 0x2d, 0x37, 0x55, 0x37, 0x7d, 0x37, 0xa4, 0x37, + 0xcc, 0x37, 0xf4, 0x37, 0x1b, 0x38, 0x43, 0x38, 0x6b, 0x38, 0x92, 0x38, + 0xba, 0x38, 0xe2, 0x38, 0x09, 0x39, 0x31, 0x39, 0x58, 0x39, 0x80, 0x39, + 0xa7, 0x39, 0xcf, 0x39, 0xf6, 0x39, 0x1e, 0x3a, 0x45, 0x3a, 0x6c, 0x3a, + 0x94, 0x3a, 0xbb, 0x3a, 0xe3, 0x3a, 0x0a, 0x3b, 0x31, 0x3b, 0x59, 0x3b, + 0x80, 0x3b, 0xa7, 0x3b, 0xce, 0x3b, 0xf6, 0x3b, 0x1d, 0x3c, 0x44, 0x3c, + 0x6b, 0x3c, 0x93, 0x3c, 0xba, 0x3c, 0xe1, 0x3c, 0x08, 0x3d, 0x2f, 0x3d, + 0x56, 0x3d, 0x7d, 0x3d, 0xa5, 0x3d, 0xcc, 0x3d, 0xf3, 0x3d, 0x1a, 0x3e, + 0x41, 0x3e, 0x68, 0x3e, 0x8f, 0x3e, 0xb6, 0x3e, 0xdd, 0x3e, 0x03, 0x3f, + 0x2a, 0x3f, 0x51, 0x3f, 0x78, 0x3f, 0x9f, 0x3f, 0xc6, 0x3f, 0xed, 0x3f, + 0x14, 0x40, 0x3a, 0x40, 0x61, 0x40, 0x88, 0x40, 0xaf, 0x40, 0xd5, 0x40, + 0xfc, 0x40, 0x23, 0x41, 0x4a, 0x41, 0x70, 0x41, 0x97, 0x41, 0xbe, 0x41, + 0xe4, 0x41, 0x0b, 0x42, 0x31, 0x42, 0x58, 0x42, 0x7f, 0x42, 0xa5, 0x42, + 0xcc, 0x42, 0xf2, 0x42, 0x19, 0x43, 0x3f, 0x43, 0x66, 0x43, 0x8c, 0x43, + 0xb3, 0x43, 0xd9, 0x43, 0xff, 0x43, 0x26, 0x44, 0x4c, 0x44, 0x72, 0x44, + 0x99, 0x44, 0xbf, 0x44, 0xe5, 0x44, 0x0c, 0x45, 0x32, 0x45, 0x58, 0x45, + 0x7f, 0x45, 0xa5, 0x45, 0xcb, 0x45, 0xf1, 0x45, 0x17, 0x46, 0x3e, 0x46, + 0x64, 0x46, 0x8a, 0x46, 0xb0, 0x46, 0xd6, 0x46, 0xfc, 0x46, 0x22, 0x47, + 0x48, 0x47, 0x6f, 0x47, 0x95, 0x47, 0xbb, 0x47, 0xe1, 0x47, 0x07, 0x48, + 0x2d, 0x48, 0x53, 0x48, 0x78, 0x48, 0x9e, 0x48, 0xc4, 0x48, 0xea, 0x48, + 0x10, 0x49, 0x36, 0x49, 0x5c, 0x49, 0x82, 0x49, 0xa8, 0x49, 0xcd, 0x49, + 0xf3, 0x49, 0x19, 0x4a, 0x3f, 0x4a, 0x64, 0x4a, 0x8a, 0x4a, 0xb0, 0x4a, + 0xd6, 0x4a, 0xfb, 0x4a, 0x21, 0x4b, 0x47, 0x4b, 0x6c, 0x4b, 0x92, 0x4b, + 0xb8, 0x4b, 0xdd, 0x4b, 0x03, 0x4c, 0x28, 0x4c, 0x4e, 0x4c, 0x73, 0x4c, + 0x99, 0x4c, 0xbe, 0x4c, 0xe4, 0x4c, 0x09, 0x4d, 0x2f, 0x4d, 0x54, 0x4d, + 0x7a, 0x4d, 0x9f, 0x4d, 0xc5, 0x4d, 0xea, 0x4d, 0x0f, 0x4e, 0x35, 0x4e, + 0x5a, 0x4e, 0x7f, 0x4e, 0xa5, 0x4e, 0xca, 0x4e, 0xef, 0x4e, 0x15, 0x4f, + 0x3a, 0x4f, 0x5f, 0x4f, 0x84, 0x4f, 0xaa, 0x4f, 0xcf, 0x4f, 0xf4, 0x4f, + 0x19, 0x50, 0x3e, 0x50, 0x63, 0x50, 0x89, 0x50, 0xae, 0x50, 0xd3, 0x50, + 0xf8, 0x50, 0x1d, 0x51, 0x42, 0x51, 0x67, 0x51, 0x8c, 0x51, 0xb1, 0x51, + 0xd6, 0x51, 0xfb, 0x51, 0x20, 0x52, 0x45, 0x52, 0x6a, 0x52, 0x8f, 0x52, + 0xb4, 0x52, 0xd9, 0x52, 0xfd, 0x52, 0x22, 0x53, 0x47, 0x53, 0x6c, 0x53, + 0x91, 0x53, 0xb6, 0x53, 0xda, 0x53, 0xff, 0x53, 0x24, 0x54, 0x49, 0x54, + 0x6e, 0x54, 0x92, 0x54, 0xb7, 0x54, 0xdc, 0x54, 0x00, 0x55, 0x25, 0x55, + 0x4a, 0x55, 0x6e, 0x55, 0x93, 0x55, 0xb8, 0x55, 0xdc, 0x55, 0x01, 0x56, + 0x25, 0x56, 0x4a, 0x56, 0x6e, 0x56, 0x93, 0x56, 0xb7, 0x56, 0xdc, 0x56, + 0x00, 0x57, 0x25, 0x57, 0x49, 0x57, 0x6e, 0x57, 0x92, 0x57, 0xb7, 0x57, + 0xdb, 0x57, 0xff, 0x57, 0x24, 0x58, 0x48, 0x58, 0x6c, 0x58, 0x91, 0x58, + 0xb5, 0x58, 0xd9, 0x58, 0xfe, 0x58, 0x22, 0x59, 0x46, 0x59, 0x6a, 0x59, + 0x8f, 0x59, 0xb3, 0x59, 0xd7, 0x59, 0xfb, 0x59, 0x20, 0x5a, 0x44, 0x5a, + 0x68, 0x5a, 0x8c, 0x5a, 0xb0, 0x5a, 0xd4, 0x5a, 0xf8, 0x5a, 0x1c, 0x5b, + 0x40, 0x5b, 0x64, 0x5b, 0x89, 0x5b, 0xad, 0x5b, 0xd1, 0x5b, 0xf5, 0x5b, + 0x19, 0x5c, 0x3d, 0x5c, 0x60, 0x5c, 0x84, 0x5c, 0xa8, 0x5c, 0xcc, 0x5c, + 0xf0, 0x5c, 0x14, 0x5d, 0x38, 0x5d, 0x5c, 0x5d, 0x80, 0x5d, 0xa3, 0x5d, + 0xc7, 0x5d, 0xeb, 0x5d, 0x0f, 0x5e, 0x33, 0x5e, 0x56, 0x5e, 0x7a, 0x5e, + 0x9e, 0x5e, 0xc2, 0x5e, 0xe5, 0x5e, 0x09, 0x5f, 0x2d, 0x5f, 0x50, 0x5f, + 0x74, 0x5f, 0x98, 0x5f, 0xbb, 0x5f, 0xdf, 0x5f, 0x03, 0x60, 0x26, 0x60, + 0x4a, 0x60, 0x6d, 0x60, 0x91, 0x60, 0xb4, 0x60, 0xd8, 0x60, 0xfb, 0x60, + 0x1f, 0x61, 0x42, 0x61, 0x66, 0x61, 0x89, 0x61, 0xad, 0x61, 0xd0, 0x61, + 0xf4, 0x61, 0x17, 0x62, 0x3a, 0x62, 0x5e, 0x62, 0x81, 0x62, 0xa5, 0x62, + 0xc8, 0x62, 0xeb, 0x62, 0x0f, 0x63, 0x32, 0x63, 0x55, 0x63, 0x78, 0x63, + 0x9c, 0x63, 0xbf, 0x63, 0xe2, 0x63, 0x05, 0x64, 0x29, 0x64, 0x4c, 0x64, + 0x6f, 0x64, 0x92, 0x64, 0xb5, 0x64, 0xd8, 0x64, 0xfc, 0x64, 0x1f, 0x65, + 0x42, 0x65, 0x65, 0x65, 0x88, 0x65, 0xab, 0x65, 0xce, 0x65, 0xf1, 0x65, + 0x14, 0x66, 0x37, 0x66, 0x5a, 0x66, 0x7d, 0x66, 0xa0, 0x66, 0xc3, 0x66, + 0xe6, 0x66, 0x09, 0x67, 0x2c, 0x67, 0x4f, 0x67, 0x72, 0x67, 0x94, 0x67, + 0xb7, 0x67, 0xda, 0x67, 0xfd, 0x67, 0x20, 0x68, 0x43, 0x68, 0x66, 0x68, + 0x88, 0x68, 0xab, 0x68, 0xce, 0x68, 0xf1, 0x68, 0x13, 0x69, 0x36, 0x69, + 0x59, 0x69, 0x7b, 0x69, 0x9e, 0x69, 0xc1, 0x69, 0xe4, 0x69, 0x06, 0x6a, + 0x29, 0x6a, 0x4b, 0x6a, 0x6e, 0x6a, 0x91, 0x6a, 0xb3, 0x6a, 0xd6, 0x6a, + 0xf8, 0x6a, 0x1b, 0x6b, 0x3d, 0x6b, 0x60, 0x6b, 0x83, 0x6b, 0xa5, 0x6b, + 0xc7, 0x6b, 0xea, 0x6b, 0x0c, 0x6c, 0x2f, 0x6c, 0x51, 0x6c, 0x74, 0x6c, + 0x96, 0x6c, 0xb9, 0x6c, 0xdb, 0x6c, 0xfd, 0x6c, 0x20, 0x6d, 0x42, 0x6d, + 0x64, 0x6d, 0x87, 0x6d, 0xa9, 0x6d, 0xcb, 0x6d, 0xee, 0x6d, 0x10, 0x6e, + 0x32, 0x6e, 0x54, 0x6e, 0x77, 0x6e, 0x99, 0x6e, 0xbb, 0x6e, 0xdd, 0x6e, + 0xff, 0x6e, 0x22, 0x6f, 0x44, 0x6f, 0x66, 0x6f, 0x88, 0x6f, 0xaa, 0x6f, + 0xcc, 0x6f, 0xee, 0x6f, 0x11, 0x70, 0x33, 0x70, 0x55, 0x70, 0x77, 0x70, + 0x99, 0x70, 0xbb, 0x70, 0xdd, 0x70, 0xff, 0x70, 0x21, 0x71, 0x43, 0x71, + 0x65, 0x71, 0x87, 0x71, 0xa9, 0x71, 0xcb, 0x71, 0xec, 0x71, 0x0e, 0x72, + 0x30, 0x72, 0x52, 0x72, 0x74, 0x72, 0x96, 0x72, 0xb8, 0x72, 0xda, 0x72, + 0xfb, 0x72, 0x1d, 0x73, 0x3f, 0x73, 0x61, 0x73, 0x83, 0x73, 0xa4, 0x73, + 0xc6, 0x73, 0xe8, 0x73, 0x0a, 0x74, 0x2b, 0x74, 0x4d, 0x74, 0x6f, 0x74, + 0x90, 0x74, 0xb2, 0x74, 0xd4, 0x74, 0xf5, 0x74, 0x17, 0x75, 0x39, 0x75, + 0x5a, 0x75, 0x7c, 0x75, 0x9d, 0x75, 0xbf, 0x75, 0xe0, 0x75, 0x02, 0x76, + 0x24, 0x76, 0x45, 0x76, 0x67, 0x76, 0x88, 0x76, 0xaa, 0x76, 0xcb, 0x76, + 0xec, 0x76, 0x0e, 0x77, 0x2f, 0x77, 0x51, 0x77, 0x72, 0x77, 0x94, 0x77, + 0xb5, 0x77, 0xd6, 0x77, 0xf8, 0x77, 0x19, 0x78, 0x3a, 0x78, 0x5c, 0x78, + 0x7d, 0x78, 0x9e, 0x78, 0xc0, 0x78, 0xe1, 0x78, 0x02, 0x79, 0x24, 0x79, + 0x45, 0x79, 0x66, 0x79, 0x87, 0x79, 0xa8, 0x79, 0xca, 0x79, 0xeb, 0x79, + 0x0c, 0x7a, 0x2d, 0x7a, 0x4e, 0x7a, 0x70, 0x7a, 0x91, 0x7a, 0xb2, 0x7a, + 0xd3, 0x7a, 0xf4, 0x7a, 0x15, 0x7b, 0x36, 0x7b, 0x57, 0x7b, 0x78, 0x7b, + 0x99, 0x7b, 0xba, 0x7b, 0xdb, 0x7b, 0xfc, 0x7b, 0x1d, 0x7c, 0x3e, 0x7c, + 0x5f, 0x7c, 0x80, 0x7c, 0xa1, 0x7c, 0xc2, 0x7c, 0xe3, 0x7c, 0x04, 0x7d, + 0x25, 0x7d, 0x46, 0x7d, 0x67, 0x7d, 0x88, 0x7d, 0xa8, 0x7d, 0xc9, 0x7d, + 0xea, 0x7d, 0x0b, 0x7e, 0x2c, 0x7e, 0x4d, 0x7e, 0x6d, 0x7e, 0x8e, 0x7e, + 0xaf, 0x7e, 0xd0, 0x7e, 0xf0, 0x7e, 0x11, 0x7f, 0x32, 0x7f, 0x53, 0x7f, + 0x73, 0x7f, 0x94, 0x7f, 0xb5, 0x7f, 0xd5, 0x7f, 0xf6, 0x7f, 0x17, 0x80, + 0x37, 0x80, 0x58, 0x80, 0x78, 0x80, 0x99, 0x80, 0xba, 0x80, 0xda, 0x80, + 0xfb, 0x80, 0x1b, 0x81, 0x3c, 0x81, 0x5c, 0x81, 0x7d, 0x81, 0x9d, 0x81, + 0xbe, 0x81, 0xde, 0x81, 0xff, 0x81, 0x1f, 0x82, 0x40, 0x82, 0x60, 0x82, + 0x81, 0x82, 0xa1, 0x82, 0xc1, 0x82, 0xe2, 0x82, 0x02, 0x83, 0x23, 0x83, + 0x43, 0x83, 0x63, 0x83, 0x84, 0x83, 0xa4, 0x83, 0xc4, 0x83, 0xe5, 0x83, + 0x05, 0x84, 0x25, 0x84, 0x45, 0x84, 0x66, 0x84, 0x86, 0x84, 0xa6, 0x84, + 0xc6, 0x84, 0xe7, 0x84, 0x07, 0x85, 0x27, 0x85, 0x47, 0x85, 0x67, 0x85, + 0x88, 0x85, 0xa8, 0x85, 0xc8, 0x85, 0xe8, 0x85, 0x08, 0x86, 0x28, 0x86, + 0x48, 0x86, 0x68, 0x86, 0x89, 0x86, 0xa9, 0x86, 0xc9, 0x86, 0xe9, 0x86, + 0x09, 0x87, 0x29, 0x87, 0x49, 0x87, 0x69, 0x87, 0x89, 0x87, 0xa9, 0x87, + 0xc9, 0x87, 0xe9, 0x87, 0x09, 0x88, 0x29, 0x88, 0x48, 0x88, 0x68, 0x88, + 0x88, 0x88, 0xa8, 0x88, 0xc8, 0x88, 0xe8, 0x88, 0x08, 0x89, 0x28, 0x89, + 0x47, 0x89, 0x67, 0x89, 0x87, 0x89, 0xa7, 0x89, 0xc7, 0x89, 0xe7, 0x89, + 0x06, 0x8a, 0x26, 0x8a, 0x46, 0x8a, 0x66, 0x8a, 0x85, 0x8a, 0xa5, 0x8a, + 0xc5, 0x8a, 0xe4, 0x8a, 0x04, 0x8b, 0x24, 0x8b, 0x43, 0x8b, 0x63, 0x8b, + 0x83, 0x8b, 0xa2, 0x8b, 0xc2, 0x8b, 0xe2, 0x8b, 0x01, 0x8c, 0x21, 0x8c, + 0x40, 0x8c, 0x60, 0x8c, 0x80, 0x8c, 0x9f, 0x8c, 0xbf, 0x8c, 0xde, 0x8c, + 0xfe, 0x8c, 0x1d, 0x8d, 0x3d, 0x8d, 0x5c, 0x8d, 0x7c, 0x8d, 0x9b, 0x8d, + 0xbb, 0x8d, 0xda, 0x8d, 0xfa, 0x8d, 0x19, 0x8e, 0x38, 0x8e, 0x58, 0x8e, + 0x77, 0x8e, 0x97, 0x8e, 0xb6, 0x8e, 0xd5, 0x8e, 0xf5, 0x8e, 0x14, 0x8f, + 0x33, 0x8f, 0x53, 0x8f, 0x72, 0x8f, 0x91, 0x8f, 0xb1, 0x8f, 0xd0, 0x8f, + 0xef, 0x8f, 0x0e, 0x90, 0x2e, 0x90, 0x4d, 0x90, 0x6c, 0x90, 0x8b, 0x90, + 0xab, 0x90, 0xca, 0x90, 0xe9, 0x90, 0x08, 0x91, 0x27, 0x91, 0x46, 0x91, + 0x66, 0x91, 0x85, 0x91, 0xa4, 0x91, 0xc3, 0x91, 0xe2, 0x91, 0x01, 0x92, + 0x20, 0x92, 0x3f, 0x92, 0x5e, 0x92, 0x7d, 0x92, 0x9c, 0x92, 0xbc, 0x92, + 0xdb, 0x92, 0xfa, 0x92, 0x19, 0x93, 0x38, 0x93, 0x57, 0x93, 0x76, 0x93, + 0x94, 0x93, 0xb3, 0x93, 0xd2, 0x93, 0xf1, 0x93, 0x10, 0x94, 0x2f, 0x94, + 0x4e, 0x94, 0x6d, 0x94, 0x8c, 0x94, 0xab, 0x94, 0xca, 0x94, 0xe8, 0x94, + 0x07, 0x95, 0x26, 0x95, 0x45, 0x95, 0x64, 0x95, 0x83, 0x95, 0xa1, 0x95, + 0xc0, 0x95, 0xdf, 0x95, 0xfe, 0x95, 0x1c, 0x96, 0x3b, 0x96, 0x5a, 0x96, + 0x79, 0x96, 0x97, 0x96, 0xb6, 0x96, 0xd5, 0x96, 0xf3, 0x96, 0x12, 0x97, + 0x31, 0x97, 0x4f, 0x97, 0x6e, 0x97, 0x8d, 0x97, 0xab, 0x97, 0xca, 0x97, + 0xe8, 0x97, 0x07, 0x98, 0x26, 0x98, 0x44, 0x98, 0x63, 0x98, 0x81, 0x98, + 0xa0, 0x98, 0xbe, 0x98, 0xdd, 0x98, 0xfb, 0x98, 0x1a, 0x99, 0x38, 0x99, + 0x57, 0x99, 0x75, 0x99, 0x94, 0x99, 0xb2, 0x99, 0xd1, 0x99, 0xef, 0x99, + 0x0e, 0x9a, 0x2c, 0x9a, 0x4a, 0x9a, 0x69, 0x9a, 0x87, 0x9a, 0xa6, 0x9a, + 0xc4, 0x9a, 0xe2, 0x9a, 0x01, 0x9b, 0x1f, 0x9b, 0x3d, 0x9b, 0x5c, 0x9b, + 0x7a, 0x9b, 0x98, 0x9b, 0xb7, 0x9b, 0xd5, 0x9b, 0xf3, 0x9b, 0x11, 0x9c, + 0x30, 0x9c, 0x4e, 0x9c, 0x6c, 0x9c, 0x8a, 0x9c, 0xa9, 0x9c, 0xc7, 0x9c, + 0xe5, 0x9c, 0x03, 0x9d, 0x21, 0x9d, 0x3f, 0x9d, 0x5e, 0x9d, 0x7c, 0x9d, + 0x9a, 0x9d, 0xb8, 0x9d, 0xd6, 0x9d, 0xf4, 0x9d, 0x12, 0x9e, 0x30, 0x9e, + 0x4f, 0x9e, 0x6d, 0x9e, 0x8b, 0x9e, 0xa9, 0x9e, 0xc7, 0x9e, 0xe5, 0x9e, + 0x03, 0x9f, 0x21, 0x9f, 0x3f, 0x9f, 0x5d, 0x9f, 0x7b, 0x9f, 0x99, 0x9f, + 0xb7, 0x9f, 0xd5, 0x9f, 0xf3, 0x9f, 0x11, 0xa0, 0x2e, 0xa0, 0x4c, 0xa0, + 0x6a, 0xa0, 0x88, 0xa0, 0xa6, 0xa0, 0xc4, 0xa0, 0xe2, 0xa0, 0x00, 0xa1, + 0x1e, 0xa1, 0x3b, 0xa1, 0x59, 0xa1, 0x77, 0xa1, 0x95, 0xa1, 0xb3, 0xa1, + 0xd0, 0xa1, 0xee, 0xa1, 0x0c, 0xa2, 0x2a, 0xa2, 0x47, 0xa2, 0x65, 0xa2, + 0x83, 0xa2, 0xa1, 0xa2, 0xbe, 0xa2, 0xdc, 0xa2, 0xfa, 0xa2, 0x18, 0xa3, + 0x35, 0xa3, 0x53, 0xa3, 0x71, 0xa3, 0x8e, 0xa3, 0xac, 0xa3, 0xc9, 0xa3, + 0xe7, 0xa3, 0x05, 0xa4, 0x22, 0xa4, 0x40, 0xa4, 0x5d, 0xa4, 0x7b, 0xa4, + 0x99, 0xa4, 0xb6, 0xa4, 0xd4, 0xa4, 0xf1, 0xa4, 0x0f, 0xa5, 0x2c, 0xa5, + 0x4a, 0xa5, 0x67, 0xa5, 0x85, 0xa5, 0xa2, 0xa5, 0xc0, 0xa5, 0xdd, 0xa5, + 0xfb, 0xa5, 0x18, 0xa6, 0x36, 0xa6, 0x53, 0xa6, 0x71, 0xa6, 0x8e, 0xa6, + 0xab, 0xa6, 0xc9, 0xa6, 0xe6, 0xa6, 0x03, 0xa7, 0x21, 0xa7, 0x3e, 0xa7, + 0x5c, 0xa7, 0x79, 0xa7, 0x96, 0xa7, 0xb4, 0xa7, 0xd1, 0xa7, 0xee, 0xa7, + 0x0b, 0xa8, 0x29, 0xa8, 0x46, 0xa8, 0x63, 0xa8, 0x81, 0xa8, 0x9e, 0xa8, + 0xbb, 0xa8, 0xd8, 0xa8, 0xf5, 0xa8, 0x13, 0xa9, 0x30, 0xa9, 0x4d, 0xa9, + 0x6a, 0xa9, 0x87, 0xa9, 0xa5, 0xa9, 0xc2, 0xa9, 0xdf, 0xa9, 0xfc, 0xa9, + 0x19, 0xaa, 0x36, 0xaa, 0x53, 0xaa, 0x71, 0xaa, 0x8e, 0xaa, 0xab, 0xaa, + 0xc8, 0xaa, 0xe5, 0xaa, 0x02, 0xab, 0x1f, 0xab, 0x3c, 0xab, 0x59, 0xab, + 0x76, 0xab, 0x93, 0xab, 0xb0, 0xab, 0xcd, 0xab, 0xea, 0xab, 0x07, 0xac, + 0x24, 0xac, 0x41, 0xac, 0x5e, 0xac, 0x7b, 0xac, 0x98, 0xac, 0xb5, 0xac, + 0xd2, 0xac, 0xef, 0xac, 0x0c, 0xad, 0x28, 0xad, 0x45, 0xad, 0x62, 0xad, + 0x7f, 0xad, 0x9c, 0xad, 0xb9, 0xad, 0xd6, 0xad, 0xf2, 0xad, 0x0f, 0xae, + 0x2c, 0xae, 0x49, 0xae, 0x66, 0xae, 0x82, 0xae, 0x9f, 0xae, 0xbc, 0xae, + 0xd9, 0xae, 0xf5, 0xae, 0x12, 0xaf, 0x2f, 0xaf, 0x4c, 0xaf, 0x68, 0xaf, + 0x85, 0xaf, 0xa2, 0xaf, 0xbe, 0xaf, 0xdb, 0xaf, 0xf8, 0xaf, 0x15, 0xb0, + 0x31, 0xb0, 0x4e, 0xb0, 0x6a, 0xb0, 0x87, 0xb0, 0xa4, 0xb0, 0xc0, 0xb0, + 0xdd, 0xb0, 0xfa, 0xb0, 0x16, 0xb1, 0x33, 0xb1, 0x4f, 0xb1, 0x6c, 0xb1, + 0x88, 0xb1, 0xa5, 0xb1, 0xc1, 0xb1, 0xde, 0xb1, 0xfa, 0xb1, 0x17, 0xb2, + 0x33, 0xb2, 0x50, 0xb2, 0x6c, 0xb2, 0x89, 0xb2, 0xa5, 0xb2, 0xc2, 0xb2, + 0xde, 0xb2, 0xfb, 0xb2, 0x17, 0xb3, 0x34, 0xb3, 0x50, 0xb3, 0x6c, 0xb3, + 0x89, 0xb3, 0xa5, 0xb3, 0xc2, 0xb3, 0xde, 0xb3, 0xfa, 0xb3, 0x17, 0xb4, + 0x33, 0xb4, 0x4f, 0xb4, 0x6c, 0xb4, 0x88, 0xb4, 0xa4, 0xb4, 0xc1, 0xb4, + 0xdd, 0xb4, 0xf9, 0xb4, 0x15, 0xb5, 0x32, 0xb5, 0x4e, 0xb5, 0x6a, 0xb5, + 0x87, 0xb5, 0xa3, 0xb5, 0xbf, 0xb5, 0xdb, 0xb5, 0xf7, 0xb5, 0x14, 0xb6, + 0x30, 0xb6, 0x4c, 0xb6, 0x68, 0xb6, 0x84, 0xb6, 0xa0, 0xb6, 0xbd, 0xb6, + 0xd9, 0xb6, 0xf5, 0xb6, 0x11, 0xb7, 0x2d, 0xb7, 0x49, 0xb7, 0x65, 0xb7, + 0x81, 0xb7, 0x9e, 0xb7, 0xba, 0xb7, 0xd6, 0xb7, 0xf2, 0xb7, 0x0e, 0xb8, + 0x2a, 0xb8, 0x46, 0xb8, 0x62, 0xb8, 0x7e, 0xb8, 0x9a, 0xb8, 0xb6, 0xb8, + 0xd2, 0xb8, 0xee, 0xb8, 0x0a, 0xb9, 0x26, 0xb9, 0x42, 0xb9, 0x5e, 0xb9, + 0x7a, 0xb9, 0x96, 0xb9, 0xb2, 0xb9, 0xce, 0xb9, 0xe9, 0xb9, 0x05, 0xba, + 0x21, 0xba, 0x3d, 0xba, 0x59, 0xba, 0x75, 0xba, 0x91, 0xba, 0xad, 0xba, + 0xc8, 0xba, 0xe4, 0xba, 0x00, 0xbb, 0x1c, 0xbb, 0x38, 0xbb, 0x54, 0xbb, + 0x6f, 0xbb, 0x8b, 0xbb, 0xa7, 0xbb, 0xc3, 0xbb, 0xde, 0xbb, 0xfa, 0xbb, + 0x16, 0xbc, 0x32, 0xbc, 0x4d, 0xbc, 0x69, 0xbc, 0x85, 0xbc, 0xa1, 0xbc, + 0xbc, 0xbc, 0xd8, 0xbc, 0xf4, 0xbc, 0x0f, 0xbd, 0x2b, 0xbd, 0x47, 0xbd, + 0x62, 0xbd, 0x7e, 0xbd, 0x9a, 0xbd, 0xb5, 0xbd, 0xd1, 0xbd, 0xec, 0xbd, + 0x08, 0xbe, 0x24, 0xbe, 0x3f, 0xbe, 0x5b, 0xbe, 0x76, 0xbe, 0x92, 0xbe, + 0xad, 0xbe, 0xc9, 0xbe, 0xe5, 0xbe, 0x00, 0xbf, 0x1c, 0xbf, 0x37, 0xbf, + 0x53, 0xbf, 0x6e, 0xbf, 0x8a, 0xbf, 0xa5, 0xbf, 0xc1, 0xbf, 0xdc, 0xbf, + 0xf7, 0xbf, 0x13, 0xc0, 0x2e, 0xc0, 0x4a, 0xc0, 0x65, 0xc0, 0x81, 0xc0, + 0x9c, 0xc0, 0xb7, 0xc0, 0xd3, 0xc0, 0xee, 0xc0, 0x0a, 0xc1, 0x25, 0xc1, + 0x40, 0xc1, 0x5c, 0xc1, 0x77, 0xc1, 0x92, 0xc1, 0xae, 0xc1, 0xc9, 0xc1, + 0xe4, 0xc1, 0x00, 0xc2, 0x1b, 0xc2, 0x36, 0xc2, 0x51, 0xc2, 0x6d, 0xc2, + 0x88, 0xc2, 0xa3, 0xc2, 0xbf, 0xc2, 0xda, 0xc2, 0xf5, 0xc2, 0x10, 0xc3, + 0x2b, 0xc3, 0x47, 0xc3, 0x62, 0xc3, 0x7d, 0xc3, 0x98, 0xc3, 0xb3, 0xc3, + 0xcf, 0xc3, 0xea, 0xc3, 0x05, 0xc4, 0x20, 0xc4, 0x3b, 0xc4, 0x56, 0xc4, + 0x71, 0xc4, 0x8d, 0xc4, 0xa8, 0xc4, 0xc3, 0xc4, 0xde, 0xc4, 0xf9, 0xc4, + 0x14, 0xc5, 0x2f, 0xc5, 0x4a, 0xc5, 0x65, 0xc5, 0x80, 0xc5, 0x9b, 0xc5, + 0xb6, 0xc5, 0xd1, 0xc5, 0xec, 0xc5, 0x07, 0xc6, 0x22, 0xc6, 0x3d, 0xc6, + 0x58, 0xc6, 0x73, 0xc6, 0x8e, 0xc6, 0xa9, 0xc6, 0xc4, 0xc6, 0xdf, 0xc6, + 0xfa, 0xc6, 0x15, 0xc7, 0x30, 0xc7, 0x4b, 0xc7, 0x66, 0xc7, 0x81, 0xc7, + 0x9c, 0xc7, 0xb7, 0xc7, 0xd1, 0xc7, 0xec, 0xc7, 0x07, 0xc8, 0x22, 0xc8, + 0x3d, 0xc8, 0x58, 0xc8, 0x73, 0xc8, 0x8d, 0xc8, 0xa8, 0xc8, 0xc3, 0xc8, + 0xde, 0xc8, 0xf9, 0xc8, 0x13, 0xc9, 0x2e, 0xc9, 0x49, 0xc9, 0x64, 0xc9, + 0x7e, 0xc9, 0x99, 0xc9, 0xb4, 0xc9, 0xcf, 0xc9, 0xe9, 0xc9, 0x04, 0xca, + 0x1f, 0xca, 0x3a, 0xca, 0x54, 0xca, 0x6f, 0xca, 0x8a, 0xca, 0xa4, 0xca, + 0xbf, 0xca, 0xda, 0xca, 0xf4, 0xca, 0x0f, 0xcb, 0x2a, 0xcb, 0x44, 0xcb, + 0x5f, 0xcb, 0x79, 0xcb, 0x94, 0xcb, 0xaf, 0xcb, 0xc9, 0xcb, 0xe4, 0xcb, + 0xfe, 0xcb, 0x19, 0xcc, 0x34, 0xcc, 0x4e, 0xcc, 0x69, 0xcc, 0x83, 0xcc, + 0x9e, 0xcc, 0xb8, 0xcc, 0xd3, 0xcc, 0xed, 0xcc, 0x08, 0xcd, 0x22, 0xcd, + 0x3d, 0xcd, 0x57, 0xcd, 0x72, 0xcd, 0x8c, 0xcd, 0xa7, 0xcd, 0xc1, 0xcd, + 0xdc, 0xcd, 0xf6, 0xcd, 0x10, 0xce, 0x2b, 0xce, 0x45, 0xce, 0x60, 0xce, + 0x7a, 0xce, 0x94, 0xce, 0xaf, 0xce, 0xc9, 0xce, 0xe4, 0xce, 0xfe, 0xce, + 0x18, 0xcf, 0x33, 0xcf, 0x4d, 0xcf, 0x67, 0xcf, 0x82, 0xcf, 0x9c, 0xcf, + 0xb6, 0xcf, 0xd1, 0xcf, 0xeb, 0xcf, 0x05, 0xd0, 0x1f, 0xd0, 0x3a, 0xd0, + 0x54, 0xd0, 0x6e, 0xd0, 0x88, 0xd0, 0xa3, 0xd0, 0xbd, 0xd0, 0xd7, 0xd0, + 0xf1, 0xd0, 0x0c, 0xd1, 0x26, 0xd1, 0x40, 0xd1, 0x5a, 0xd1, 0x74, 0xd1, + 0x8f, 0xd1, 0xa9, 0xd1, 0xc3, 0xd1, 0xdd, 0xd1, 0xf7, 0xd1, 0x11, 0xd2, + 0x2c, 0xd2, 0x46, 0xd2, 0x60, 0xd2, 0x7a, 0xd2, 0x94, 0xd2, 0xae, 0xd2, + 0xc8, 0xd2, 0xe2, 0xd2, 0xfc, 0xd2, 0x16, 0xd3, 0x30, 0xd3, 0x4b, 0xd3, + 0x65, 0xd3, 0x7f, 0xd3, 0x99, 0xd3, 0xb3, 0xd3, 0xcd, 0xd3, 0xe7, 0xd3, + 0x01, 0xd4, 0x1b, 0xd4, 0x35, 0xd4, 0x4f, 0xd4, 0x69, 0xd4, 0x83, 0xd4, + 0x9d, 0xd4, 0xb7, 0xd4, 0xd1, 0xd4, 0xea, 0xd4, 0x04, 0xd5, 0x1e, 0xd5, + 0x38, 0xd5, 0x52, 0xd5, 0x6c, 0xd5, 0x86, 0xd5, 0xa0, 0xd5, 0xba, 0xd5, + 0xd4, 0xd5, 0xee, 0xd5, 0x07, 0xd6, 0x21, 0xd6, 0x3b, 0xd6, 0x55, 0xd6, + 0x6f, 0xd6, 0x89, 0xd6, 0xa2, 0xd6, 0xbc, 0xd6, 0xd6, 0xd6, 0xf0, 0xd6, + 0x0a, 0xd7, 0x23, 0xd7, 0x3d, 0xd7, 0x57, 0xd7, 0x71, 0xd7, 0x8b, 0xd7, + 0xa4, 0xd7, 0xbe, 0xd7, 0xd8, 0xd7, 0xf1, 0xd7, 0x0b, 0xd8, 0x25, 0xd8, + 0x3f, 0xd8, 0x58, 0xd8, 0x72, 0xd8, 0x8c, 0xd8, 0xa5, 0xd8, 0xbf, 0xd8, + 0xd9, 0xd8, 0xf2, 0xd8, 0x0c, 0xd9, 0x26, 0xd9, 0x3f, 0xd9, 0x59, 0xd9, + 0x73, 0xd9, 0x8c, 0xd9, 0xa6, 0xd9, 0xbf, 0xd9, 0xd9, 0xd9, 0xf3, 0xd9, + 0x0c, 0xda, 0x26, 0xda, 0x3f, 0xda, 0x59, 0xda, 0x72, 0xda, 0x8c, 0xda, + 0xa6, 0xda, 0xbf, 0xda, 0xd9, 0xda, 0xf2, 0xda, 0x0c, 0xdb, 0x25, 0xdb, + 0x3f, 0xdb, 0x58, 0xdb, 0x72, 0xdb, 0x8b, 0xdb, 0xa5, 0xdb, 0xbe, 0xdb, + 0xd8, 0xdb, 0xf1, 0xdb, 0x0a, 0xdc, 0x24, 0xdc, 0x3d, 0xdc, 0x57, 0xdc, + 0x70, 0xdc, 0x8a, 0xdc, 0xa3, 0xdc, 0xbc, 0xdc, 0xd6, 0xdc, 0xef, 0xdc, + 0x09, 0xdd, 0x22, 0xdd, 0x3b, 0xdd, 0x55, 0xdd, 0x6e, 0xdd, 0x87, 0xdd, + 0xa1, 0xdd, 0xba, 0xdd, 0xd3, 0xdd, 0xed, 0xdd, 0x06, 0xde, 0x1f, 0xde, + 0x39, 0xde, 0x52, 0xde, 0x6b, 0xde, 0x84, 0xde, 0x9e, 0xde, 0xb7, 0xde, + 0xd0, 0xde, 0xe9, 0xde, 0x03, 0xdf, 0x1c, 0xdf, 0x35, 0xdf, 0x4e, 0xdf, + 0x68, 0xdf, 0x81, 0xdf, 0x9a, 0xdf, 0xb3, 0xdf, 0xcc, 0xdf, 0xe6, 0xdf, + 0xff, 0xdf, 0x18, 0xe0, 0x31, 0xe0, 0x4a, 0xe0, 0x63, 0xe0, 0x7d, 0xe0, + 0x96, 0xe0, 0xaf, 0xe0, 0xc8, 0xe0, 0xe1, 0xe0, 0xfa, 0xe0, 0x13, 0xe1, + 0x2c, 0xe1, 0x45, 0xe1, 0x5f, 0xe1, 0x78, 0xe1, 0x91, 0xe1, 0xaa, 0xe1, + 0xc3, 0xe1, 0xdc, 0xe1, 0xf5, 0xe1, 0x0e, 0xe2, 0x27, 0xe2, 0x40, 0xe2, + 0x59, 0xe2, 0x72, 0xe2, 0x8b, 0xe2, 0xa4, 0xe2, 0xbd, 0xe2, 0xd6, 0xe2, + 0xef, 0xe2, 0x08, 0xe3, 0x21, 0xe3, 0x3a, 0xe3, 0x53, 0xe3, 0x6c, 0xe3, + 0x85, 0xe3, 0x9e, 0xe3, 0xb7, 0xe3, 0xcf, 0xe3, 0xe8, 0xe3, 0x01, 0xe4, + 0x1a, 0xe4, 0x33, 0xe4, 0x4c, 0xe4, 0x65, 0xe4, 0x7e, 0xe4, 0x97, 0xe4, + 0xaf, 0xe4, 0xc8, 0xe4, 0xe1, 0xe4, 0xfa, 0xe4, 0x13, 0xe5, 0x2c, 0xe5, + 0x44, 0xe5, 0x5d, 0xe5, 0x76, 0xe5, 0x8f, 0xe5, 0xa8, 0xe5, 0xc0, 0xe5, + 0xd9, 0xe5, 0xf2, 0xe5, 0x0b, 0xe6, 0x24, 0xe6, 0x3c, 0xe6, 0x55, 0xe6, + 0x6e, 0xe6, 0x86, 0xe6, 0x9f, 0xe6, 0xb8, 0xe6, 0xd1, 0xe6, 0xe9, 0xe6, + 0x02, 0xe7, 0x1b, 0xe7, 0x33, 0xe7, 0x4c, 0xe7, 0x65, 0xe7, 0x7d, 0xe7, + 0x96, 0xe7, 0xaf, 0xe7, 0xc7, 0xe7, 0xe0, 0xe7, 0xf9, 0xe7, 0x11, 0xe8, + 0x2a, 0xe8, 0x43, 0xe8, 0x5b, 0xe8, 0x74, 0xe8, 0x8c, 0xe8, 0xa5, 0xe8, + 0xbe, 0xe8, 0xd6, 0xe8, 0xef, 0xe8, 0x07, 0xe9, 0x20, 0xe9, 0x38, 0xe9, + 0x51, 0xe9, 0x6a, 0xe9, 0x82, 0xe9, 0x9b, 0xe9, 0xb3, 0xe9, 0xcc, 0xe9, + 0xe4, 0xe9, 0xfd, 0xe9, 0x15, 0xea, 0x2e, 0xea, 0x46, 0xea, 0x5f, 0xea, + 0x77, 0xea, 0x90, 0xea, 0xa8, 0xea, 0xc0, 0xea, 0xd9, 0xea, 0xf1, 0xea, + 0x0a, 0xeb, 0x22, 0xeb, 0x3b, 0xeb, 0x53, 0xeb, 0x6b, 0xeb, 0x84, 0xeb, + 0x9c, 0xeb, 0xb5, 0xeb, 0xcd, 0xeb, 0xe5, 0xeb, 0xfe, 0xeb, 0x16, 0xec, + 0x2e, 0xec, 0x47, 0xec, 0x5f, 0xec, 0x78, 0xec, 0x90, 0xec, 0xa8, 0xec, + 0xc1, 0xec, 0xd9, 0xec, 0xf1, 0xec, 0x09, 0xed, 0x22, 0xed, 0x3a, 0xed, + 0x52, 0xed, 0x6b, 0xed, 0x83, 0xed, 0x9b, 0xed, 0xb3, 0xed, 0xcc, 0xed, + 0xe4, 0xed, 0xfc, 0xed, 0x14, 0xee, 0x2d, 0xee, 0x45, 0xee, 0x5d, 0xee, + 0x75, 0xee, 0x8d, 0xee, 0xa6, 0xee, 0xbe, 0xee, 0xd6, 0xee, 0xee, 0xee, + 0x06, 0xef, 0x1f, 0xef, 0x37, 0xef, 0x4f, 0xef, 0x67, 0xef, 0x7f, 0xef, + 0x97, 0xef, 0xaf, 0xef, 0xc8, 0xef, 0xe0, 0xef, 0xf8, 0xef, 0x10, 0xf0, + 0x28, 0xf0, 0x40, 0xf0, 0x58, 0xf0, 0x70, 0xf0, 0x88, 0xf0, 0xa0, 0xf0, + 0xb8, 0xf0, 0xd0, 0xf0, 0xe8, 0xf0, 0x01, 0xf1, 0x19, 0xf1, 0x31, 0xf1, + 0x49, 0xf1, 0x61, 0xf1, 0x79, 0xf1, 0x91, 0xf1, 0xa9, 0xf1, 0xc1, 0xf1, + 0xd9, 0xf1, 0xf1, 0xf1, 0x09, 0xf2, 0x21, 0xf2, 0x39, 0xf2, 0x50, 0xf2, + 0x68, 0xf2, 0x80, 0xf2, 0x98, 0xf2, 0xb0, 0xf2, 0xc8, 0xf2, 0xe0, 0xf2, + 0xf8, 0xf2, 0x10, 0xf3, 0x28, 0xf3, 0x40, 0xf3, 0x58, 0xf3, 0x70, 0xf3, + 0x87, 0xf3, 0x9f, 0xf3, 0xb7, 0xf3, 0xcf, 0xf3, 0xe7, 0xf3, 0xff, 0xf3, + 0x17, 0xf4, 0x2e, 0xf4, 0x46, 0xf4, 0x5e, 0xf4, 0x76, 0xf4, 0x8e, 0xf4, + 0xa5, 0xf4, 0xbd, 0xf4, 0xd5, 0xf4, 0xed, 0xf4, 0x05, 0xf5, 0x1c, 0xf5, + 0x34, 0xf5, 0x4c, 0xf5, 0x64, 0xf5, 0x7b, 0xf5, 0x93, 0xf5, 0xab, 0xf5, + 0xc3, 0xf5, 0xda, 0xf5, 0xf2, 0xf5, 0x0a, 0xf6, 0x22, 0xf6, 0x39, 0xf6, + 0x51, 0xf6, 0x69, 0xf6, 0x80, 0xf6, 0x98, 0xf6, 0xb0, 0xf6, 0xc7, 0xf6, + 0xdf, 0xf6, 0xf7, 0xf6, 0x0e, 0xf7, 0x26, 0xf7, 0x3e, 0xf7, 0x55, 0xf7, + 0x6d, 0xf7, 0x85, 0xf7, 0x9c, 0xf7, 0xb4, 0xf7, 0xcb, 0xf7, 0xe3, 0xf7, + 0xfb, 0xf7, 0x12, 0xf8, 0x2a, 0xf8, 0x41, 0xf8, 0x59, 0xf8, 0x70, 0xf8, + 0x88, 0xf8, 0xa0, 0xf8, 0xb7, 0xf8, 0xcf, 0xf8, 0xe6, 0xf8, 0xfe, 0xf8, + 0x15, 0xf9, 0x2d, 0xf9, 0x44, 0xf9, 0x5c, 0xf9, 0x73, 0xf9, 0x8b, 0xf9, + 0xa2, 0xf9, 0xba, 0xf9, 0xd1, 0xf9, 0xe9, 0xf9, 0x00, 0xfa, 0x18, 0xfa, + 0x2f, 0xfa, 0x46, 0xfa, 0x5e, 0xfa, 0x75, 0xfa, 0x8d, 0xfa, 0xa4, 0xfa, + 0xbc, 0xfa, 0xd3, 0xfa, 0xea, 0xfa, 0x02, 0xfb, 0x19, 0xfb, 0x31, 0xfb, + 0x48, 0xfb, 0x5f, 0xfb, 0x77, 0xfb, 0x8e, 0xfb, 0xa5, 0xfb, 0xbd, 0xfb, + 0xd4, 0xfb, 0xec, 0xfb, 0x03, 0xfc, 0x1a, 0xfc, 0x32, 0xfc, 0x49, 0xfc, + 0x60, 0xfc, 0x77, 0xfc, 0x8f, 0xfc, 0xa6, 0xfc, 0xbd, 0xfc, 0xd5, 0xfc, + 0xec, 0xfc, 0x03, 0xfd, 0x1a, 0xfd, 0x32, 0xfd, 0x49, 0xfd, 0x60, 0xfd, + 0x77, 0xfd, 0x8f, 0xfd, 0xa6, 0xfd, 0xbd, 0xfd, 0xd4, 0xfd, 0xec, 0xfd, + 0x03, 0xfe, 0x1a, 0xfe, 0x31, 0xfe, 0x48, 0xfe, 0x60, 0xfe, 0x77, 0xfe, + 0x8e, 0xfe, 0xa5, 0xfe, 0xbc, 0xfe, 0xd3, 0xfe, 0xeb, 0xfe, 0x02, 0xff, + 0x19, 0xff, 0x30, 0xff, 0x47, 0xff, 0x5e, 0xff, 0x75, 0xff, 0x8d, 0xff, + 0xa4, 0xff, 0xbb, 0xff, 0xd2, 0xff, 0xe9, 0xff, 0x00, 0x00, 0x16, 0x00, + 0x2c, 0x00, 0x43, 0x00, 0x59, 0x00, 0x6f, 0x00, 0x85, 0x00, 0x9b, 0x00, + 0xb2, 0x00, 0xc8, 0x00, 0xde, 0x00, 0xf4, 0x00, 0x0b, 0x01, 0x21, 0x01, + 0x37, 0x01, 0x4e, 0x01, 0x64, 0x01, 0x7a, 0x01, 0x90, 0x01, 0xa7, 0x01, + 0xbd, 0x01, 0xd3, 0x01, 0xea, 0x01, 0x00, 0x02, 0x17, 0x02, 0x2d, 0x02, + 0x43, 0x02, 0x5a, 0x02, 0x70, 0x02, 0x86, 0x02, 0x9d, 0x02, 0xb3, 0x02, + 0xca, 0x02, 0xe0, 0x02, 0xf6, 0x02, 0x0d, 0x03, 0x23, 0x03, 0x3a, 0x03, + 0x50, 0x03, 0x67, 0x03, 0x7d, 0x03, 0x94, 0x03, 0xaa, 0x03, 0xc1, 0x03, + 0xd7, 0x03, 0xee, 0x03, 0x04, 0x04, 0x1b, 0x04, 0x31, 0x04, 0x48, 0x04, + 0x5e, 0x04, 0x75, 0x04, 0x8c, 0x04, 0xa2, 0x04, 0xb9, 0x04, 0xcf, 0x04, + 0xe6, 0x04, 0xfd, 0x04, 0x13, 0x05, 0x2a, 0x05, 0x40, 0x05, 0x57, 0x05, + 0x6e, 0x05, 0x84, 0x05, 0x9b, 0x05, 0xb2, 0x05, 0xc8, 0x05, 0xdf, 0x05, + 0xf6, 0x05, 0x0c, 0x06, 0x23, 0x06, 0x3a, 0x06, 0x51, 0x06, 0x67, 0x06, + 0x7e, 0x06, 0x95, 0x06, 0xac, 0x06, 0xc2, 0x06, 0xd9, 0x06, 0xf0, 0x06, + 0x07, 0x07, 0x1d, 0x07, 0x34, 0x07, 0x4b, 0x07, 0x62, 0x07, 0x79, 0x07, + 0x90, 0x07, 0xa6, 0x07, 0xbd, 0x07, 0xd4, 0x07, 0xeb, 0x07, 0x02, 0x08, + 0x19, 0x08, 0x30, 0x08, 0x47, 0x08, 0x5d, 0x08, 0x74, 0x08, 0x8b, 0x08, + 0xa2, 0x08, 0xb9, 0x08, 0xd0, 0x08, 0xe7, 0x08, 0xfe, 0x08, 0x15, 0x09, + 0x2c, 0x09, 0x43, 0x09, 0x5a, 0x09, 0x71, 0x09, 0x88, 0x09, 0x9f, 0x09, + 0xb6, 0x09, 0xcd, 0x09, 0xe4, 0x09, 0xfb, 0x09, 0x12, 0x0a, 0x29, 0x0a, + 0x40, 0x0a, 0x57, 0x0a, 0x6e, 0x0a, 0x85, 0x0a, 0x9c, 0x0a, 0xb4, 0x0a, + 0xcb, 0x0a, 0xe2, 0x0a, 0xf9, 0x0a, 0x10, 0x0b, 0x27, 0x0b, 0x3e, 0x0b, + 0x56, 0x0b, 0x6d, 0x0b, 0x84, 0x0b, 0x9b, 0x0b, 0xb2, 0x0b, 0xc9, 0x0b, + 0xe1, 0x0b, 0xf8, 0x0b, 0x0f, 0x0c, 0x26, 0x0c, 0x3e, 0x0c, 0x55, 0x0c, + 0x6c, 0x0c, 0x83, 0x0c, 0x9b, 0x0c, 0xb2, 0x0c, 0xc9, 0x0c, 0xe0, 0x0c, + 0xf8, 0x0c, 0x0f, 0x0d, 0x26, 0x0d, 0x3e, 0x0d, 0x55, 0x0d, 0x6c, 0x0d, + 0x84, 0x0d, 0x9b, 0x0d, 0xb2, 0x0d, 0xca, 0x0d, 0xe1, 0x0d, 0xf9, 0x0d, + 0x10, 0x0e, 0x27, 0x0e, 0x3f, 0x0e, 0x56, 0x0e, 0x6e, 0x0e, 0x85, 0x0e, + 0x9c, 0x0e, 0xb4, 0x0e, 0xcb, 0x0e, 0xe3, 0x0e, 0xfa, 0x0e, 0x12, 0x0f, + 0x29, 0x0f, 0x41, 0x0f, 0x58, 0x0f, 0x70, 0x0f, 0x87, 0x0f, 0x9f, 0x0f, + 0xb6, 0x0f, 0xce, 0x0f, 0xe6, 0x0f, 0xfd, 0x0f, 0x15, 0x10, 0x2c, 0x10, + 0x44, 0x10, 0x5b, 0x10, 0x73, 0x10, 0x8b, 0x10, 0xa2, 0x10, 0xba, 0x10, + 0xd1, 0x10, 0xe9, 0x10, 0x01, 0x11, 0x18, 0x11, 0x30, 0x11, 0x48, 0x11, + 0x5f, 0x11, 0x77, 0x11, 0x8f, 0x11, 0xa7, 0x11, 0xbe, 0x11, 0xd6, 0x11, + 0xee, 0x11, 0x05, 0x12, 0x1d, 0x12, 0x35, 0x12, 0x4d, 0x12, 0x65, 0x12, + 0x7c, 0x12, 0x94, 0x12, 0xac, 0x12, 0xc4, 0x12, 0xdb, 0x12, 0xf3, 0x12, + 0x0b, 0x13, 0x23, 0x13, 0x3b, 0x13, 0x53, 0x13, 0x6b, 0x13, 0x82, 0x13, + 0x9a, 0x13, 0xb2, 0x13, 0xca, 0x13, 0xe2, 0x13, 0xfa, 0x13, 0x12, 0x14, + 0x2a, 0x14, 0x42, 0x14, 0x5a, 0x14, 0x71, 0x14, 0x89, 0x14, 0xa1, 0x14, + 0xb9, 0x14, 0xd1, 0x14, 0xe9, 0x14, 0x01, 0x15, 0x19, 0x15, 0x31, 0x15, + 0x49, 0x15, 0x61, 0x15, 0x79, 0x15, 0x91, 0x15, 0xaa, 0x15, 0xc2, 0x15, + 0xda, 0x15, 0xf2, 0x15, 0x0a, 0x16, 0x22, 0x16, 0x3a, 0x16, 0x52, 0x16, + 0x6a, 0x16, 0x82, 0x16, 0x9b, 0x16, 0xb3, 0x16, 0xcb, 0x16, 0xe3, 0x16, + 0xfb, 0x16, 0x13, 0x17, 0x2c, 0x17, 0x44, 0x17, 0x5c, 0x17, 0x74, 0x17, + 0x8c, 0x17, 0xa5, 0x17, 0xbd, 0x17, 0xd5, 0x17, 0xed, 0x17, 0x06, 0x18, + 0x1e, 0x18, 0x36, 0x18, 0x4e, 0x18, 0x67, 0x18, 0x7f, 0x18, 0x97, 0x18, + 0xb0, 0x18, 0xc8, 0x18, 0xe0, 0x18, 0xf9, 0x18, 0x11, 0x19, 0x29, 0x19, + 0x42, 0x19, 0x5a, 0x19, 0x72, 0x19, 0x8b, 0x19, 0xa3, 0x19, 0xbc, 0x19, + 0xd4, 0x19, 0xec, 0x19, 0x05, 0x1a, 0x1d, 0x1a, 0x36, 0x1a, 0x4e, 0x1a, + 0x67, 0x1a, 0x7f, 0x1a, 0x98, 0x1a, 0xb0, 0x1a, 0xc9, 0x1a, 0xe1, 0x1a, + 0xfa, 0x1a, 0x12, 0x1b, 0x2b, 0x1b, 0x43, 0x1b, 0x5c, 0x1b, 0x74, 0x1b, + 0x8d, 0x1b, 0xa5, 0x1b, 0xbe, 0x1b, 0xd7, 0x1b, 0xef, 0x1b, 0x08, 0x1c, + 0x20, 0x1c, 0x39, 0x1c, 0x52, 0x1c, 0x6a, 0x1c, 0x83, 0x1c, 0x9c, 0x1c, + 0xb4, 0x1c, 0xcd, 0x1c, 0xe6, 0x1c, 0xfe, 0x1c, 0x17, 0x1d, 0x30, 0x1d, + 0x48, 0x1d, 0x61, 0x1d, 0x7a, 0x1d, 0x93, 0x1d, 0xab, 0x1d, 0xc4, 0x1d, + 0xdd, 0x1d, 0xf6, 0x1d, 0x0e, 0x1e, 0x27, 0x1e, 0x40, 0x1e, 0x59, 0x1e, + 0x72, 0x1e, 0x8a, 0x1e, 0xa3, 0x1e, 0xbc, 0x1e, 0xd5, 0x1e, 0xee, 0x1e, + 0x07, 0x1f, 0x20, 0x1f, 0x38, 0x1f, 0x51, 0x1f, 0x6a, 0x1f, 0x83, 0x1f, + 0x9c, 0x1f, 0xb5, 0x1f, 0xce, 0x1f, 0xe7, 0x1f, 0x00, 0x20, 0x19, 0x20, + 0x32, 0x20, 0x4b, 0x20, 0x64, 0x20, 0x7d, 0x20, 0x96, 0x20, 0xaf, 0x20, + 0xc8, 0x20, 0xe1, 0x20, 0xfa, 0x20, 0x13, 0x21, 0x2c, 0x21, 0x45, 0x21, + 0x5e, 0x21, 0x77, 0x21, 0x90, 0x21, 0xa9, 0x21, 0xc2, 0x21, 0xdb, 0x21, + 0xf5, 0x21, 0x0e, 0x22, 0x27, 0x22, 0x40, 0x22, 0x59, 0x22, 0x72, 0x22, + 0x8b, 0x22, 0xa5, 0x22, 0xbe, 0x22, 0xd7, 0x22, 0xf0, 0x22, 0x09, 0x23, + 0x23, 0x23, 0x3c, 0x23, 0x55, 0x23, 0x6e, 0x23, 0x88, 0x23, 0xa1, 0x23, + 0xba, 0x23, 0xd3, 0x23, 0xed, 0x23, 0x06, 0x24, 0x1f, 0x24, 0x39, 0x24, + 0x52, 0x24, 0x6b, 0x24, 0x85, 0x24, 0x9e, 0x24, 0xb7, 0x24, 0xd1, 0x24, + 0xea, 0x24, 0x04, 0x25, 0x1d, 0x25, 0x36, 0x25, 0x50, 0x25, 0x69, 0x25, + 0x83, 0x25, 0x9c, 0x25, 0xb5, 0x25, 0xcf, 0x25, 0xe8, 0x25, 0x02, 0x26, + 0x1b, 0x26, 0x35, 0x26, 0x4e, 0x26, 0x68, 0x26, 0x81, 0x26, 0x9b, 0x26, + 0xb4, 0x26, 0xce, 0x26, 0xe7, 0x26, 0x01, 0x27, 0x1b, 0x27, 0x34, 0x27, + 0x4e, 0x27, 0x67, 0x27, 0x81, 0x27, 0x9a, 0x27, 0xb4, 0x27, 0xce, 0x27, + 0xe7, 0x27, 0x01, 0x28, 0x1b, 0x28, 0x34, 0x28, 0x4e, 0x28, 0x68, 0x28, + 0x81, 0x28, 0x9b, 0x28, 0xb5, 0x28, 0xce, 0x28, 0xe8, 0x28, 0x02, 0x29, + 0x1c, 0x29, 0x35, 0x29, 0x4f, 0x29, 0x69, 0x29, 0x83, 0x29, 0x9c, 0x29, + 0xb6, 0x29, 0xd0, 0x29, 0xea, 0x29, 0x04, 0x2a, 0x1e, 0x2a, 0x37, 0x2a, + 0x51, 0x2a, 0x6b, 0x2a, 0x85, 0x2a, 0x9f, 0x2a, 0xb9, 0x2a, 0xd3, 0x2a, + 0xec, 0x2a, 0x06, 0x2b, 0x20, 0x2b, 0x3a, 0x2b, 0x54, 0x2b, 0x6e, 0x2b, + 0x88, 0x2b, 0xa2, 0x2b, 0xbc, 0x2b, 0xd6, 0x2b, 0xf0, 0x2b, 0x0a, 0x2c, + 0x24, 0x2c, 0x3e, 0x2c, 0x58, 0x2c, 0x72, 0x2c, 0x8c, 0x2c, 0xa6, 0x2c, + 0xc0, 0x2c, 0xda, 0x2c, 0xf4, 0x2c, 0x0e, 0x2d, 0x28, 0x2d, 0x42, 0x2d, + 0x5d, 0x2d, 0x77, 0x2d, 0x91, 0x2d, 0xab, 0x2d, 0xc5, 0x2d, 0xdf, 0x2d, + 0xf9, 0x2d, 0x14, 0x2e, 0x2e, 0x2e, 0x48, 0x2e, 0x62, 0x2e, 0x7c, 0x2e, + 0x97, 0x2e, 0xb1, 0x2e, 0xcb, 0x2e, 0xe5, 0x2e, 0xff, 0x2e, 0x1a, 0x2f, + 0x34, 0x2f, 0x4e, 0x2f, 0x69, 0x2f, 0x83, 0x2f, 0x9d, 0x2f, 0xb7, 0x2f, + 0xd2, 0x2f, 0xec, 0x2f, 0x06, 0x30, 0x21, 0x30, 0x3b, 0x30, 0x56, 0x30, + 0x70, 0x30, 0x8a, 0x30, 0xa5, 0x30, 0xbf, 0x30, 0xd9, 0x30, 0xf4, 0x30, + 0x0e, 0x31, 0x29, 0x31, 0x43, 0x31, 0x5e, 0x31, 0x78, 0x31, 0x93, 0x31, + 0xad, 0x31, 0xc8, 0x31, 0xe2, 0x31, 0xfd, 0x31, 0x17, 0x32, 0x32, 0x32, + 0x4c, 0x32, 0x67, 0x32, 0x81, 0x32, 0x9c, 0x32, 0xb6, 0x32, 0xd1, 0x32, + 0xec, 0x32, 0x06, 0x33, 0x21, 0x33, 0x3b, 0x33, 0x56, 0x33, 0x71, 0x33, + 0x8b, 0x33, 0xa6, 0x33, 0xc1, 0x33, 0xdb, 0x33, 0xf6, 0x33, 0x11, 0x34, + 0x2b, 0x34, 0x46, 0x34, 0x61, 0x34, 0x7b, 0x34, 0x96, 0x34, 0xb1, 0x34, + 0xcc, 0x34, 0xe6, 0x34, 0x01, 0x35, 0x1c, 0x35, 0x37, 0x35, 0x52, 0x35, + 0x6c, 0x35, 0x87, 0x35, 0xa2, 0x35, 0xbd, 0x35, 0xd8, 0x35, 0xf2, 0x35, + 0x0d, 0x36, 0x28, 0x36, 0x43, 0x36, 0x5e, 0x36, 0x79, 0x36, 0x94, 0x36, + 0xaf, 0x36, 0xca, 0x36, 0xe5, 0x36, 0x00, 0x37, 0x1a, 0x37, 0x35, 0x37, + 0x50, 0x37, 0x6b, 0x37, 0x86, 0x37, 0xa1, 0x37, 0xbc, 0x37, 0xd7, 0x37, + 0xf2, 0x37, 0x0d, 0x38, 0x28, 0x38, 0x44, 0x38, 0x5f, 0x38, 0x7a, 0x38, + 0x95, 0x38, 0xb0, 0x38, 0xcb, 0x38, 0xe6, 0x38, 0x01, 0x39, 0x1c, 0x39, + 0x37, 0x39, 0x53, 0x39, 0x6e, 0x39, 0x89, 0x39, 0xa4, 0x39, 0xbf, 0x39, + 0xda, 0x39, 0xf6, 0x39, 0x11, 0x3a, 0x2c, 0x3a, 0x47, 0x3a, 0x62, 0x3a, + 0x7e, 0x3a, 0x99, 0x3a, 0xb4, 0x3a, 0xcf, 0x3a, 0xeb, 0x3a, 0x06, 0x3b, + 0x21, 0x3b, 0x3d, 0x3b, 0x58, 0x3b, 0x73, 0x3b, 0x8f, 0x3b, 0xaa, 0x3b, + 0xc5, 0x3b, 0xe1, 0x3b, 0xfc, 0x3b, 0x17, 0x3c, 0x33, 0x3c, 0x4e, 0x3c, + 0x6a, 0x3c, 0x85, 0x3c, 0xa1, 0x3c, 0xbc, 0x3c, 0xd7, 0x3c, 0xf3, 0x3c, + 0x0e, 0x3d, 0x2a, 0x3d, 0x45, 0x3d, 0x61, 0x3d, 0x7c, 0x3d, 0x98, 0x3d, + 0xb3, 0x3d, 0xcf, 0x3d, 0xea, 0x3d, 0x06, 0x3e, 0x22, 0x3e, 0x3d, 0x3e, + 0x59, 0x3e, 0x74, 0x3e, 0x90, 0x3e, 0xab, 0x3e, 0xc7, 0x3e, 0xe3, 0x3e, + 0xfe, 0x3e, 0x1a, 0x3f, 0x36, 0x3f, 0x51, 0x3f, 0x6d, 0x3f, 0x89, 0x3f, + 0xa4, 0x3f, 0xc0, 0x3f, 0xdc, 0x3f, 0xf7, 0x3f, 0x13, 0x40, 0x2f, 0x40, + 0x4b, 0x40, 0x66, 0x40, 0x82, 0x40, 0x9e, 0x40, 0xba, 0x40, 0xd6, 0x40, + 0xf1, 0x40, 0x0d, 0x41, 0x29, 0x41, 0x45, 0x41, 0x61, 0x41, 0x7c, 0x41, + 0x98, 0x41, 0xb4, 0x41, 0xd0, 0x41, 0xec, 0x41, 0x08, 0x42, 0x24, 0x42, + 0x40, 0x42, 0x5c, 0x42, 0x78, 0x42, 0x94, 0x42, 0xaf, 0x42, 0xcb, 0x42, + 0xe7, 0x42, 0x03, 0x43, 0x1f, 0x43, 0x3b, 0x43, 0x57, 0x43, 0x73, 0x43, + 0x8f, 0x43, 0xab, 0x43, 0xc8, 0x43, 0xe4, 0x43, 0x00, 0x44, 0x1c, 0x44, + 0x38, 0x44, 0x54, 0x44, 0x70, 0x44, 0x8c, 0x44, 0xa8, 0x44, 0xc4, 0x44, + 0xe1, 0x44, 0xfd, 0x44, 0x19, 0x45, 0x35, 0x45, 0x51, 0x45, 0x6d, 0x45, + 0x8a, 0x45, 0xa6, 0x45, 0xc2, 0x45, 0xde, 0x45, 0xfa, 0x45, 0x17, 0x46, + 0x33, 0x46, 0x4f, 0x46, 0x6c, 0x46, 0x88, 0x46, 0xa4, 0x46, 0xc0, 0x46, + 0xdd, 0x46, 0xf9, 0x46, 0x15, 0x47, 0x32, 0x47, 0x4e, 0x47, 0x6a, 0x47, + 0x87, 0x47, 0xa3, 0x47, 0xc0, 0x47, 0xdc, 0x47, 0xf8, 0x47, 0x15, 0x48, + 0x31, 0x48, 0x4e, 0x48, 0x6a, 0x48, 0x87, 0x48, 0xa3, 0x48, 0xc0, 0x48, + 0xdc, 0x48, 0xf9, 0x48, 0x15, 0x49, 0x32, 0x49, 0x4e, 0x49, 0x6b, 0x49, + 0x87, 0x49, 0xa4, 0x49, 0xc0, 0x49, 0xdd, 0x49, 0xf9, 0x49, 0x16, 0x4a, + 0x33, 0x4a, 0x4f, 0x4a, 0x6c, 0x4a, 0x89, 0x4a, 0xa5, 0x4a, 0xc2, 0x4a, + 0xdf, 0x4a, 0xfb, 0x4a, 0x18, 0x4b, 0x35, 0x4b, 0x51, 0x4b, 0x6e, 0x4b, + 0x8b, 0x4b, 0xa7, 0x4b, 0xc4, 0x4b, 0xe1, 0x4b, 0xfe, 0x4b, 0x1a, 0x4c, + 0x37, 0x4c, 0x54, 0x4c, 0x71, 0x4c, 0x8e, 0x4c, 0xaa, 0x4c, 0xc7, 0x4c, + 0xe4, 0x4c, 0x01, 0x4d, 0x1e, 0x4d, 0x3b, 0x4d, 0x58, 0x4d, 0x74, 0x4d, + 0x91, 0x4d, 0xae, 0x4d, 0xcb, 0x4d, 0xe8, 0x4d, 0x05, 0x4e, 0x22, 0x4e, + 0x3f, 0x4e, 0x5c, 0x4e, 0x79, 0x4e, 0x96, 0x4e, 0xb3, 0x4e, 0xd0, 0x4e, + 0xed, 0x4e, 0x0a, 0x4f, 0x27, 0x4f, 0x44, 0x4f, 0x61, 0x4f, 0x7e, 0x4f, + 0x9b, 0x4f, 0xb8, 0x4f, 0xd5, 0x4f, 0xf2, 0x4f, 0x10, 0x50, 0x2d, 0x50, + 0x4a, 0x50, 0x67, 0x50, 0x84, 0x50, 0xa1, 0x50, 0xbe, 0x50, 0xdc, 0x50, + 0xf9, 0x50, 0x16, 0x51, 0x33, 0x51, 0x50, 0x51, 0x6e, 0x51, 0x8b, 0x51, + 0xa8, 0x51, 0xc5, 0x51, 0xe3, 0x51, 0x00, 0x52, 0x1d, 0x52, 0x3b, 0x52, + 0x58, 0x52, 0x75, 0x52, 0x93, 0x52, 0xb0, 0x52, 0xcd, 0x52, 0xeb, 0x52, + 0x08, 0x53, 0x25, 0x53, 0x43, 0x53, 0x60, 0x53, 0x7e, 0x53, 0x9b, 0x53, + 0xb8, 0x53, 0xd6, 0x53, 0xf3, 0x53, 0x11, 0x54, 0x2e, 0x54, 0x4c, 0x54, + 0x69, 0x54, 0x87, 0x54, 0xa4, 0x54, 0xc2, 0x54, 0xdf, 0x54, 0xfd, 0x54, + 0x1a, 0x55, 0x38, 0x55, 0x55, 0x55, 0x73, 0x55, 0x91, 0x55, 0xae, 0x55, + 0xcc, 0x55, 0xe9, 0x55, 0x07, 0x56, 0x25, 0x56, 0x42, 0x56, 0x60, 0x56, + 0x7e, 0x56, 0x9b, 0x56, 0xb9, 0x56, 0xd7, 0x56, 0xf4, 0x56, 0x12, 0x57, + 0x30, 0x57, 0x4e, 0x57, 0x6b, 0x57, 0x89, 0x57, 0xa7, 0x57, 0xc5, 0x57, + 0xe2, 0x57, 0x00, 0x58, 0x1e, 0x58, 0x3c, 0x58, 0x5a, 0x58, 0x78, 0x58, + 0x95, 0x58, 0xb3, 0x58, 0xd1, 0x58, 0xef, 0x58, 0x0d, 0x59, 0x2b, 0x59, + 0x49, 0x59, 0x67, 0x59, 0x85, 0x59, 0xa3, 0x59, 0xc1, 0x59, 0xde, 0x59, + 0xfc, 0x59, 0x1a, 0x5a, 0x38, 0x5a, 0x56, 0x5a, 0x74, 0x5a, 0x92, 0x5a, + 0xb0, 0x5a, 0xcf, 0x5a, 0xed, 0x5a, 0x0b, 0x5b, 0x29, 0x5b, 0x47, 0x5b, + 0x65, 0x5b, 0x83, 0x5b, 0xa1, 0x5b, 0xbf, 0x5b, 0xdd, 0x5b, 0xfc, 0x5b, + 0x1a, 0x5c, 0x38, 0x5c, 0x56, 0x5c, 0x74, 0x5c, 0x92, 0x5c, 0xb1, 0x5c, + 0xcf, 0x5c, 0xed, 0x5c, 0x0b, 0x5d, 0x2a, 0x5d, 0x48, 0x5d, 0x66, 0x5d, + 0x84, 0x5d, 0xa3, 0x5d, 0xc1, 0x5d, 0xdf, 0x5d, 0xfe, 0x5d, 0x1c, 0x5e, + 0x3a, 0x5e, 0x59, 0x5e, 0x77, 0x5e, 0x95, 0x5e, 0xb4, 0x5e, 0xd2, 0x5e, + 0xf0, 0x5e, 0x0f, 0x5f, 0x2d, 0x5f, 0x4c, 0x5f, 0x6a, 0x5f, 0x89, 0x5f, + 0xa7, 0x5f, 0xc6, 0x5f, 0xe4, 0x5f, 0x03, 0x60, 0x21, 0x60, 0x40, 0x60, + 0x5e, 0x60, 0x7d, 0x60, 0x9b, 0x60, 0xba, 0x60, 0xd8, 0x60, 0xf7, 0x60, + 0x15, 0x61, 0x34, 0x61, 0x53, 0x61, 0x71, 0x61, 0x90, 0x61, 0xaf, 0x61, + 0xcd, 0x61, 0xec, 0x61, 0x0b, 0x62, 0x29, 0x62, 0x48, 0x62, 0x67, 0x62, + 0x85, 0x62, 0xa4, 0x62, 0xc3, 0x62, 0xe2, 0x62, 0x00, 0x63, 0x1f, 0x63, + 0x3e, 0x63, 0x5d, 0x63, 0x7b, 0x63, 0x9a, 0x63, 0xb9, 0x63, 0xd8, 0x63, + 0xf7, 0x63, 0x16, 0x64, 0x34, 0x64, 0x53, 0x64, 0x72, 0x64, 0x91, 0x64, + 0xb0, 0x64, 0xcf, 0x64, 0xee, 0x64, 0x0d, 0x65, 0x2c, 0x65, 0x4b, 0x65, + 0x6a, 0x65, 0x89, 0x65, 0xa7, 0x65, 0xc6, 0x65, 0xe5, 0x65, 0x05, 0x66, + 0x24, 0x66, 0x43, 0x66, 0x62, 0x66, 0x81, 0x66, 0xa0, 0x66, 0xbf, 0x66, + 0xde, 0x66, 0xfd, 0x66, 0x1c, 0x67, 0x3b, 0x67, 0x5a, 0x67, 0x7a, 0x67, + 0x99, 0x67, 0xb8, 0x67, 0xd7, 0x67, 0xf6, 0x67, 0x15, 0x68, 0x35, 0x68, + 0x54, 0x68, 0x73, 0x68, 0x92, 0x68, 0xb1, 0x68, 0xd1, 0x68, 0xf0, 0x68, + 0x0f, 0x69, 0x2f, 0x69, 0x4e, 0x69, 0x6d, 0x69, 0x8d, 0x69, 0xac, 0x69, + 0xcb, 0x69, 0xeb, 0x69, 0x0a, 0x6a, 0x29, 0x6a, 0x49, 0x6a, 0x68, 0x6a, + 0x87, 0x6a, 0xa7, 0x6a, 0xc6, 0x6a, 0xe6, 0x6a, 0x05, 0x6b, 0x25, 0x6b, + 0x44, 0x6b, 0x64, 0x6b, 0x83, 0x6b, 0xa3, 0x6b, 0xc2, 0x6b, 0xe2, 0x6b, + 0x01, 0x6c, 0x21, 0x6c, 0x40, 0x6c, 0x60, 0x6c, 0x7f, 0x6c, 0x9f, 0x6c, + 0xbf, 0x6c, 0xde, 0x6c, 0xfe, 0x6c, 0x1d, 0x6d, 0x3d, 0x6d, 0x5d, 0x6d, + 0x7c, 0x6d, 0x9c, 0x6d, 0xbc, 0x6d, 0xdb, 0x6d, 0xfb, 0x6d, 0x1b, 0x6e, + 0x3b, 0x6e, 0x5a, 0x6e, 0x7a, 0x6e, 0x9a, 0x6e, 0xba, 0x6e, 0xd9, 0x6e, + 0xf9, 0x6e, 0x19, 0x6f, 0x39, 0x6f, 0x59, 0x6f, 0x78, 0x6f, 0x98, 0x6f, + 0xb8, 0x6f, 0xd8, 0x6f, 0xf8, 0x6f, 0x18, 0x70, 0x38, 0x70, 0x58, 0x70, + 0x77, 0x70, 0x97, 0x70, 0xb7, 0x70, 0xd7, 0x70, 0xf7, 0x70, 0x17, 0x71, + 0x37, 0x71, 0x57, 0x71, 0x77, 0x71, 0x97, 0x71, 0xb7, 0x71, 0xd7, 0x71, + 0xf7, 0x71, 0x17, 0x72, 0x38, 0x72, 0x58, 0x72, 0x78, 0x72, 0x98, 0x72, + 0xb8, 0x72, 0xd8, 0x72, 0xf8, 0x72, 0x18, 0x73, 0x38, 0x73, 0x59, 0x73, + 0x79, 0x73, 0x99, 0x73, 0xb9, 0x73, 0xd9, 0x73, 0xfa, 0x73, 0x1a, 0x74, + 0x3a, 0x74, 0x5a, 0x74, 0x7b, 0x74, 0x9b, 0x74, 0xbb, 0x74, 0xdc, 0x74, + 0xfc, 0x74, 0x1c, 0x75, 0x3c, 0x75, 0x5d, 0x75, 0x7d, 0x75, 0x9e, 0x75, + 0xbe, 0x75, 0xde, 0x75, 0xff, 0x75, 0x1f, 0x76, 0x40, 0x76, 0x60, 0x76, + 0x80, 0x76, 0xa1, 0x76, 0xc1, 0x76, 0xe2, 0x76, 0x02, 0x77, 0x23, 0x77, + 0x43, 0x77, 0x64, 0x77, 0x84, 0x77, 0xa5, 0x77, 0xc5, 0x77, 0xe6, 0x77, + 0x07, 0x78, 0x27, 0x78, 0x48, 0x78, 0x68, 0x78, 0x89, 0x78, 0xaa, 0x78, + 0xca, 0x78, 0xeb, 0x78, 0x0c, 0x79, 0x2c, 0x79, 0x4d, 0x79, 0x6e, 0x79, + 0x8e, 0x79, 0xaf, 0x79, 0xd0, 0x79, 0xf1, 0x79, 0x11, 0x7a, 0x32, 0x7a, + 0x53, 0x7a, 0x74, 0x7a, 0x94, 0x7a, 0xb5, 0x7a, 0xd6, 0x7a, 0xf7, 0x7a, + 0x18, 0x7b, 0x39, 0x7b, 0x59, 0x7b, 0x7a, 0x7b, 0x9b, 0x7b, 0xbc, 0x7b, + 0xdd, 0x7b, 0xfe, 0x7b, 0x1f, 0x7c, 0x40, 0x7c, 0x61, 0x7c, 0x82, 0x7c, + 0xa3, 0x7c, 0xc4, 0x7c, 0xe5, 0x7c, 0x06, 0x7d, 0x27, 0x7d, 0x48, 0x7d, + 0x69, 0x7d, 0x8a, 0x7d, 0xab, 0x7d, 0xcc, 0x7d, 0xed, 0x7d, 0x0e, 0x7e, + 0x2f, 0x7e, 0x50, 0x7e, 0x71, 0x7e, 0x93, 0x7e, 0xb4, 0x7e, 0xd5, 0x7e, + 0xf6, 0x7e, 0x17, 0x7f, 0x38, 0x7f, 0x5a, 0x7f, 0x7b, 0x7f, 0x9c, 0x7f, + 0xbd, 0x7f, 0xdf, 0x7f, 0x00, 0x80, 0x21, 0x80, 0x42, 0x80, 0x64, 0x80, + 0x85, 0x80, 0xa6, 0x80, 0xc8, 0x80, 0xe9, 0x80, 0x0a, 0x81, 0x2c, 0x81, + 0x4d, 0x81, 0x6f, 0x81, 0x90, 0x81, 0xb1, 0x81, 0xd3, 0x81, 0xf4, 0x81, + 0x16, 0x82, 0x37, 0x82, 0x59, 0x82, 0x7a, 0x82, 0x9c, 0x82, 0xbd, 0x82, + 0xdf, 0x82, 0x00, 0x83, 0x22, 0x83, 0x43, 0x83, 0x65, 0x83, 0x86, 0x83, + 0xa8, 0x83, 0xca, 0x83, 0xeb, 0x83, 0x0d, 0x84, 0x2e, 0x84, 0x50, 0x84, + 0x72, 0x84, 0x93, 0x84, 0xb5, 0x84, 0xd7, 0x84, 0xf8, 0x84, 0x1a, 0x85, + 0x3c, 0x85, 0x5e, 0x85, 0x7f, 0x85, 0xa1, 0x85, 0xc3, 0x85, 0xe5, 0x85, + 0x06, 0x86, 0x28, 0x86, 0x4a, 0x86, 0x6c, 0x86, 0x8e, 0x86, 0xaf, 0x86, + 0xd1, 0x86, 0xf3, 0x86, 0x15, 0x87, 0x37, 0x87, 0x59, 0x87, 0x7b, 0x87, + 0x9d, 0x87, 0xbf, 0x87, 0xe1, 0x87, 0x03, 0x88, 0x24, 0x88, 0x46, 0x88, + 0x68, 0x88, 0x8a, 0x88, 0xac, 0x88, 0xcf, 0x88, 0xf1, 0x88, 0x13, 0x89, + 0x35, 0x89, 0x57, 0x89, 0x79, 0x89, 0x9b, 0x89, 0xbd, 0x89, 0xdf, 0x89, + 0x01, 0x8a, 0x23, 0x8a, 0x46, 0x8a, 0x68, 0x8a, 0x8a, 0x8a, 0xac, 0x8a, + 0xce, 0x8a, 0xf1, 0x8a, 0x13, 0x8b, 0x35, 0x8b, 0x57, 0x8b, 0x7a, 0x8b, + 0x9c, 0x8b, 0xbe, 0x8b, 0xe0, 0x8b, 0x03, 0x8c, 0x25, 0x8c, 0x47, 0x8c, + 0x6a, 0x8c, 0x8c, 0x8c, 0xae, 0x8c, 0xd1, 0x8c, 0xf3, 0x8c, 0x16, 0x8d, + 0x38, 0x8d, 0x5a, 0x8d, 0x7d, 0x8d, 0x9f, 0x8d, 0xc2, 0x8d, 0xe4, 0x8d, + 0x07, 0x8e, 0x29, 0x8e, 0x4c, 0x8e, 0x6e, 0x8e, 0x91, 0x8e, 0xb3, 0x8e, + 0xd6, 0x8e, 0xf8, 0x8e, 0x1b, 0x8f, 0x3d, 0x8f, 0x60, 0x8f, 0x83, 0x8f, + 0xa5, 0x8f, 0xc8, 0x8f, 0xeb, 0x8f, 0x0d, 0x90, 0x30, 0x90, 0x53, 0x90, + 0x75, 0x90, 0x98, 0x90, 0xbb, 0x90, 0xdd, 0x90, 0x00, 0x91, 0x23, 0x91, + 0x46, 0x91, 0x68, 0x91, 0x8b, 0x91, 0xae, 0x91, 0xd1, 0x91, 0xf4, 0x91, + 0x17, 0x92, 0x39, 0x92, 0x5c, 0x92, 0x7f, 0x92, 0xa2, 0x92, 0xc5, 0x92, + 0xe8, 0x92, 0x0b, 0x93, 0x2e, 0x93, 0x51, 0x93, 0x73, 0x93, 0x96, 0x93, + 0xb9, 0x93, 0xdc, 0x93, 0xff, 0x93, 0x22, 0x94, 0x45, 0x94, 0x68, 0x94, + 0x8c, 0x94, 0xaf, 0x94, 0xd2, 0x94, 0xf5, 0x94, 0x18, 0x95, 0x3b, 0x95, + 0x5e, 0x95, 0x81, 0x95, 0xa4, 0x95, 0xc7, 0x95, 0xeb, 0x95, 0x0e, 0x96, + 0x31, 0x96, 0x54, 0x96, 0x77, 0x96, 0x9b, 0x96, 0xbe, 0x96, 0xe1, 0x96, + 0x04, 0x97, 0x28, 0x97, 0x4b, 0x97, 0x6e, 0x97, 0x92, 0x97, 0xb5, 0x97, + 0xd8, 0x97, 0xfc, 0x97, 0x1f, 0x98, 0x42, 0x98, 0x66, 0x98, 0x89, 0x98, + 0xac, 0x98, 0xd0, 0x98, 0xf3, 0x98, 0x17, 0x99, 0x3a, 0x99, 0x5e, 0x99, + 0x81, 0x99, 0xa5, 0x99, 0xc8, 0x99, 0xec, 0x99, 0x0f, 0x9a, 0x33, 0x9a, + 0x56, 0x9a, 0x7a, 0x9a, 0x9d, 0x9a, 0xc1, 0x9a, 0xe4, 0x9a, 0x08, 0x9b, + 0x2c, 0x9b, 0x4f, 0x9b, 0x73, 0x9b, 0x97, 0x9b, 0xba, 0x9b, 0xde, 0x9b, + 0x02, 0x9c, 0x25, 0x9c, 0x49, 0x9c, 0x6d, 0x9c, 0x91, 0x9c, 0xb4, 0x9c, + 0xd8, 0x9c, 0xfc, 0x9c, 0x20, 0x9d, 0x43, 0x9d, 0x67, 0x9d, 0x8b, 0x9d, + 0xaf, 0x9d, 0xd3, 0x9d, 0xf7, 0x9d, 0x1b, 0x9e, 0x3e, 0x9e, 0x62, 0x9e, + 0x86, 0x9e, 0xaa, 0x9e, 0xce, 0x9e, 0xf2, 0x9e, 0x16, 0x9f, 0x3a, 0x9f, + 0x5e, 0x9f, 0x82, 0x9f, 0xa6, 0x9f, 0xca, 0x9f, 0xee, 0x9f, 0x12, 0xa0, + 0x36, 0xa0, 0x5a, 0xa0, 0x7e, 0xa0, 0xa2, 0xa0, 0xc6, 0xa0, 0xeb, 0xa0, + 0x0f, 0xa1, 0x33, 0xa1, 0x57, 0xa1, 0x7b, 0xa1, 0x9f, 0xa1, 0xc3, 0xa1, + 0xe8, 0xa1, 0x0c, 0xa2, 0x30, 0xa2, 0x54, 0xa2, 0x79, 0xa2, 0x9d, 0xa2, + 0xc1, 0xa2, 0xe5, 0xa2, 0x0a, 0xa3, 0x2e, 0xa3, 0x52, 0xa3, 0x77, 0xa3, + 0x9b, 0xa3, 0xbf, 0xa3, 0xe4, 0xa3, 0x08, 0xa4, 0x2d, 0xa4, 0x51, 0xa4, + 0x75, 0xa4, 0x9a, 0xa4, 0xbe, 0xa4, 0xe3, 0xa4, 0x07, 0xa5, 0x2c, 0xa5, + 0x50, 0xa5, 0x75, 0xa5, 0x99, 0xa5, 0xbe, 0xa5, 0xe2, 0xa5, 0x07, 0xa6, + 0x2b, 0xa6, 0x50, 0xa6, 0x75, 0xa6, 0x99, 0xa6, 0xbe, 0xa6, 0xe3, 0xa6, + 0x07, 0xa7, 0x2c, 0xa7, 0x51, 0xa7, 0x75, 0xa7, 0x9a, 0xa7, 0xbf, 0xa7, + 0xe3, 0xa7, 0x08, 0xa8, 0x2d, 0xa8, 0x52, 0xa8, 0x76, 0xa8, 0x9b, 0xa8, + 0xc0, 0xa8, 0xe5, 0xa8, 0x0a, 0xa9, 0x2e, 0xa9, 0x53, 0xa9, 0x78, 0xa9, + 0x9d, 0xa9, 0xc2, 0xa9, 0xe7, 0xa9, 0x0c, 0xaa, 0x31, 0xaa, 0x55, 0xaa, + 0x7a, 0xaa, 0x9f, 0xaa, 0xc4, 0xaa, 0xe9, 0xaa, 0x0e, 0xab, 0x33, 0xab, + 0x58, 0xab, 0x7d, 0xab, 0xa2, 0xab, 0xc7, 0xab, 0xed, 0xab, 0x12, 0xac, + 0x37, 0xac, 0x5c, 0xac, 0x81, 0xac, 0xa6, 0xac, 0xcb, 0xac, 0xf0, 0xac, + 0x16, 0xad, 0x3b, 0xad, 0x60, 0xad, 0x85, 0xad, 0xaa, 0xad, 0xd0, 0xad, + 0xf5, 0xad, 0x1a, 0xae, 0x3f, 0xae, 0x65, 0xae, 0x8a, 0xae, 0xaf, 0xae, + 0xd5, 0xae, 0xfa, 0xae, 0x1f, 0xaf, 0x45, 0xaf, 0x6a, 0xaf, 0x8f, 0xaf, + 0xb5, 0xaf, 0xda, 0xaf, 0x00, 0xb0, 0x25, 0xb0, 0x4b, 0xb0, 0x70, 0xb0, + 0x95, 0xb0, 0xbb, 0xb0, 0xe0, 0xb0, 0x06, 0xb1, 0x2b, 0xb1, 0x51, 0xb1, + 0x77, 0xb1, 0x9c, 0xb1, 0xc2, 0xb1, 0xe7, 0xb1, 0x0d, 0xb2, 0x33, 0xb2, + 0x58, 0xb2, 0x7e, 0xb2, 0xa3, 0xb2, 0xc9, 0xb2, 0xef, 0xb2, 0x14, 0xb3, + 0x3a, 0xb3, 0x60, 0xb3, 0x86, 0xb3, 0xab, 0xb3, 0xd1, 0xb3, 0xf7, 0xb3, + 0x1d, 0xb4, 0x42, 0xb4, 0x68, 0xb4, 0x8e, 0xb4, 0xb4, 0xb4, 0xda, 0xb4, + 0x00, 0xb5, 0x25, 0xb5, 0x4b, 0xb5, 0x71, 0xb5, 0x97, 0xb5, 0xbd, 0xb5, + 0xe3, 0xb5, 0x09, 0xb6, 0x2f, 0xb6, 0x55, 0xb6, 0x7b, 0xb6, 0xa1, 0xb6, + 0xc7, 0xb6, 0xed, 0xb6, 0x13, 0xb7, 0x39, 0xb7, 0x5f, 0xb7, 0x85, 0xb7, + 0xab, 0xb7, 0xd1, 0xb7, 0xf7, 0xb7, 0x1e, 0xb8, 0x44, 0xb8, 0x6a, 0xb8, + 0x90, 0xb8, 0xb6, 0xb8, 0xdc, 0xb8, 0x03, 0xb9, 0x29, 0xb9, 0x4f, 0xb9, + 0x75, 0xb9, 0x9c, 0xb9, 0xc2, 0xb9, 0xe8, 0xb9, 0x0e, 0xba, 0x35, 0xba, + 0x5b, 0xba, 0x81, 0xba, 0xa8, 0xba, 0xce, 0xba, 0xf4, 0xba, 0x1b, 0xbb, + 0x41, 0xbb, 0x68, 0xbb, 0x8e, 0xbb, 0xb4, 0xbb, 0xdb, 0xbb, 0x01, 0xbc, + 0x28, 0xbc, 0x4e, 0xbc, 0x75, 0xbc, 0x9b, 0xbc, 0xc2, 0xbc, 0xe8, 0xbc, + 0x0f, 0xbd, 0x36, 0xbd, 0x5c, 0xbd, 0x83, 0xbd, 0xa9, 0xbd, 0xd0, 0xbd, + 0xf7, 0xbd, 0x1d, 0xbe, 0x44, 0xbe, 0x6b, 0xbe, 0x91, 0xbe, 0xb8, 0xbe, + 0xdf, 0xbe, 0x05, 0xbf, 0x2c, 0xbf, 0x53, 0xbf, 0x7a, 0xbf, 0xa0, 0xbf, + 0xc7, 0xbf, 0xee, 0xbf, 0x15, 0xc0, 0x3c, 0xc0, 0x63, 0xc0, 0x89, 0xc0, + 0xb0, 0xc0, 0xd7, 0xc0, 0xfe, 0xc0, 0x25, 0xc1, 0x4c, 0xc1, 0x73, 0xc1, + 0x9a, 0xc1, 0xc1, 0xc1, 0xe8, 0xc1, 0x0f, 0xc2, 0x36, 0xc2, 0x5d, 0xc2, + 0x84, 0xc2, 0xab, 0xc2, 0xd2, 0xc2, 0xf9, 0xc2, 0x20, 0xc3, 0x47, 0xc3, + 0x6e, 0xc3, 0x95, 0xc3, 0xbc, 0xc3, 0xe4, 0xc3, 0x0b, 0xc4, 0x32, 0xc4, + 0x59, 0xc4, 0x80, 0xc4, 0xa7, 0xc4, 0xcf, 0xc4, 0xf6, 0xc4, 0x1d, 0xc5, + 0x44, 0xc5, 0x6c, 0xc5, 0x93, 0xc5, 0xba, 0xc5, 0xe2, 0xc5, 0x09, 0xc6, + 0x30, 0xc6, 0x58, 0xc6, 0x7f, 0xc6, 0xa6, 0xc6, 0xce, 0xc6, 0xf5, 0xc6, + 0x1d, 0xc7, 0x44, 0xc7, 0x6c, 0xc7, 0x93, 0xc7, 0xbb, 0xc7, 0xe2, 0xc7, + 0x0a, 0xc8, 0x31, 0xc8, 0x59, 0xc8, 0x80, 0xc8, 0xa8, 0xc8, 0xcf, 0xc8, + 0xf7, 0xc8, 0x1e, 0xc9, 0x46, 0xc9, 0x6e, 0xc9, 0x95, 0xc9, 0xbd, 0xc9, + 0xe5, 0xc9, 0x0c, 0xca, 0x34, 0xca, 0x5c, 0xca, 0x83, 0xca, 0xab, 0xca, + 0xd3, 0xca, 0xfb, 0xca, 0x22, 0xcb, 0x4a, 0xcb, 0x72, 0xcb, 0x9a, 0xcb, + 0xc2, 0xcb, 0xea, 0xcb, 0x11, 0xcc, 0x39, 0xcc, 0x61, 0xcc, 0x89, 0xcc, + 0xb1, 0xcc, 0xd9, 0xcc, 0x01, 0xcd, 0x29, 0xcd, 0x51, 0xcd, 0x79, 0xcd, + 0xa1, 0xcd, 0xc9, 0xcd, 0xf1, 0xcd, 0x19, 0xce, 0x41, 0xce, 0x69, 0xce, + 0x91, 0xce, 0xb9, 0xce, 0xe1, 0xce, 0x09, 0xcf, 0x31, 0xcf, 0x59, 0xcf, + 0x82, 0xcf, 0xaa, 0xcf, 0xd2, 0xcf, 0xfa, 0xcf, 0x22, 0xd0, 0x4b, 0xd0, + 0x73, 0xd0, 0x9b, 0xd0, 0xc3, 0xd0, 0xec, 0xd0, 0x14, 0xd1, 0x3c, 0xd1, + 0x65, 0xd1, 0x8d, 0xd1, 0xb5, 0xd1, 0xde, 0xd1, 0x06, 0xd2, 0x2e, 0xd2, + 0x57, 0xd2, 0x7f, 0xd2, 0xa8, 0xd2, 0xd0, 0xd2, 0xf8, 0xd2, 0x21, 0xd3, + 0x49, 0xd3, 0x72, 0xd3, 0x9a, 0xd3, 0xc3, 0xd3, 0xeb, 0xd3, 0x14, 0xd4, + 0x3d, 0xd4, 0x65, 0xd4, 0x8e, 0xd4, 0xb6, 0xd4, 0xdf, 0xd4, 0x08, 0xd5, + 0x30, 0xd5, 0x59, 0xd5, 0x82, 0xd5, 0xaa, 0xd5, 0xd3, 0xd5, 0xfc, 0xd5, + 0x24, 0xd6, 0x4d, 0xd6, 0x76, 0xd6, 0x9f, 0xd6, 0xc7, 0xd6, 0xf0, 0xd6, + 0x19, 0xd7, 0x42, 0xd7, 0x6b, 0xd7, 0x94, 0xd7, 0xbc, 0xd7, 0xe5, 0xd7, + 0x0e, 0xd8, 0x37, 0xd8, 0x60, 0xd8, 0x89, 0xd8, 0xb2, 0xd8, 0xdb, 0xd8, + 0x04, 0xd9, 0x2d, 0xd9, 0x56, 0xd9, 0x7f, 0xd9, 0xa8, 0xd9, 0xd1, 0xd9, + 0xfa, 0xd9, 0x23, 0xda, 0x4c, 0xda, 0x75, 0xda, 0x9e, 0xda, 0xc8, 0xda, + 0xf1, 0xda, 0x1a, 0xdb, 0x43, 0xdb, 0x6c, 0xdb, 0x95, 0xdb, 0xbf, 0xdb, + 0xe8, 0xdb, 0x11, 0xdc, 0x3a, 0xdc, 0x64, 0xdc, 0x8d, 0xdc, 0xb6, 0xdc, + 0xdf, 0xdc, 0x09, 0xdd, 0x32, 0xdd, 0x5b, 0xdd, 0x85, 0xdd, 0xae, 0xdd, + 0xd8, 0xdd, 0x01, 0xde, 0x2a, 0xde, 0x54, 0xde, 0x7d, 0xde, 0xa7, 0xde, + 0xd0, 0xde, 0xfa, 0xde, 0x23, 0xdf, 0x4d, 0xdf, 0x76, 0xdf, 0xa0, 0xdf, + 0xc9, 0xdf, 0xf3, 0xdf, 0x1d, 0xe0, 0x46, 0xe0, 0x70, 0xe0, 0x99, 0xe0, + 0xc3, 0xe0, 0xed, 0xe0, 0x16, 0xe1, 0x40, 0xe1, 0x6a, 0xe1, 0x94, 0xe1, + 0xbd, 0xe1, 0xe7, 0xe1, 0x11, 0xe2, 0x3b, 0xe2, 0x64, 0xe2, 0x8e, 0xe2, + 0xb8, 0xe2, 0xe2, 0xe2, 0x0c, 0xe3, 0x36, 0xe3, 0x5f, 0xe3, 0x89, 0xe3, + 0xb3, 0xe3, 0xdd, 0xe3, 0x07, 0xe4, 0x31, 0xe4, 0x5b, 0xe4, 0x85, 0xe4, + 0xaf, 0xe4, 0xd9, 0xe4, 0x03, 0xe5, 0x2d, 0xe5, 0x57, 0xe5, 0x81, 0xe5, + 0xab, 0xe5, 0xd5, 0xe5, 0xff, 0xe5, 0x29, 0xe6, 0x54, 0xe6, 0x7e, 0xe6, + 0xa8, 0xe6, 0xd2, 0xe6, 0xfc, 0xe6, 0x26, 0xe7, 0x51, 0xe7, 0x7b, 0xe7, + 0xa5, 0xe7, 0xcf, 0xe7, 0xfa, 0xe7, 0x24, 0xe8, 0x4e, 0xe8, 0x79, 0xe8, + 0xa3, 0xe8, 0xcd, 0xe8, 0xf8, 0xe8, 0x22, 0xe9, 0x4c, 0xe9, 0x77, 0xe9, + 0xa1, 0xe9, 0xcc, 0xe9, 0xf6, 0xe9, 0x21, 0xea, 0x4b, 0xea, 0x75, 0xea, + 0xa0, 0xea, 0xca, 0xea, 0xf5, 0xea, 0x20, 0xeb, 0x4a, 0xeb, 0x75, 0xeb, + 0x9f, 0xeb, 0xca, 0xeb, 0xf5, 0xeb, 0x1f, 0xec, 0x4a, 0xec, 0x74, 0xec, + 0x9f, 0xec, 0xca, 0xec, 0xf5, 0xec, 0x1f, 0xed, 0x4a, 0xed, 0x75, 0xed, + 0x9f, 0xed, 0xca, 0xed, 0xf5, 0xed, 0x20, 0xee, 0x4b, 0xee, 0x75, 0xee, + 0xa0, 0xee, 0xcb, 0xee, 0xf6, 0xee, 0x21, 0xef, 0x4c, 0xef, 0x77, 0xef, + 0xa2, 0xef, 0xcd, 0xef, 0xf8, 0xef, 0x23, 0xf0, 0x4e, 0xf0, 0x79, 0xf0, + 0xa4, 0xf0, 0xcf, 0xf0, 0xfa, 0xf0, 0x25, 0xf1, 0x50, 0xf1, 0x7b, 0xf1, + 0xa6, 0xf1, 0xd1, 0xf1, 0xfc, 0xf1, 0x28, 0xf2, 0x53, 0xf2, 0x7e, 0xf2, + 0xa9, 0xf2, 0xd4, 0xf2, 0x00, 0xf3, 0x2b, 0xf3, 0x56, 0xf3, 0x81, 0xf3, + 0xad, 0xf3, 0xd8, 0xf3, 0x03, 0xf4, 0x2f, 0xf4, 0x5a, 0xf4, 0x85, 0xf4, + 0xb1, 0xf4, 0xdc, 0xf4, 0x07, 0xf5, 0x33, 0xf5, 0x5e, 0xf5, 0x8a, 0xf5, + 0xb5, 0xf5, 0xe1, 0xf5, 0x0c, 0xf6, 0x38, 0xf6, 0x63, 0xf6, 0x8f, 0xf6, + 0xba, 0xf6, 0xe6, 0xf6, 0x11, 0xf7, 0x3d, 0xf7, 0x69, 0xf7, 0x94, 0xf7, + 0xc0, 0xf7, 0xec, 0xf7, 0x17, 0xf8, 0x43, 0xf8, 0x6f, 0xf8, 0x9a, 0xf8, + 0xc6, 0xf8, 0xf2, 0xf8, 0x1e, 0xf9, 0x49, 0xf9, 0x75, 0xf9, 0xa1, 0xf9, + 0xcd, 0xf9, 0xf9, 0xf9, 0x24, 0xfa, 0x50, 0xfa, 0x7c, 0xfa, 0xa8, 0xfa, + 0xd4, 0xfa, 0x00, 0xfb, 0x2c, 0xfb, 0x58, 0xfb, 0x84, 0xfb, 0xb0, 0xfb, + 0xdc, 0xfb, 0x08, 0xfc, 0x34, 0xfc, 0x60, 0xfc, 0x8c, 0xfc, 0xb8, 0xfc, + 0xe4, 0xfc, 0x10, 0xfd, 0x3c, 0xfd, 0x68, 0xfd, 0x94, 0xfd, 0xc1, 0xfd, + 0xed, 0xfd, 0x19, 0xfe, 0x45, 0xfe, 0x71, 0xfe, 0x9e, 0xfe, 0xca, 0xfe, + 0xf6, 0xfe, 0x22, 0xff, 0x4f, 0xff, 0x7b, 0xff, 0xa7, 0xff, 0xd4, 0xff, + 0x00, 0x00, 0x32, 0x00, 0x65, 0x00, 0x97, 0x00, 0xc9, 0x00, 0xfb, 0x00, + 0x2e, 0x01, 0x60, 0x01, 0x92, 0x01, 0xc4, 0x01, 0xf7, 0x01, 0x29, 0x02, + 0x5b, 0x02, 0x8d, 0x02, 0xc0, 0x02, 0xf2, 0x02, 0x24, 0x03, 0x56, 0x03, + 0x89, 0x03, 0xbb, 0x03, 0xed, 0x03, 0x20, 0x04, 0x52, 0x04, 0x84, 0x04, + 0xb6, 0x04, 0xe9, 0x04, 0x1b, 0x05, 0x4d, 0x05, 0x7f, 0x05, 0xb2, 0x05, + 0xe4, 0x05, 0x16, 0x06, 0x48, 0x06, 0x7b, 0x06, 0xad, 0x06, 0xdf, 0x06, + 0x11, 0x07, 0x44, 0x07, 0x76, 0x07, 0xa8, 0x07, 0xda, 0x07, 0x0d, 0x08, + 0x3f, 0x08, 0x71, 0x08, 0xa3, 0x08, 0xd5, 0x08, 0x08, 0x09, 0x3a, 0x09, + 0x6c, 0x09, 0x9e, 0x09, 0xd1, 0x09, 0x03, 0x0a, 0x35, 0x0a, 0x67, 0x0a, + 0x9a, 0x0a, 0xcc, 0x0a, 0xfe, 0x0a, 0x30, 0x0b, 0x62, 0x0b, 0x95, 0x0b, + 0xc7, 0x0b, 0xf9, 0x0b, 0x2b, 0x0c, 0x5d, 0x0c, 0x90, 0x0c, 0xc2, 0x0c, + 0xf4, 0x0c, 0x26, 0x0d, 0x58, 0x0d, 0x8b, 0x0d, 0xbd, 0x0d, 0xef, 0x0d, + 0x21, 0x0e, 0x53, 0x0e, 0x86, 0x0e, 0xb8, 0x0e, 0xea, 0x0e, 0x1c, 0x0f, + 0x4e, 0x0f, 0x80, 0x0f, 0xb3, 0x0f, 0xe5, 0x0f, 0x17, 0x10, 0x49, 0x10, + 0x7b, 0x10, 0xad, 0x10, 0xe0, 0x10, 0x12, 0x11, 0x44, 0x11, 0x76, 0x11, + 0xa8, 0x11, 0xda, 0x11, 0x0d, 0x12, 0x3f, 0x12, 0x71, 0x12, 0xa3, 0x12, + 0xd5, 0x12, 0x07, 0x13, 0x39, 0x13, 0x6b, 0x13, 0x9e, 0x13, 0xd0, 0x13, + 0x02, 0x14, 0x34, 0x14, 0x66, 0x14, 0x98, 0x14, 0xca, 0x14, 0xfc, 0x14, + 0x2e, 0x15, 0x60, 0x15, 0x93, 0x15, 0xc5, 0x15, 0xf7, 0x15, 0x29, 0x16, + 0x5b, 0x16, 0x8d, 0x16, 0xbf, 0x16, 0xf1, 0x16, 0x23, 0x17, 0x55, 0x17, + 0x87, 0x17, 0xb9, 0x17, 0xeb, 0x17, 0x1d, 0x18, 0x4f, 0x18, 0x81, 0x18, + 0xb4, 0x18, 0xe6, 0x18, 0x18, 0x19, 0x4a, 0x19, 0x7c, 0x19, 0xae, 0x19, + 0xe0, 0x19, 0x12, 0x1a, 0x44, 0x1a, 0x76, 0x1a, 0xa8, 0x1a, 0xda, 0x1a, + 0x0c, 0x1b, 0x3e, 0x1b, 0x70, 0x1b, 0xa2, 0x1b, 0xd3, 0x1b, 0x05, 0x1c, + 0x37, 0x1c, 0x69, 0x1c, 0x9b, 0x1c, 0xcd, 0x1c, 0xff, 0x1c, 0x31, 0x1d, + 0x63, 0x1d, 0x95, 0x1d, 0xc7, 0x1d, 0xf9, 0x1d, 0x2b, 0x1e, 0x5d, 0x1e, + 0x8f, 0x1e, 0xc1, 0x1e, 0xf2, 0x1e, 0x24, 0x1f, 0x56, 0x1f, 0x88, 0x1f, + 0xba, 0x1f, 0xec, 0x1f, 0x1e, 0x20, 0x50, 0x20, 0x81, 0x20, 0xb3, 0x20, + 0xe5, 0x20, 0x17, 0x21, 0x49, 0x21, 0x7b, 0x21, 0xac, 0x21, 0xde, 0x21, + 0x10, 0x22, 0x42, 0x22, 0x74, 0x22, 0xa6, 0x22, 0xd7, 0x22, 0x09, 0x23, + 0x3b, 0x23, 0x6d, 0x23, 0x9e, 0x23, 0xd0, 0x23, 0x02, 0x24, 0x34, 0x24, + 0x66, 0x24, 0x97, 0x24, 0xc9, 0x24, 0xfb, 0x24, 0x2d, 0x25, 0x5e, 0x25, + 0x90, 0x25, 0xc2, 0x25, 0xf3, 0x25, 0x25, 0x26, 0x57, 0x26, 0x89, 0x26, + 0xba, 0x26, 0xec, 0x26, 0x1e, 0x27, 0x4f, 0x27, 0x81, 0x27, 0xb3, 0x27, + 0xe4, 0x27, 0x16, 0x28, 0x48, 0x28, 0x79, 0x28, 0xab, 0x28, 0xdc, 0x28, + 0x0e, 0x29, 0x40, 0x29, 0x71, 0x29, 0xa3, 0x29, 0xd4, 0x29, 0x06, 0x2a, + 0x38, 0x2a, 0x69, 0x2a, 0x9b, 0x2a, 0xcc, 0x2a, 0xfe, 0x2a, 0x2f, 0x2b, + 0x61, 0x2b, 0x92, 0x2b, 0xc4, 0x2b, 0xf6, 0x2b, 0x27, 0x2c, 0x59, 0x2c, + 0x8a, 0x2c, 0xbc, 0x2c, 0xed, 0x2c, 0x1e, 0x2d, 0x50, 0x2d, 0x81, 0x2d, + 0xb3, 0x2d, 0xe4, 0x2d, 0x16, 0x2e, 0x47, 0x2e, 0x79, 0x2e, 0xaa, 0x2e, + 0xdc, 0x2e, 0x0d, 0x2f, 0x3e, 0x2f, 0x70, 0x2f, 0xa1, 0x2f, 0xd3, 0x2f, + 0x04, 0x30, 0x35, 0x30, 0x67, 0x30, 0x98, 0x30, 0xc9, 0x30, 0xfb, 0x30, + 0x2c, 0x31, 0x5d, 0x31, 0x8f, 0x31, 0xc0, 0x31, 0xf1, 0x31, 0x23, 0x32, + 0x54, 0x32, 0x85, 0x32, 0xb6, 0x32, 0xe8, 0x32, 0x19, 0x33, 0x4a, 0x33, + 0x7b, 0x33, 0xad, 0x33, 0xde, 0x33, 0x0f, 0x34, 0x40, 0x34, 0x71, 0x34, + 0xa3, 0x34, 0xd4, 0x34, 0x05, 0x35, 0x36, 0x35, 0x67, 0x35, 0x99, 0x35, + 0xca, 0x35, 0xfb, 0x35, 0x2c, 0x36, 0x5d, 0x36, 0x8e, 0x36, 0xbf, 0x36, + 0xf0, 0x36, 0x21, 0x37, 0x53, 0x37, 0x84, 0x37, 0xb5, 0x37, 0xe6, 0x37, + 0x17, 0x38, 0x48, 0x38, 0x79, 0x38, 0xaa, 0x38, 0xdb, 0x38, 0x0c, 0x39, + 0x3d, 0x39, 0x6e, 0x39, 0x9f, 0x39, 0xd0, 0x39, 0x01, 0x3a, 0x32, 0x3a, + 0x63, 0x3a, 0x94, 0x3a, 0xc5, 0x3a, 0xf5, 0x3a, 0x26, 0x3b, 0x57, 0x3b, + 0x88, 0x3b, 0xb9, 0x3b, 0xea, 0x3b, 0x1b, 0x3c, 0x4c, 0x3c, 0x7d, 0x3c, + 0xad, 0x3c, 0xde, 0x3c, 0x0f, 0x3d, 0x40, 0x3d, 0x71, 0x3d, 0xa1, 0x3d, + 0xd2, 0x3d, 0x03, 0x3e, 0x34, 0x3e, 0x64, 0x3e, 0x95, 0x3e, 0xc6, 0x3e, + 0xf7, 0x3e, 0x27, 0x3f, 0x58, 0x3f, 0x89, 0x3f, 0xb9, 0x3f, 0xea, 0x3f, + 0x1b, 0x40, 0x4b, 0x40, 0x7c, 0x40, 0xad, 0x40, 0xdd, 0x40, 0x0e, 0x41, + 0x3f, 0x41, 0x6f, 0x41, 0xa0, 0x41, 0xd0, 0x41, 0x01, 0x42, 0x32, 0x42, + 0x62, 0x42, 0x93, 0x42, 0xc3, 0x42, 0xf4, 0x42, 0x24, 0x43, 0x55, 0x43, + 0x85, 0x43, 0xb6, 0x43, 0xe6, 0x43, 0x17, 0x44, 0x47, 0x44, 0x77, 0x44, + 0xa8, 0x44, 0xd8, 0x44, 0x09, 0x45, 0x39, 0x45, 0x69, 0x45, 0x9a, 0x45, + 0xca, 0x45, 0xfb, 0x45, 0x2b, 0x46, 0x5b, 0x46, 0x8c, 0x46, 0xbc, 0x46, + 0xec, 0x46, 0x1d, 0x47, 0x4d, 0x47, 0x7d, 0x47, 0xad, 0x47, 0xde, 0x47, + 0x0e, 0x48, 0x3e, 0x48, 0x6e, 0x48, 0x9e, 0x48, 0xcf, 0x48, 0xff, 0x48, + 0x2f, 0x49, 0x5f, 0x49, 0x8f, 0x49, 0xbf, 0x49, 0xf0, 0x49, 0x20, 0x4a, + 0x50, 0x4a, 0x80, 0x4a, 0xb0, 0x4a, 0xe0, 0x4a, 0x10, 0x4b, 0x40, 0x4b, + 0x70, 0x4b, 0xa0, 0x4b, 0xd0, 0x4b, 0x00, 0x4c, 0x30, 0x4c, 0x60, 0x4c, + 0x90, 0x4c, 0xc0, 0x4c, 0xf0, 0x4c, 0x20, 0x4d, 0x50, 0x4d, 0x80, 0x4d, + 0xb0, 0x4d, 0xe0, 0x4d, 0x10, 0x4e, 0x3f, 0x4e, 0x6f, 0x4e, 0x9f, 0x4e, + 0xcf, 0x4e, 0xff, 0x4e, 0x2f, 0x4f, 0x5e, 0x4f, 0x8e, 0x4f, 0xbe, 0x4f, + 0xee, 0x4f, 0x1d, 0x50, 0x4d, 0x50, 0x7d, 0x50, 0xad, 0x50, 0xdc, 0x50, + 0x0c, 0x51, 0x3c, 0x51, 0x6b, 0x51, 0x9b, 0x51, 0xcb, 0x51, 0xfa, 0x51, + 0x2a, 0x52, 0x59, 0x52, 0x89, 0x52, 0xb9, 0x52, 0xe8, 0x52, 0x18, 0x53, + 0x47, 0x53, 0x77, 0x53, 0xa6, 0x53, 0xd6, 0x53, 0x05, 0x54, 0x35, 0x54, + 0x64, 0x54, 0x94, 0x54, 0xc3, 0x54, 0xf2, 0x54, 0x22, 0x55, 0x51, 0x55, + 0x81, 0x55, 0xb0, 0x55, 0xdf, 0x55, 0x0f, 0x56, 0x3e, 0x56, 0x6d, 0x56, + 0x9d, 0x56, 0xcc, 0x56, 0xfb, 0x56, 0x2b, 0x57, 0x5a, 0x57, 0x89, 0x57, + 0xb8, 0x57, 0xe7, 0x57, 0x17, 0x58, 0x46, 0x58, 0x75, 0x58, 0xa4, 0x58, + 0xd3, 0x58, 0x02, 0x59, 0x32, 0x59, 0x61, 0x59, 0x90, 0x59, 0xbf, 0x59, + 0xee, 0x59, 0x1d, 0x5a, 0x4c, 0x5a, 0x7b, 0x5a, 0xaa, 0x5a, 0xd9, 0x5a, + 0x08, 0x5b, 0x37, 0x5b, 0x66, 0x5b, 0x95, 0x5b, 0xc4, 0x5b, 0xf3, 0x5b, + 0x22, 0x5c, 0x51, 0x5c, 0x7f, 0x5c, 0xae, 0x5c, 0xdd, 0x5c, 0x0c, 0x5d, + 0x3b, 0x5d, 0x6a, 0x5d, 0x98, 0x5d, 0xc7, 0x5d, 0xf6, 0x5d, 0x25, 0x5e, + 0x53, 0x5e, 0x82, 0x5e, 0xb1, 0x5e, 0xe0, 0x5e, 0x0e, 0x5f, 0x3d, 0x5f, + 0x6c, 0x5f, 0x9a, 0x5f, 0xc9, 0x5f, 0xf7, 0x5f, 0x26, 0x60, 0x55, 0x60, + 0x83, 0x60, 0xb2, 0x60, 0xe0, 0x60, 0x0f, 0x61, 0x3d, 0x61, 0x6c, 0x61, + 0x9a, 0x61, 0xc9, 0x61, 0xf7, 0x61, 0x26, 0x62, 0x54, 0x62, 0x82, 0x62, + 0xb1, 0x62, 0xdf, 0x62, 0x0e, 0x63, 0x3c, 0x63, 0x6a, 0x63, 0x99, 0x63, + 0xc7, 0x63, 0xf5, 0x63, 0x23, 0x64, 0x52, 0x64, 0x80, 0x64, 0xae, 0x64, + 0xdc, 0x64, 0x0a, 0x65, 0x39, 0x65, 0x67, 0x65, 0x95, 0x65, 0xc3, 0x65, + 0xf1, 0x65, 0x1f, 0x66, 0x4d, 0x66, 0x7b, 0x66, 0xa9, 0x66, 0xd8, 0x66, + 0x06, 0x67, 0x34, 0x67, 0x62, 0x67, 0x90, 0x67, 0xbd, 0x67, 0xeb, 0x67, + 0x19, 0x68, 0x47, 0x68, 0x75, 0x68, 0xa3, 0x68, 0xd1, 0x68, 0xff, 0x68, + 0x2d, 0x69, 0x5a, 0x69, 0x88, 0x69, 0xb6, 0x69, 0xe4, 0x69, 0x12, 0x6a, + 0x3f, 0x6a, 0x6d, 0x6a, 0x9b, 0x6a, 0xc8, 0x6a, 0xf6, 0x6a, 0x24, 0x6b, + 0x51, 0x6b, 0x7f, 0x6b, 0xad, 0x6b, 0xda, 0x6b, 0x08, 0x6c, 0x35, 0x6c, + 0x63, 0x6c, 0x90, 0x6c, 0xbe, 0x6c, 0xeb, 0x6c, 0x19, 0x6d, 0x46, 0x6d, + 0x74, 0x6d, 0xa1, 0x6d, 0xcf, 0x6d, 0xfc, 0x6d, 0x29, 0x6e, 0x57, 0x6e, + 0x84, 0x6e, 0xb1, 0x6e, 0xdf, 0x6e, 0x0c, 0x6f, 0x39, 0x6f, 0x67, 0x6f, + 0x94, 0x6f, 0xc1, 0x6f, 0xee, 0x6f, 0x1c, 0x70, 0x49, 0x70, 0x76, 0x70, + 0xa3, 0x70, 0xd0, 0x70, 0xfd, 0x70, 0x2a, 0x71, 0x57, 0x71, 0x85, 0x71, + 0xb2, 0x71, 0xdf, 0x71, 0x0c, 0x72, 0x39, 0x72, 0x66, 0x72, 0x93, 0x72, + 0xbf, 0x72, 0xec, 0x72, 0x19, 0x73, 0x46, 0x73, 0x73, 0x73, 0xa0, 0x73, + 0xcd, 0x73, 0xfa, 0x73, 0x26, 0x74, 0x53, 0x74, 0x80, 0x74, 0xad, 0x74, + 0xd9, 0x74, 0x06, 0x75, 0x33, 0x75, 0x5f, 0x75, 0x8c, 0x75, 0xb9, 0x75, + 0xe5, 0x75, 0x12, 0x76, 0x3f, 0x76, 0x6b, 0x76, 0x98, 0x76, 0xc4, 0x76, + 0xf1, 0x76, 0x1d, 0x77, 0x4a, 0x77, 0x76, 0x77, 0xa3, 0x77, 0xcf, 0x77, + 0xfc, 0x77, 0x28, 0x78, 0x54, 0x78, 0x81, 0x78, 0xad, 0x78, 0xd9, 0x78, + 0x06, 0x79, 0x32, 0x79, 0x5e, 0x79, 0x8a, 0x79, 0xb7, 0x79, 0xe3, 0x79, + 0x0f, 0x7a, 0x3b, 0x7a, 0x67, 0x7a, 0x94, 0x7a, 0xc0, 0x7a, 0xec, 0x7a, + 0x18, 0x7b, 0x44, 0x7b, 0x70, 0x7b, 0x9c, 0x7b, 0xc8, 0x7b, 0xf4, 0x7b, + 0x20, 0x7c, 0x4c, 0x7c, 0x78, 0x7c, 0xa4, 0x7c, 0xd0, 0x7c, 0xfb, 0x7c, + 0x27, 0x7d, 0x53, 0x7d, 0x7f, 0x7d, 0xab, 0x7d, 0xd7, 0x7d, 0x02, 0x7e, + 0x2e, 0x7e, 0x5a, 0x7e, 0x86, 0x7e, 0xb1, 0x7e, 0xdd, 0x7e, 0x09, 0x7f, + 0x34, 0x7f, 0x60, 0x7f, 0x8b, 0x7f, 0xb7, 0x7f, 0xe2, 0x7f, 0x0e, 0x80, + 0x3a, 0x80, 0x65, 0x80, 0x90, 0x80, 0xbc, 0x80, 0xe7, 0x80, 0x13, 0x81, + 0x3e, 0x81, 0x6a, 0x81, 0x95, 0x81, 0xc0, 0x81, 0xec, 0x81, 0x17, 0x82, + 0x42, 0x82, 0x6d, 0x82, 0x99, 0x82, 0xc4, 0x82, 0xef, 0x82, 0x1a, 0x83, + 0x45, 0x83, 0x71, 0x83, 0x9c, 0x83, 0xc7, 0x83, 0xf2, 0x83, 0x1d, 0x84, + 0x48, 0x84, 0x73, 0x84, 0x9e, 0x84, 0xc9, 0x84, 0xf4, 0x84, 0x1f, 0x85, + 0x4a, 0x85, 0x75, 0x85, 0xa0, 0x85, 0xcb, 0x85, 0xf5, 0x85, 0x20, 0x86, + 0x4b, 0x86, 0x76, 0x86, 0xa1, 0x86, 0xcb, 0x86, 0xf6, 0x86, 0x21, 0x87, + 0x4b, 0x87, 0x76, 0x87, 0xa1, 0x87, 0xcb, 0x87, 0xf6, 0x87, 0x20, 0x88, + 0x4b, 0x88, 0x76, 0x88, 0xa0, 0x88, 0xcb, 0x88, 0xf5, 0x88, 0x20, 0x89, + 0x4a, 0x89, 0x74, 0x89, 0x9f, 0x89, 0xc9, 0x89, 0xf3, 0x89, 0x1e, 0x8a, + 0x48, 0x8a, 0x72, 0x8a, 0x9d, 0x8a, 0xc7, 0x8a, 0xf1, 0x8a, 0x1b, 0x8b, + 0x46, 0x8b, 0x70, 0x8b, 0x9a, 0x8b, 0xc4, 0x8b, 0xee, 0x8b, 0x18, 0x8c, + 0x42, 0x8c, 0x6c, 0x8c, 0x96, 0x8c, 0xc0, 0x8c, 0xea, 0x8c, 0x14, 0x8d, + 0x3e, 0x8d, 0x68, 0x8d, 0x92, 0x8d, 0xbc, 0x8d, 0xe6, 0x8d, 0x0f, 0x8e, + 0x39, 0x8e, 0x63, 0x8e, 0x8d, 0x8e, 0xb7, 0x8e, 0xe0, 0x8e, 0x0a, 0x8f, + 0x34, 0x8f, 0x5d, 0x8f, 0x87, 0x8f, 0xb1, 0x8f, 0xda, 0x8f, 0x04, 0x90, + 0x2d, 0x90, 0x57, 0x90, 0x80, 0x90, 0xaa, 0x90, 0xd3, 0x90, 0xfd, 0x90, + 0x26, 0x91, 0x4f, 0x91, 0x79, 0x91, 0xa2, 0x91, 0xcc, 0x91, 0xf5, 0x91, + 0x1e, 0x92, 0x47, 0x92, 0x71, 0x92, 0x9a, 0x92, 0xc3, 0x92, 0xec, 0x92, + 0x15, 0x93, 0x3e, 0x93, 0x68, 0x93, 0x91, 0x93, 0xba, 0x93, 0xe3, 0x93, + 0x0c, 0x94, 0x35, 0x94, 0x5e, 0x94, 0x87, 0x94, 0xb0, 0x94, 0xd9, 0x94, + 0x01, 0x95, 0x2a, 0x95, 0x53, 0x95, 0x7c, 0x95, 0xa5, 0x95, 0xce, 0x95, + 0xf6, 0x95, 0x1f, 0x96, 0x48, 0x96, 0x70, 0x96, 0x99, 0x96, 0xc2, 0x96, + 0xea, 0x96, 0x13, 0x97, 0x3b, 0x97, 0x64, 0x97, 0x8d, 0x97, 0xb5, 0x97, + 0xdd, 0x97, 0x06, 0x98, 0x2e, 0x98, 0x57, 0x98, 0x7f, 0x98, 0xa8, 0x98, + 0xd0, 0x98, 0xf8, 0x98, 0x20, 0x99, 0x49, 0x99, 0x71, 0x99, 0x99, 0x99, + 0xc1, 0x99, 0xea, 0x99, 0x12, 0x9a, 0x3a, 0x9a, 0x62, 0x9a, 0x8a, 0x9a, + 0xb2, 0x9a, 0xda, 0x9a, 0x02, 0x9b, 0x2a, 0x9b, 0x52, 0x9b, 0x7a, 0x9b, + 0xa2, 0x9b, 0xca, 0x9b, 0xf2, 0x9b, 0x1a, 0x9c, 0x41, 0x9c, 0x69, 0x9c, + 0x91, 0x9c, 0xb9, 0x9c, 0xe1, 0x9c, 0x08, 0x9d, 0x30, 0x9d, 0x58, 0x9d, + 0x7f, 0x9d, 0xa7, 0x9d, 0xce, 0x9d, 0xf6, 0x9d, 0x1e, 0x9e, 0x45, 0x9e, + 0x6d, 0x9e, 0x94, 0x9e, 0xbb, 0x9e, 0xe3, 0x9e, 0x0a, 0x9f, 0x32, 0x9f, + 0x59, 0x9f, 0x80, 0x9f, 0xa8, 0x9f, 0xcf, 0x9f, 0xf6, 0x9f, 0x1d, 0xa0, + 0x45, 0xa0, 0x6c, 0xa0, 0x93, 0xa0, 0xba, 0xa0, 0xe1, 0xa0, 0x08, 0xa1, + 0x2f, 0xa1, 0x56, 0xa1, 0x7d, 0xa1, 0xa4, 0xa1, 0xcb, 0xa1, 0xf2, 0xa1, + 0x19, 0xa2, 0x40, 0xa2, 0x67, 0xa2, 0x8e, 0xa2, 0xb5, 0xa2, 0xdb, 0xa2, + 0x02, 0xa3, 0x29, 0xa3, 0x50, 0xa3, 0x76, 0xa3, 0x9d, 0xa3, 0xc4, 0xa3, + 0xea, 0xa3, 0x11, 0xa4, 0x37, 0xa4, 0x5e, 0xa4, 0x85, 0xa4, 0xab, 0xa4, + 0xd2, 0xa4, 0xf8, 0xa4, 0x1e, 0xa5, 0x45, 0xa5, 0x6b, 0xa5, 0x91, 0xa5, + 0xb8, 0xa5, 0xde, 0xa5, 0x04, 0xa6, 0x2b, 0xa6, 0x51, 0xa6, 0x77, 0xa6, + 0x9d, 0xa6, 0xc3, 0xa6, 0xea, 0xa6, 0x10, 0xa7, 0x36, 0xa7, 0x5c, 0xa7, + 0x82, 0xa7, 0xa8, 0xa7, 0xce, 0xa7, 0xf4, 0xa7, 0x1a, 0xa8, 0x3f, 0xa8, + 0x65, 0xa8, 0x8b, 0xa8, 0xb1, 0xa8, 0xd7, 0xa8, 0xfd, 0xa8, 0x22, 0xa9, + 0x48, 0xa9, 0x6e, 0xa9, 0x93, 0xa9, 0xb9, 0xa9, 0xdf, 0xa9, 0x04, 0xaa, + 0x2a, 0xaa, 0x4f, 0xaa, 0x75, 0xaa, 0x9a, 0xaa, 0xc0, 0xaa, 0xe5, 0xaa, + 0x0b, 0xab, 0x30, 0xab, 0x55, 0xab, 0x7b, 0xab, 0xa0, 0xab, 0xc5, 0xab, + 0xeb, 0xab, 0x10, 0xac, 0x35, 0xac, 0x5a, 0xac, 0x7f, 0xac, 0xa5, 0xac, + 0xca, 0xac, 0xef, 0xac, 0x14, 0xad, 0x39, 0xad, 0x5e, 0xad, 0x83, 0xad, + 0xa8, 0xad, 0xcd, 0xad, 0xf1, 0xad, 0x16, 0xae, 0x3b, 0xae, 0x60, 0xae, + 0x85, 0xae, 0xaa, 0xae, 0xce, 0xae, 0xf3, 0xae, 0x18, 0xaf, 0x3c, 0xaf, + 0x61, 0xaf, 0x86, 0xaf, 0xaa, 0xaf, 0xcf, 0xaf, 0xf3, 0xaf, 0x18, 0xb0, + 0x3c, 0xb0, 0x61, 0xb0, 0x85, 0xb0, 0xa9, 0xb0, 0xce, 0xb0, 0xf2, 0xb0, + 0x16, 0xb1, 0x3b, 0xb1, 0x5f, 0xb1, 0x83, 0xb1, 0xa7, 0xb1, 0xcc, 0xb1, + 0xf0, 0xb1, 0x14, 0xb2, 0x38, 0xb2, 0x5c, 0xb2, 0x80, 0xb2, 0xa4, 0xb2, + 0xc8, 0xb2, 0xec, 0xb2, 0x10, 0xb3, 0x34, 0xb3, 0x58, 0xb3, 0x7c, 0xb3, + 0x9f, 0xb3, 0xc3, 0xb3, 0xe7, 0xb3, 0x0b, 0xb4, 0x2e, 0xb4, 0x52, 0xb4, + 0x76, 0xb4, 0x99, 0xb4, 0xbd, 0xb4, 0xe1, 0xb4, 0x04, 0xb5, 0x28, 0xb5, + 0x4b, 0xb5, 0x6f, 0xb5, 0x92, 0xb5, 0xb6, 0xb5, 0xd9, 0xb5, 0xfc, 0xb5, + 0x20, 0xb6, 0x43, 0xb6, 0x66, 0xb6, 0x8a, 0xb6, 0xad, 0xb6, 0xd0, 0xb6, + 0xf3, 0xb6, 0x16, 0xb7, 0x39, 0xb7, 0x5d, 0xb7, 0x80, 0xb7, 0xa3, 0xb7, + 0xc6, 0xb7, 0xe9, 0xb7, 0x0c, 0xb8, 0x2e, 0xb8, 0x51, 0xb8, 0x74, 0xb8, + 0x97, 0xb8, 0xba, 0xb8, 0xdd, 0xb8, 0xff, 0xb8, 0x22, 0xb9, 0x45, 0xb9, + 0x68, 0xb9, 0x8a, 0xb9, 0xad, 0xb9, 0xcf, 0xb9, 0xf2, 0xb9, 0x14, 0xba, + 0x37, 0xba, 0x59, 0xba, 0x7c, 0xba, 0x9e, 0xba, 0xc1, 0xba, 0xe3, 0xba, + 0x05, 0xbb, 0x28, 0xbb, 0x4a, 0xbb, 0x6c, 0xbb, 0x8e, 0xbb, 0xb1, 0xbb, + 0xd3, 0xbb, 0xf5, 0xbb, 0x17, 0xbc, 0x39, 0xbc, 0x5b, 0xbc, 0x7d, 0xbc, + 0x9f, 0xbc, 0xc1, 0xbc, 0xe3, 0xbc, 0x05, 0xbd, 0x27, 0xbd, 0x49, 0xbd, + 0x6b, 0xbd, 0x8c, 0xbd, 0xae, 0xbd, 0xd0, 0xbd, 0xf2, 0xbd, 0x13, 0xbe, + 0x35, 0xbe, 0x57, 0xbe, 0x78, 0xbe, 0x9a, 0xbe, 0xbb, 0xbe, 0xdd, 0xbe, + 0xfe, 0xbe, 0x20, 0xbf, 0x41, 0xbf, 0x63, 0xbf, 0x84, 0xbf, 0xa5, 0xbf, + 0xc7, 0xbf, 0xe8, 0xbf, 0x09, 0xc0, 0x2a, 0xc0, 0x4c, 0xc0, 0x6d, 0xc0, + 0x8e, 0xc0, 0xaf, 0xc0, 0xd0, 0xc0, 0xf1, 0xc0, 0x12, 0xc1, 0x33, 0xc1, + 0x54, 0xc1, 0x75, 0xc1, 0x96, 0xc1, 0xb7, 0xc1, 0xd8, 0xc1, 0xf8, 0xc1, + 0x19, 0xc2, 0x3a, 0xc2, 0x5b, 0xc2, 0x7b, 0xc2, 0x9c, 0xc2, 0xbd, 0xc2, + 0xdd, 0xc2, 0xfe, 0xc2, 0x1f, 0xc3, 0x3f, 0xc3, 0x60, 0xc3, 0x80, 0xc3, + 0xa0, 0xc3, 0xc1, 0xc3, 0xe1, 0xc3, 0x02, 0xc4, 0x22, 0xc4, 0x42, 0xc4, + 0x62, 0xc4, 0x83, 0xc4, 0xa3, 0xc4, 0xc3, 0xc4, 0xe3, 0xc4, 0x03, 0xc5, + 0x23, 0xc5, 0x43, 0xc5, 0x63, 0xc5, 0x83, 0xc5, 0xa3, 0xc5, 0xc3, 0xc5, + 0xe3, 0xc5, 0x03, 0xc6, 0x23, 0xc6, 0x43, 0xc6, 0x63, 0xc6, 0x82, 0xc6, + 0xa2, 0xc6, 0xc2, 0xc6, 0xe1, 0xc6, 0x01, 0xc7, 0x21, 0xc7, 0x40, 0xc7, + 0x60, 0xc7, 0x7f, 0xc7, 0x9f, 0xc7, 0xbe, 0xc7, 0xde, 0xc7, 0xfd, 0xc7, + 0x1c, 0xc8, 0x3c, 0xc8, 0x5b, 0xc8, 0x7a, 0xc8, 0x9a, 0xc8, 0xb9, 0xc8, + 0xd8, 0xc8, 0xf7, 0xc8, 0x16, 0xc9, 0x35, 0xc9, 0x54, 0xc9, 0x73, 0xc9, + 0x92, 0xc9, 0xb1, 0xc9, 0xd0, 0xc9, 0xef, 0xc9, 0x0e, 0xca, 0x2d, 0xca, + 0x4c, 0xca, 0x6b, 0xca, 0x89, 0xca, 0xa8, 0xca, 0xc7, 0xca, 0xe5, 0xca, + 0x04, 0xcb, 0x23, 0xcb, 0x41, 0xcb, 0x60, 0xcb, 0x7e, 0xcb, 0x9d, 0xcb, + 0xbb, 0xcb, 0xda, 0xcb, 0xf8, 0xcb, 0x16, 0xcc, 0x35, 0xcc, 0x53, 0xcc, + 0x71, 0xcc, 0x8f, 0xcc, 0xae, 0xcc, 0xcc, 0xcc, 0xea, 0xcc, 0x08, 0xcd, + 0x26, 0xcd, 0x44, 0xcd, 0x62, 0xcd, 0x80, 0xcd, 0x9e, 0xcd, 0xbc, 0xcd, + 0xda, 0xcd, 0xf8, 0xcd, 0x16, 0xce, 0x34, 0xce, 0x51, 0xce, 0x6f, 0xce, + 0x8d, 0xce, 0xaa, 0xce, 0xc8, 0xce, 0xe6, 0xce, 0x03, 0xcf, 0x21, 0xcf, + 0x3e, 0xcf, 0x5c, 0xcf, 0x79, 0xcf, 0x97, 0xcf, 0xb4, 0xcf, 0xd2, 0xcf, + 0xef, 0xcf, 0x0c, 0xd0, 0x29, 0xd0, 0x47, 0xd0, 0x64, 0xd0, 0x81, 0xd0, + 0x9e, 0xd0, 0xbb, 0xd0, 0xd8, 0xd0, 0xf5, 0xd0, 0x12, 0xd1, 0x2f, 0xd1, + 0x4c, 0xd1, 0x69, 0xd1, 0x86, 0xd1, 0xa3, 0xd1, 0xc0, 0xd1, 0xdd, 0xd1, + 0xfa, 0xd1, 0x16, 0xd2, 0x33, 0xd2, 0x50, 0xd2, 0x6c, 0xd2, 0x89, 0xd2, + 0xa5, 0xd2, 0xc2, 0xd2, 0xdf, 0xd2, 0xfb, 0xd2, 0x17, 0xd3, 0x34, 0xd3, + 0x50, 0xd3, 0x6d, 0xd3, 0x89, 0xd3, 0xa5, 0xd3, 0xc2, 0xd3, 0xde, 0xd3, + 0xfa, 0xd3, 0x16, 0xd4, 0x32, 0xd4, 0x4e, 0xd4, 0x6a, 0xd4, 0x86, 0xd4, + 0xa2, 0xd4, 0xbe, 0xd4, 0xda, 0xd4, 0xf6, 0xd4, 0x12, 0xd5, 0x2e, 0xd5, + 0x4a, 0xd5, 0x66, 0xd5, 0x81, 0xd5, 0x9d, 0xd5, 0xb9, 0xd5, 0xd4, 0xd5, + 0xf0, 0xd5, 0x0c, 0xd6, 0x27, 0xd6, 0x43, 0xd6, 0x5e, 0xd6, 0x7a, 0xd6, + 0x95, 0xd6, 0xb0, 0xd6, 0xcc, 0xd6, 0xe7, 0xd6, 0x02, 0xd7, 0x1e, 0xd7, + 0x39, 0xd7, 0x54, 0xd7, 0x6f, 0xd7, 0x8a, 0xd7, 0xa6, 0xd7, 0xc1, 0xd7, + 0xdc, 0xd7, 0xf7, 0xd7, 0x12, 0xd8, 0x2d, 0xd8, 0x47, 0xd8, 0x62, 0xd8, + 0x7d, 0xd8, 0x98, 0xd8, 0xb3, 0xd8, 0xce, 0xd8, 0xe8, 0xd8, 0x03, 0xd9, + 0x1e, 0xd9, 0x38, 0xd9, 0x53, 0xd9, 0x6d, 0xd9, 0x88, 0xd9, 0xa2, 0xd9, + 0xbd, 0xd9, 0xd7, 0xd9, 0xf2, 0xd9, 0x0c, 0xda, 0x26, 0xda, 0x41, 0xda, + 0x5b, 0xda, 0x75, 0xda, 0x8f, 0xda, 0xa9, 0xda, 0xc3, 0xda, 0xde, 0xda, + 0xf8, 0xda, 0x12, 0xdb, 0x2c, 0xdb, 0x46, 0xdb, 0x5f, 0xdb, 0x79, 0xdb, + 0x93, 0xdb, 0xad, 0xdb, 0xc7, 0xdb, 0xe1, 0xdb, 0xfa, 0xdb, 0x14, 0xdc, + 0x2e, 0xdc, 0x47, 0xdc, 0x61, 0xdc, 0x7a, 0xdc, 0x94, 0xdc, 0xad, 0xdc, + 0xc7, 0xdc, 0xe0, 0xdc, 0xfa, 0xdc, 0x13, 0xdd, 0x2c, 0xdd, 0x46, 0xdd, + 0x5f, 0xdd, 0x78, 0xdd, 0x91, 0xdd, 0xab, 0xdd, 0xc4, 0xdd, 0xdd, 0xdd, + 0xf6, 0xdd, 0x0f, 0xde, 0x28, 0xde, 0x41, 0xde, 0x5a, 0xde, 0x73, 0xde, + 0x8c, 0xde, 0xa4, 0xde, 0xbd, 0xde, 0xd6, 0xde, 0xef, 0xde, 0x07, 0xdf, + 0x20, 0xdf, 0x39, 0xdf, 0x51, 0xdf, 0x6a, 0xdf, 0x82, 0xdf, 0x9b, 0xdf, + 0xb3, 0xdf, 0xcc, 0xdf, 0xe4, 0xdf, 0xfc, 0xdf, 0x15, 0xe0, 0x2d, 0xe0, + 0x45, 0xe0, 0x5d, 0xe0, 0x76, 0xe0, 0x8e, 0xe0, 0xa6, 0xe0, 0xbe, 0xe0, + 0xd6, 0xe0, 0xee, 0xe0, 0x06, 0xe1, 0x1e, 0xe1, 0x36, 0xe1, 0x4e, 0xe1, + 0x66, 0xe1, 0x7d, 0xe1, 0x95, 0xe1, 0xad, 0xe1, 0xc5, 0xe1, 0xdc, 0xe1, + 0xf4, 0xe1, 0x0c, 0xe2, 0x23, 0xe2, 0x3b, 0xe2, 0x52, 0xe2, 0x6a, 0xe2, + 0x81, 0xe2, 0x99, 0xe2, 0xb0, 0xe2, 0xc7, 0xe2, 0xdf, 0xe2, 0xf6, 0xe2, + 0x0d, 0xe3, 0x24, 0xe3, 0x3b, 0xe3, 0x53, 0xe3, 0x6a, 0xe3, 0x81, 0xe3, + 0x98, 0xe3, 0xaf, 0xe3, 0xc6, 0xe3, 0xdd, 0xe3, 0xf4, 0xe3, 0x0a, 0xe4, + 0x21, 0xe4, 0x38, 0xe4, 0x4f, 0xe4, 0x66, 0xe4, 0x7c, 0xe4, 0x93, 0xe4, + 0xa9, 0xe4, 0xc0, 0xe4, 0xd7, 0xe4, 0xed, 0xe4, 0x04, 0xe5, 0x1a, 0xe5, + 0x30, 0xe5, 0x47, 0xe5, 0x5d, 0xe5, 0x73, 0xe5, 0x8a, 0xe5, 0xa0, 0xe5, + 0xb6, 0xe5, 0xcc, 0xe5, 0xe2, 0xe5, 0xf9, 0xe5, 0x0f, 0xe6, 0x25, 0xe6, + 0x3b, 0xe6, 0x51, 0xe6, 0x67, 0xe6, 0x7c, 0xe6, 0x92, 0xe6, 0xa8, 0xe6, + 0xbe, 0xe6, 0xd4, 0xe6, 0xe9, 0xe6, 0xff, 0xe6, 0x15, 0xe7, 0x2a, 0xe7, + 0x40, 0xe7, 0x55, 0xe7, 0x6b, 0xe7, 0x80, 0xe7, 0x96, 0xe7, 0xab, 0xe7, + 0xc1, 0xe7, 0xd6, 0xe7, 0xeb, 0xe7, 0x01, 0xe8, 0x16, 0xe8, 0x2b, 0xe8, + 0x40, 0xe8, 0x55, 0xe8, 0x6a, 0xe8, 0x7f, 0xe8, 0x94, 0xe8, 0xa9, 0xe8, + 0xbe, 0xe8, 0xd3, 0xe8, 0xe8, 0xe8, 0xfd, 0xe8, 0x12, 0xe9, 0x27, 0xe9, + 0x3b, 0xe9, 0x50, 0xe9, 0x65, 0xe9, 0x79, 0xe9, 0x8e, 0xe9, 0xa2, 0xe9, + 0xb7, 0xe9, 0xcb, 0xe9, 0xe0, 0xe9, 0xf4, 0xe9, 0x09, 0xea, 0x1d, 0xea, + 0x31, 0xea, 0x46, 0xea, 0x5a, 0xea, 0x6e, 0xea, 0x82, 0xea, 0x96, 0xea, + 0xab, 0xea, 0xbf, 0xea, 0xd3, 0xea, 0xe7, 0xea, 0xfb, 0xea, 0x0f, 0xeb, + 0x22, 0xeb, 0x36, 0xeb, 0x4a, 0xeb, 0x5e, 0xeb, 0x72, 0xeb, 0x85, 0xeb, + 0x99, 0xeb, 0xad, 0xeb, 0xc0, 0xeb, 0xd4, 0xeb, 0xe7, 0xeb, 0xfb, 0xeb, + 0x0e, 0xec, 0x22, 0xec, 0x35, 0xec, 0x49, 0xec, 0x5c, 0xec, 0x6f, 0xec, + 0x82, 0xec, 0x96, 0xec, 0xa9, 0xec, 0xbc, 0xec, 0xcf, 0xec, 0xe2, 0xec, + 0xf5, 0xec, 0x08, 0xed, 0x1b, 0xed, 0x2e, 0xed, 0x41, 0xed, 0x54, 0xed, + 0x67, 0xed, 0x79, 0xed, 0x8c, 0xed, 0x9f, 0xed, 0xb2, 0xed, 0xc4, 0xed, + 0xd7, 0xed, 0xe9, 0xed, 0xfc, 0xed, 0x0f, 0xee, 0x21, 0xee, 0x33, 0xee, + 0x46, 0xee, 0x58, 0xee, 0x6a, 0xee, 0x7d, 0xee, 0x8f, 0xee, 0xa1, 0xee, + 0xb3, 0xee, 0xc6, 0xee, 0xd8, 0xee, 0xea, 0xee, 0xfc, 0xee, 0x0e, 0xef, + 0x20, 0xef, 0x32, 0xef, 0x44, 0xef, 0x55, 0xef, 0x67, 0xef, 0x79, 0xef, + 0x8b, 0xef, 0x9c, 0xef, 0xae, 0xef, 0xc0, 0xef, 0xd1, 0xef, 0xe3, 0xef, + 0xf5, 0xef, 0x06, 0xf0, 0x17, 0xf0, 0x29, 0xf0, 0x3a, 0xf0, 0x4c, 0xf0, + 0x5d, 0xf0, 0x6e, 0xf0, 0x7f, 0xf0, 0x91, 0xf0, 0xa2, 0xf0, 0xb3, 0xf0, + 0xc4, 0xf0, 0xd5, 0xf0, 0xe6, 0xf0, 0xf7, 0xf0, 0x08, 0xf1, 0x19, 0xf1, + 0x2a, 0xf1, 0x3b, 0xf1, 0x4c, 0xf1, 0x5c, 0xf1, 0x6d, 0xf1, 0x7e, 0xf1, + 0x8e, 0xf1, 0x9f, 0xf1, 0xb0, 0xf1, 0xc0, 0xf1, 0xd1, 0xf1, 0xe1, 0xf1, + 0xf2, 0xf1, 0x02, 0xf2, 0x12, 0xf2, 0x23, 0xf2, 0x33, 0xf2, 0x43, 0xf2, + 0x53, 0xf2, 0x64, 0xf2, 0x74, 0xf2, 0x84, 0xf2, 0x94, 0xf2, 0xa4, 0xf2, + 0xb4, 0xf2, 0xc4, 0xf2, 0xd4, 0xf2, 0xe4, 0xf2, 0xf4, 0xf2, 0x04, 0xf3, + 0x13, 0xf3, 0x23, 0xf3, 0x33, 0xf3, 0x42, 0xf3, 0x52, 0xf3, 0x62, 0xf3, + 0x71, 0xf3, 0x81, 0xf3, 0x90, 0xf3, 0xa0, 0xf3, 0xaf, 0xf3, 0xbf, 0xf3, + 0xce, 0xf3, 0xdd, 0xf3, 0xec, 0xf3, 0xfc, 0xf3, 0x0b, 0xf4, 0x1a, 0xf4, + 0x29, 0xf4, 0x38, 0xf4, 0x47, 0xf4, 0x56, 0xf4, 0x65, 0xf4, 0x74, 0xf4, + 0x83, 0xf4, 0x92, 0xf4, 0xa1, 0xf4, 0xb0, 0xf4, 0xbe, 0xf4, 0xcd, 0xf4, + 0xdc, 0xf4, 0xea, 0xf4, 0xf9, 0xf4, 0x08, 0xf5, 0x16, 0xf5, 0x25, 0xf5, + 0x33, 0xf5, 0x42, 0xf5, 0x50, 0xf5, 0x5e, 0xf5, 0x6d, 0xf5, 0x7b, 0xf5, + 0x89, 0xf5, 0x97, 0xf5, 0xa6, 0xf5, 0xb4, 0xf5, 0xc2, 0xf5, 0xd0, 0xf5, + 0xde, 0xf5, 0xec, 0xf5, 0xfa, 0xf5, 0x08, 0xf6, 0x16, 0xf6, 0x23, 0xf6, + 0x31, 0xf6, 0x3f, 0xf6, 0x4d, 0xf6, 0x5a, 0xf6, 0x68, 0xf6, 0x76, 0xf6, + 0x83, 0xf6, 0x91, 0xf6, 0x9e, 0xf6, 0xac, 0xf6, 0xb9, 0xf6, 0xc6, 0xf6, + 0xd4, 0xf6, 0xe1, 0xf6, 0xee, 0xf6, 0xfc, 0xf6, 0x09, 0xf7, 0x16, 0xf7, + 0x23, 0xf7, 0x30, 0xf7, 0x3d, 0xf7, 0x4a, 0xf7, 0x57, 0xf7, 0x64, 0xf7, + 0x71, 0xf7, 0x7e, 0xf7, 0x8b, 0xf7, 0x98, 0xf7, 0xa4, 0xf7, 0xb1, 0xf7, + 0xbe, 0xf7, 0xca, 0xf7, 0xd7, 0xf7, 0xe4, 0xf7, 0xf0, 0xf7, 0xfd, 0xf7, + 0x09, 0xf8, 0x15, 0xf8, 0x22, 0xf8, 0x2e, 0xf8, 0x3a, 0xf8, 0x47, 0xf8, + 0x53, 0xf8, 0x5f, 0xf8, 0x6b, 0xf8, 0x77, 0xf8, 0x84, 0xf8, 0x90, 0xf8, + 0x9c, 0xf8, 0xa8, 0xf8, 0xb4, 0xf8, 0xbf, 0xf8, 0xcb, 0xf8, 0xd7, 0xf8, + 0xe3, 0xf8, 0xef, 0xf8, 0xfa, 0xf8, 0x06, 0xf9, 0x12, 0xf9, 0x1d, 0xf9, + 0x29, 0xf9, 0x34, 0xf9, 0x40, 0xf9, 0x4b, 0xf9, 0x57, 0xf9, 0x62, 0xf9, + 0x6d, 0xf9, 0x79, 0xf9, 0x84, 0xf9, 0x8f, 0xf9, 0x9a, 0xf9, 0xa5, 0xf9, + 0xb1, 0xf9, 0xbc, 0xf9, 0xc7, 0xf9, 0xd2, 0xf9, 0xdd, 0xf9, 0xe8, 0xf9, + 0xf2, 0xf9, 0xfd, 0xf9, 0x08, 0xfa, 0x13, 0xfa, 0x1e, 0xfa, 0x28, 0xfa, + 0x33, 0xfa, 0x3e, 0xfa, 0x48, 0xfa, 0x53, 0xfa, 0x5d, 0xfa, 0x68, 0xfa, + 0x72, 0xfa, 0x7c, 0xfa, 0x87, 0xfa, 0x91, 0xfa, 0x9b, 0xfa, 0xa6, 0xfa, + 0xb0, 0xfa, 0xba, 0xfa, 0xc4, 0xfa, 0xce, 0xfa, 0xd8, 0xfa, 0xe2, 0xfa, + 0xec, 0xfa, 0xf6, 0xfa, 0x00, 0xfb, 0x0a, 0xfb, 0x14, 0xfb, 0x1e, 0xfb, + 0x27, 0xfb, 0x31, 0xfb, 0x3b, 0xfb, 0x44, 0xfb, 0x4e, 0xfb, 0x57, 0xfb, + 0x61, 0xfb, 0x6a, 0xfb, 0x74, 0xfb, 0x7d, 0xfb, 0x87, 0xfb, 0x90, 0xfb, + 0x99, 0xfb, 0xa3, 0xfb, 0xac, 0xfb, 0xb5, 0xfb, 0xbe, 0xfb, 0xc7, 0xfb, + 0xd0, 0xfb, 0xd9, 0xfb, 0xe2, 0xfb, 0xeb, 0xfb, 0xf4, 0xfb, 0xfd, 0xfb, + 0x06, 0xfc, 0x0f, 0xfc, 0x17, 0xfc, 0x20, 0xfc, 0x29, 0xfc, 0x32, 0xfc, + 0x3a, 0xfc, 0x43, 0xfc, 0x4b, 0xfc, 0x54, 0xfc, 0x5c, 0xfc, 0x65, 0xfc, + 0x6d, 0xfc, 0x75, 0xfc, 0x7e, 0xfc, 0x86, 0xfc, 0x8e, 0xfc, 0x96, 0xfc, + 0x9f, 0xfc, 0xa7, 0xfc, 0xaf, 0xfc, 0xb7, 0xfc, 0xbf, 0xfc, 0xc7, 0xfc, + 0xcf, 0xfc, 0xd7, 0xfc, 0xde, 0xfc, 0xe6, 0xfc, 0xee, 0xfc, 0xf6, 0xfc, + 0xfd, 0xfc, 0x05, 0xfd, 0x0d, 0xfd, 0x14, 0xfd, 0x1c, 0xfd, 0x23, 0xfd, + 0x2b, 0xfd, 0x32, 0xfd, 0x3a, 0xfd, 0x41, 0xfd, 0x48, 0xfd, 0x50, 0xfd, + 0x57, 0xfd, 0x5e, 0xfd, 0x65, 0xfd, 0x6c, 0xfd, 0x73, 0xfd, 0x7b, 0xfd, + 0x82, 0xfd, 0x89, 0xfd, 0x8f, 0xfd, 0x96, 0xfd, 0x9d, 0xfd, 0xa4, 0xfd, + 0xab, 0xfd, 0xb2, 0xfd, 0xb8, 0xfd, 0xbf, 0xfd, 0xc6, 0xfd, 0xcc, 0xfd, + 0xd3, 0xfd, 0xd9, 0xfd, 0xe0, 0xfd, 0xe6, 0xfd, 0xed, 0xfd, 0xf3, 0xfd, + 0xf9, 0xfd, 0x00, 0xfe, 0x06, 0xfe, 0x0c, 0xfe, 0x12, 0xfe, 0x18, 0xfe, + 0x1e, 0xfe, 0x24, 0xfe, 0x2a, 0xfe, 0x30, 0xfe, 0x36, 0xfe, 0x3c, 0xfe, + 0x42, 0xfe, 0x48, 0xfe, 0x4e, 0xfe, 0x54, 0xfe, 0x59, 0xfe, 0x5f, 0xfe, + 0x65, 0xfe, 0x6a, 0xfe, 0x70, 0xfe, 0x75, 0xfe, 0x7b, 0xfe, 0x80, 0xfe, + 0x86, 0xfe, 0x8b, 0xfe, 0x90, 0xfe, 0x96, 0xfe, 0x9b, 0xfe, 0xa0, 0xfe, + 0xa5, 0xfe, 0xaa, 0xfe, 0xaf, 0xfe, 0xb4, 0xfe, 0xba, 0xfe, 0xbe, 0xfe, + 0xc3, 0xfe, 0xc8, 0xfe, 0xcd, 0xfe, 0xd2, 0xfe, 0xd7, 0xfe, 0xdc, 0xfe, + 0xe0, 0xfe, 0xe5, 0xfe, 0xea, 0xfe, 0xee, 0xfe, 0xf3, 0xfe, 0xf7, 0xfe, + 0xfc, 0xfe, 0x00, 0xff, 0x05, 0xff, 0x09, 0xff, 0x0d, 0xff, 0x12, 0xff, + 0x16, 0xff, 0x1a, 0xff, 0x1e, 0xff, 0x22, 0xff, 0x27, 0xff, 0x2b, 0xff, + 0x2f, 0xff, 0x33, 0xff, 0x37, 0xff, 0x3a, 0xff, 0x3e, 0xff, 0x42, 0xff, + 0x46, 0xff, 0x4a, 0xff, 0x4d, 0xff, 0x51, 0xff, 0x55, 0xff, 0x58, 0xff, + 0x5c, 0xff, 0x5f, 0xff, 0x63, 0xff, 0x66, 0xff, 0x6a, 0xff, 0x6d, 0xff, + 0x70, 0xff, 0x74, 0xff, 0x77, 0xff, 0x7a, 0xff, 0x7d, 0xff, 0x81, 0xff, + 0x84, 0xff, 0x87, 0xff, 0x8a, 0xff, 0x8d, 0xff, 0x90, 0xff, 0x93, 0xff, + 0x95, 0xff, 0x98, 0xff, 0x9b, 0xff, 0x9e, 0xff, 0xa1, 0xff, 0xa3, 0xff, + 0xa6, 0xff, 0xa8, 0xff, 0xab, 0xff, 0xae, 0xff, 0xb0, 0xff, 0xb3, 0xff, + 0xb5, 0xff, 0xb7, 0xff, 0xba, 0xff, 0xbc, 0xff, 0xbe, 0xff, 0xc0, 0xff, + 0xc3, 0xff, 0xc5, 0xff, 0xc7, 0xff, 0xc9, 0xff, 0xcb, 0xff, 0xcd, 0xff, + 0xcf, 0xff, 0xd1, 0xff, 0xd3, 0xff, 0xd4, 0xff, 0xd6, 0xff, 0xd8, 0xff, + 0xda, 0xff, 0xdb, 0xff, 0xdd, 0xff, 0xdf, 0xff, 0xe0, 0xff, 0xe2, 0xff, + 0xe3, 0xff, 0xe5, 0xff, 0xe6, 0xff, 0xe7, 0xff, 0xe9, 0xff, 0xea, 0xff, + 0xeb, 0xff, 0xec, 0xff, 0xee, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xf1, 0xff, + 0xf2, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf6, 0xff, + 0xf7, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xfb, 0xff, + 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, + 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xca, 0x02, 0x09, 0xcd, 0x30, 0x01, + 0x0d, 0x69, 0x70, 0x1a, 0x09, 0xc9, 0x10, 0x06, 0x23, 0x4d, 0x9c, 0xc2, + 0x0d, 0xc9, 0x14, 0x02, 0x0d, 0xc9, 0x14, 0x02, 0x89, 0xc9, 0x38, 0x04, + 0x63, 0xcd, 0x98, 0xc2, 0x09, 0xc9, 0x30, 0x00, 0x05, 0x6b, 0x50, 0x37, + 0x2b, 0xcf, 0x94, 0xc0, 0x09, 0xcb, 0x4a, 0x02, 0xc1, 0xf0, 0x48, 0x35, + 0x09, 0x4d, 0x34, 0x03, 0x01, 0xc9, 0x34, 0x03, 0x09, 0xc9, 0x14, 0x2e, + 0x81, 0x5d, 0x15, 0x06, 0x01, 0xc9, 0x3c, 0x06, 0x41, 0xcd, 0x3c, 0x06, + 0x09, 0x4b, 0x30, 0x2c, 0x41, 0x4f, 0x30, 0x04, 0x81, 0xef, 0x70, 0x3d, + 0xa1, 0x59, 0x11, 0x03, 0x91, 0xcf, 0x20, 0x02, 0x81, 0xcb, 0x22, 0x06, + 0xc1, 0xd9, 0x08, 0x00, 0x95, 0x4b, 0x09, 0x6f, 0x92, 0x99, 0x63, 0xe6, + 0x2a, 0x07, 0xb2, 0x1a, 0x9b, 0xf0, 0x9c, 0xd9, 0xc5, 0x6f, 0x70, 0x36, + 0x05, 0x6f, 0x48, 0x37, 0x2b, 0xcb, 0x94, 0xc6, 0x27, 0x6f, 0xc8, 0xf5, + 0x2b, 0xcb, 0x94, 0xc6, 0x27, 0x6f, 0xc8, 0xf7, 0x2b, 0xcb, 0x94, 0xc6, + 0x27, 0x6d, 0xcc, 0xf5, 0x2f, 0x6d, 0xf4, 0xf5, 0x2b, 0xcb, 0x94, 0xc6, + 0xc5, 0xd9, 0x48, 0x28, 0x2b, 0x49, 0x94, 0xc2, 0x2b, 0x4f, 0x92, 0xc0, + 0xc1, 0xb4, 0x08, 0x2d, 0xe6, 0x9a, 0xdd, 0x79, 0x05, 0x69, 0x50, 0x37, + 0x2b, 0xcf, 0x94, 0xc0, 0x08, 0x08, 0x10, 0x02, 0x41, 0xc9, 0x38, 0x06, + 0x0d, 0x6d, 0x50, 0x36, 0x41, 0x4d, 0x10, 0x02, 0x09, 0x4d, 0x30, 0x00, + 0x41, 0xc9, 0x30, 0x0a, 0xd0, 0xbd, 0x08, 0x20, 0x2f, 0x6b, 0xf0, 0xf6, + 0x27, 0x69, 0xdc, 0xf4, 0x27, 0x6f, 0xcc, 0xf1, 0x2b, 0xcb, 0x90, 0xc6, + 0x2b, 0x4f, 0x94, 0xc2, 0x2f, 0x66, 0xf4, 0xf4, 0x2b, 0x42, 0x94, 0xc0, + 0xc1, 0xd9, 0x08, 0x20, 0xe7, 0xdb, 0xdd, 0x79, 0xe5, 0xdd, 0x59, 0x33, + 0x08, 0xc4, 0x18, 0x00, 0x09, 0xcd, 0x0a, 0x00, 0x2a, 0x43, 0x94, 0xc5, + 0x91, 0xdf, 0x30, 0x22, 0xc5, 0x91, 0x48, 0x28, 0xc0, 0xd8, 0x08, 0x20, + 0xc1, 0x94, 0x48, 0x2d, 0x2a, 0x8a, 0x9c, 0xe3, 0xc4, 0x98, 0x48, 0x28, + 0xf5, 0xdd, 0x59, 0x33, 0xe7, 0xd2, 0xdd, 0x7c, 0x09, 0x44, 0x34, 0x00, + 0xe6, 0x9b, 0xdd, 0x78, 0x2b, 0xcb, 0x9c, 0xe2, 0x45, 0x6d, 0x54, 0x37, + 0x89, 0x4d, 0x06, 0x00, 0x09, 0x5b, 0x30, 0x00, 0x49, 0x56, 0x10, 0x04, + 0x08, 0x0f, 0x10, 0x04, 0x49, 0x56, 0x18, 0x00, 0x08, 0x0f, 0x10, 0x00, + 0xc7, 0xdf, 0xd8, 0xfd, 0x09, 0x05, 0x0a, 0x04, 0x09, 0x49, 0x14, 0x06, + 0x09, 0x4d, 0x1c, 0x02, 0x09, 0x00, 0x0e, 0x02, 0x09, 0x40, 0x34, 0x03, + 0x08, 0x8d, 0x14, 0x02, 0x91, 0xcb, 0x20, 0x03, 0x45, 0x25, 0x44, 0x37, + 0x2b, 0xcb, 0x94, 0xe3, 0xe7, 0x92, 0xdd, 0x7c, 0xc1, 0xb5, 0x08, 0x2c, + 0xc1, 0xd9, 0x48, 0x04, 0xe7, 0x93, 0xdd, 0x79, 0x2b, 0x02, 0x9c, 0xc2, + 0x2e, 0x60, 0xf0, 0xf5, 0x2e, 0x62, 0xb4, 0xe8, 0xc1, 0xd0, 0x08, 0x20, + 0xe6, 0xda, 0xdd, 0x7c, 0x09, 0x49, 0x34, 0x00, 0x09, 0xcd, 0x38, 0x00, + 0x01, 0x49, 0x14, 0x06, 0x09, 0xcd, 0x14, 0x00, 0xc9, 0x85, 0x6c, 0x33, + 0x00, 0x4e, 0x10, 0x00, 0x08, 0xcc, 0x10, 0x02, 0xc0, 0x48, 0x3c, 0x03, + 0xcc, 0xe8, 0x24, 0x23, 0xdc, 0xea, 0x28, 0x21, 0x89, 0xe9, 0x78, 0x24, + 0xe7, 0xdb, 0xdd, 0x78, 0xc0, 0x98, 0x08, 0x31, 0xc9, 0xc9, 0x2c, 0x20, + 0x91, 0xcb, 0x22, 0x03, 0x81, 0xcf, 0x30, 0x06, 0x09, 0x05, 0x34, 0x02, + 0x08, 0x48, 0x0a, 0x02, 0x08, 0x0a, 0x30, 0x04, 0x08, 0x8e, 0x18, 0x00, + 0x40, 0x0e, 0x38, 0x01, 0x08, 0x08, 0x10, 0x03, 0x08, 0x08, 0x10, 0x01, + 0x09, 0xdf, 0x30, 0x00, 0x41, 0x4f, 0x38, 0x01, 0x41, 0xcf, 0x38, 0x06, + 0xe3, 0x5d, 0x10, 0x01, 0xc1, 0xcf, 0x30, 0x02, 0xc3, 0x5f, 0x14, 0x01, + 0x24, 0x26, 0xc5, 0xbf, 0x40, 0x4c, 0x14, 0x02, 0x08, 0x48, 0x10, 0x03, + 0x41, 0x49, 0x04, 0x02, 0x09, 0x49, 0x10, 0x01, 0x89, 0xc9, 0x3c, 0x15, + 0xc1, 0xd9, 0x08, 0x20, 0x81, 0xcd, 0x26, 0x00, 0x91, 0xcb, 0x20, 0x03, + 0x89, 0x15, 0x20, 0x00, 0x88, 0x5c, 0x28, 0x00, 0xc1, 0xd9, 0x08, 0x20, + 0xe7, 0x92, 0xdd, 0x7c, 0x41, 0x80, 0x08, 0x00, 0x41, 0x80, 0x00, 0x02, + 0x01, 0x80, 0x00, 0x01, 0xe6, 0xdb, 0xdd, 0x79, 0x40, 0xc4, 0x08, 0x04, + 0x40, 0x85, 0x08, 0x01, 0xc8, 0x98, 0x30, 0x00, 0xc1, 0xd9, 0x08, 0x20, + 0xe6, 0x9a, 0xdd, 0x7c, 0xc8, 0x1c, 0x28, 0x00, 0xc0, 0x98, 0x08, 0x20, + 0xe7, 0xdb, 0xdd, 0x79, 0xc1, 0xc9, 0x30, 0x08, 0x91, 0xc9, 0x22, 0x08, + 0xc1, 0xd9, 0x48, 0x3c, 0xc0, 0xb9, 0x08, 0x35, 0xe7, 0x93, 0xdd, 0x78, + 0x85, 0x21, 0x34, 0x28, 0x41, 0x81, 0x3c, 0x08, 0x85, 0x21, 0x30, 0x2a, + 0x41, 0x81, 0x38, 0x06, 0xc1, 0x01, 0x30, 0x06, 0xc1, 0x81, 0x18, 0x20, + 0xc1, 0x05, 0x30, 0x00, 0x41, 0x81, 0x1a, 0x04, 0x40, 0xc8, 0x1a, 0x01, + 0x08, 0x8d, 0x38, 0x00, 0xc1, 0xf9, 0x08, 0x1c, 0xe7, 0xdb, 0xdd, 0x79, + 0x41, 0x81, 0x0a, 0x05, 0x40, 0xcc, 0x0a, 0x05, 0x85, 0x7d, 0x70, 0x11, + 0x91, 0xcb, 0x20, 0x03, 0xc1, 0xd9, 0x48, 0x01, 0x45, 0x25, 0x50, 0x31, + 0xe6, 0xda, 0xdd, 0x79, 0x2f, 0x6f, 0xf4, 0xf3, 0x2b, 0xcb, 0x9c, 0xc6, + 0x27, 0x6f, 0xdc, 0xf5, 0x2b, 0xcb, 0x9c, 0xc6, 0x27, 0x6f, 0xd8, 0xf7, + 0x2b, 0xcb, 0x9c, 0xc6, 0x27, 0x6f, 0xd8, 0xf5, 0x2b, 0xcb, 0x9c, 0xc6, + 0x27, 0x6d, 0xdc, 0xf7, 0xa3, 0xc0, 0xa6, 0xc6, 0xc1, 0xf0, 0x08, 0x1d, + 0xb3, 0xcd, 0xa4, 0xc2, 0xa7, 0x69, 0xb4, 0xea, 0xc1, 0xd9, 0x48, 0x01, + 0x09, 0x4d, 0x30, 0x01, 0x09, 0xed, 0x18, 0x09, 0xc5, 0xd1, 0x48, 0x28, + 0x05, 0x69, 0x50, 0x37, 0x2b, 0xcf, 0x94, 0xc0, 0x01, 0x4d, 0x38, 0x00, + 0x81, 0xe9, 0x22, 0x02, 0x08, 0x8d, 0x18, 0x00, 0x81, 0xc9, 0x62, 0x02, + 0xc4, 0x2d, 0x78, 0x11, 0xc5, 0xd9, 0x48, 0x28, 0x09, 0xef, 0x18, 0x0f, + 0x05, 0x69, 0x54, 0x35, 0x2b, 0xcf, 0x94, 0xc0, 0x41, 0xc9, 0x38, 0x20, + 0xc1, 0x49, 0x30, 0x04, 0x89, 0xcb, 0x78, 0x1a, 0xc5, 0xd9, 0x48, 0x28, + 0x05, 0x69, 0x50, 0x35, 0x2b, 0xcf, 0x94, 0xc0, 0x09, 0x4b, 0x30, 0x02, + 0x41, 0xcf, 0x30, 0x03, 0xc5, 0xe9, 0x70, 0x10, 0x83, 0x59, 0x90, 0x42, + 0x83, 0x59, 0x9c, 0x42, 0xa3, 0x59, 0x90, 0x40, 0xc4, 0xbc, 0x48, 0x28, + 0xe7, 0xd2, 0xdd, 0x79, 0x09, 0x40, 0x30, 0x02, 0xe6, 0x9b, 0xdd, 0x7c, + 0x81, 0xcd, 0x30, 0x2d, 0x81, 0xcd, 0x30, 0x2f, 0x09, 0x4b, 0x34, 0x02, + 0x09, 0x4f, 0x1e, 0x02, 0x49, 0x4f, 0x3c, 0x07, 0x09, 0xcf, 0x1c, 0x02, + 0x2b, 0x44, 0xb0, 0xc0, 0x2a, 0x09, 0xb0, 0xc0, 0xa7, 0x7f, 0x7d, 0xd7, + 0xa7, 0x7d, 0xfc, 0x57, 0xc1, 0xcb, 0x30, 0x23, 0xc5, 0xfd, 0x48, 0x28, + 0x09, 0xcb, 0x0a, 0x12, 0xc4, 0x9d, 0x48, 0x29, 0x09, 0xeb, 0x4a, 0x12, + 0xc4, 0xb9, 0x48, 0x04, 0x19, 0x4d, 0x34, 0x01, 0x81, 0xcd, 0x34, 0x2d, + 0x21, 0x4b, 0xb1, 0x44, 0x21, 0x4b, 0xbb, 0x44, 0xe7, 0xd2, 0xdd, 0x79, + 0xe6, 0x9b, 0xdd, 0x7c, 0xc1, 0x45, 0x38, 0x00, 0xc1, 0x41, 0x38, 0x02, + 0xc1, 0x45, 0x38, 0x00, 0x09, 0xc9, 0x34, 0x02, 0x91, 0xc9, 0x24, 0x08, + 0xc5, 0xf4, 0x08, 0x2c, 0xc5, 0xb1, 0x08, 0x25, 0x81, 0xc9, 0x26, 0x20, + 0xc4, 0xbd, 0x08, 0x05, 0x81, 0xc9, 0x26, 0x01, 0x19, 0xc0, 0x08, 0x00, + 0xc5, 0x74, 0x78, 0x11, 0x19, 0xc0, 0x08, 0x02, 0xc5, 0x74, 0x78, 0x13, + 0xc5, 0xf4, 0x08, 0x09, 0x09, 0xeb, 0x30, 0x00, 0x49, 0x49, 0x32, 0x00, + 0x81, 0xd9, 0x34, 0x21, 0x59, 0x4d, 0x32, 0x02, 0xc0, 0x89, 0x3c, 0x01, + 0x81, 0xc9, 0x26, 0x04, 0xc4, 0x98, 0x08, 0x2c, 0x41, 0xcd, 0x32, 0x00, + 0x08, 0x0d, 0x16, 0x02, 0x01, 0xdd, 0x36, 0x02, 0x01, 0xdd, 0x32, 0x00, + 0x8d, 0xcf, 0x38, 0x25, 0x91, 0xc9, 0x24, 0x01, 0x08, 0x4c, 0x3c, 0x06, + 0x18, 0x48, 0x38, 0x00, 0x08, 0xcc, 0x1c, 0x02, 0x91, 0xcd, 0x24, 0x00, + 0x08, 0x4c, 0x30, 0x04, 0xc5, 0xd9, 0x48, 0x28, 0x51, 0xcd, 0x32, 0x02, + 0x01, 0xdd, 0x34, 0x02, 0x8c, 0xca, 0x38, 0x2c, 0x89, 0x4d, 0x32, 0x04, + 0x01, 0xdd, 0x38, 0x02, 0x41, 0xcd, 0x34, 0x02, 0x8d, 0xcf, 0x38, 0x29, + 0x81, 0xc9, 0x26, 0x20, 0x09, 0x59, 0x30, 0x00, 0x81, 0xc9, 0x26, 0x01, + 0x91, 0xcd, 0x24, 0x00, 0x09, 0x15, 0x30, 0x00, 0xc5, 0xd9, 0x48, 0x28, + 0x99, 0x4d, 0x02, 0x00, 0x09, 0x81, 0x30, 0x01, 0x08, 0xc8, 0x30, 0x04, + 0x08, 0x8d, 0x30, 0x00, 0x91, 0x49, 0x38, 0x04, 0xc5, 0x7d, 0x70, 0x11, + 0xc5, 0xd9, 0x48, 0x28, 0x19, 0xcd, 0x0c, 0x25, 0x09, 0x05, 0x38, 0x02, + 0x09, 0x49, 0x34, 0x06, 0x81, 0xc9, 0x34, 0x23, 0x09, 0x4d, 0x14, 0x04, + 0x09, 0xc9, 0x0e, 0x2c, 0x09, 0xc0, 0x1c, 0x09, 0x41, 0xcd, 0x3c, 0x04, + 0x09, 0xcd, 0x54, 0x00, 0xe1, 0x59, 0x11, 0xc6, 0x24, 0x22, 0xc5, 0xbb, + 0x01, 0x4d, 0x30, 0x00, 0xc5, 0xd9, 0x48, 0x28, 0x81, 0xc9, 0x26, 0x20, + 0xc4, 0xd8, 0x48, 0x04, 0x91, 0xcd, 0x24, 0x00, 0x09, 0x44, 0x38, 0x00, + 0x08, 0xc4, 0x18, 0x00, 0x48, 0x0d, 0x30, 0x00, 0xc5, 0xd9, 0x48, 0x28, + 0x91, 0xc9, 0x24, 0x04, 0xc4, 0x99, 0x48, 0x24, 0x09, 0xa1, 0x30, 0x00, + 0x41, 0x85, 0x3a, 0x02, 0x8d, 0x84, 0x78, 0x01, 0x08, 0xcc, 0x30, 0x00, + 0x40, 0x4c, 0x38, 0x00, 0xc5, 0xd9, 0x48, 0x28, 0x09, 0xc9, 0x30, 0x00, + 0x09, 0x83, 0x30, 0x08, 0x41, 0x85, 0x3a, 0x02, 0x01, 0x95, 0x3c, 0x02, + 0x41, 0x85, 0x3a, 0x02, 0x01, 0x95, 0x3c, 0x02, 0x41, 0x81, 0x38, 0x04, + 0xc1, 0x85, 0x30, 0x00, 0x89, 0x01, 0x36, 0x02, 0x41, 0x81, 0x30, 0x04, + 0x01, 0x95, 0x38, 0x00, 0x8d, 0x83, 0x78, 0x21, 0x08, 0x4c, 0x0a, 0x00, + 0x84, 0x7c, 0x78, 0x11, 0x45, 0x6d, 0x40, 0x35, 0x2b, 0xcb, 0x94, 0xc3, + 0x81, 0xcb, 0x66, 0x00, 0xc1, 0xd9, 0x08, 0x20, 0x79, 0x9f, 0xaf, 0xff, + 0x09, 0xc9, 0x30, 0x06, 0x09, 0x4f, 0x34, 0x03, 0x81, 0xcb, 0x34, 0x2b, + 0x91, 0xeb, 0x20, 0x02, 0xc5, 0xf9, 0x48, 0x0c, 0x09, 0x4d, 0x30, 0x03, + 0x41, 0xcd, 0x30, 0x03, 0x81, 0xcd, 0x30, 0x06, 0x81, 0xcb, 0x22, 0x0a, + 0xe6, 0x9b, 0xdd, 0x79, 0x40, 0x0d, 0x38, 0x00, 0x81, 0xcb, 0x22, 0x22, + 0x91, 0xcb, 0x20, 0x03, 0x2b, 0x82, 0x9c, 0xc3, 0x45, 0x26, 0x54, 0x37, + 0xc2, 0xdd, 0xd5, 0x48, 0xe4, 0xd9, 0x59, 0x37, 0x81, 0xcb, 0x22, 0x22, + 0x08, 0x4b, 0x34, 0x07, 0x09, 0x4b, 0x14, 0x02, 0x0c, 0x66, 0x54, 0x36, + 0x0c, 0x23, 0x54, 0x33, 0x0c, 0x2e, 0x54, 0x33, 0x41, 0xcd, 0x38, 0x06, + 0xe3, 0x5d, 0x11, 0xc0, 0xc1, 0xcd, 0x30, 0x02, 0xc3, 0x5f, 0x94, 0x40, + 0x81, 0xcf, 0x30, 0x06, 0xe1, 0xdd, 0x19, 0x0f, 0xc5, 0x94, 0x48, 0x11, + 0xe6, 0xd2, 0xdd, 0x79, 0xc4, 0xf4, 0x08, 0x1d, 0x08, 0x0c, 0x30, 0x05, + 0x80, 0x0c, 0x30, 0x11, 0xc4, 0x98, 0x48, 0x28, 0xe5, 0xdd, 0x59, 0x1e, + 0x91, 0xeb, 0x64, 0x2d, 0xe7, 0x93, 0xdd, 0x79, 0xc5, 0xb1, 0x08, 0x19, + 0xe5, 0xdd, 0xdd, 0x53, 0x91, 0xeb, 0x24, 0x00, 0x08, 0x09, 0x34, 0x05, + 0xe0, 0xbd, 0xdd, 0x5e, 0x2b, 0xcb, 0x9c, 0xc3, 0xc4, 0xb9, 0x08, 0x19, + 0x81, 0xcb, 0x26, 0x08, 0xc4, 0xfc, 0x08, 0x34, 0x91, 0xcb, 0x24, 0x01, + 0xc4, 0xb9, 0x08, 0x11, 0x81, 0xcb, 0x26, 0x20, 0xc4, 0x9d, 0x08, 0x3c, + 0xa3, 0xdf, 0x99, 0x46, 0xe7, 0xdb, 0xdd, 0x78, 0xa3, 0xdb, 0x99, 0x42, + 0x2b, 0x83, 0x94, 0xc3, 0x09, 0x85, 0x34, 0x02, 0xe5, 0xdd, 0x59, 0x33, + 0x89, 0x4d, 0x06, 0x00, 0x09, 0x5d, 0x10, 0x04, 0xc7, 0xdf, 0xd8, 0xfd, + 0x2b, 0x42, 0x94, 0xc5, 0xc5, 0xf9, 0x08, 0x1d, 0xc1, 0xcd, 0x10, 0x00, + 0x09, 0xe9, 0x30, 0x02, 0x09, 0xcd, 0x34, 0x0d, 0x00, 0xcc, 0x34, 0x00, + 0x81, 0x49, 0x22, 0x04, 0x01, 0x95, 0x30, 0x00, 0x00, 0xdc, 0x38, 0x00, + 0x8d, 0xcd, 0x3a, 0x3f, 0xc5, 0xfd, 0x08, 0x1c, 0x81, 0xcb, 0x26, 0x20, + 0x41, 0x80, 0x38, 0x28, 0x41, 0x90, 0x30, 0x28, 0x40, 0xc0, 0x38, 0x08, + 0x40, 0xd0, 0x30, 0x08, 0xc4, 0x3d, 0x78, 0x11, 0xc5, 0xfd, 0x08, 0x1c, + 0x09, 0xdd, 0x10, 0x00, 0x81, 0xcb, 0x26, 0x01, 0x91, 0xcb, 0x24, 0x04, + 0x41, 0x14, 0x38, 0x05, 0x41, 0x14, 0x38, 0x05, 0x80, 0xe4, 0x70, 0x3d, + 0x80, 0x05, 0x30, 0x11, 0x81, 0xcb, 0x26, 0x20, 0x45, 0x64, 0x40, 0x35, + 0x81, 0xcb, 0x26, 0x10, 0x2a, 0x8b, 0x94, 0xc3, 0xa1, 0xd9, 0x95, 0x62, + 0x91, 0xcb, 0x22, 0x23, 0x41, 0x05, 0x00, 0x05, 0xc1, 0x91, 0x08, 0x20, + 0x09, 0xc4, 0x3c, 0x00, 0x41, 0x54, 0x3c, 0x05, 0x45, 0x60, 0x7c, 0x30, + 0xc5, 0x64, 0x7c, 0x11, 0x41, 0x54, 0x38, 0x05, 0x41, 0x54, 0x38, 0x05, + 0x45, 0x60, 0x78, 0x30, 0x85, 0x64, 0x74, 0x3d, 0xc1, 0x40, 0x30, 0x04, + 0x2b, 0x4b, 0xb5, 0xc2, 0xc1, 0xd9, 0x08, 0x20, 0x91, 0xcb, 0x22, 0x23, + 0x41, 0x05, 0x10, 0x05, 0xc5, 0x91, 0x48, 0x28, 0x0d, 0x6d, 0x70, 0x3d, + 0x45, 0x60, 0x70, 0x30, 0x41, 0x54, 0x38, 0x05, 0x41, 0x54, 0x38, 0x05, + 0xc5, 0xd9, 0x48, 0x28, 0xc3, 0xfd, 0xd5, 0x48, 0x05, 0x6b, 0x54, 0x35, + 0x2b, 0xcf, 0x94, 0xc0, 0x81, 0xcb, 0x26, 0x10, 0x41, 0xcf, 0x3c, 0x28, + 0x41, 0xdf, 0x34, 0x28, 0x04, 0x2b, 0x50, 0x35, 0x2a, 0x8f, 0x94, 0xc0, + 0x40, 0x8b, 0x3c, 0x20, 0xc0, 0x0b, 0x34, 0x01, 0xc1, 0xd9, 0x08, 0x28, + 0x2b, 0xcb, 0x9c, 0xc3, 0x45, 0x6d, 0x54, 0x35, 0x2b, 0xcb, 0x9c, 0xc3, + 0x45, 0x6d, 0x50, 0x37, 0x2b, 0xcb, 0x9c, 0xc3, 0x45, 0x6d, 0x50, 0x35, + 0xc1, 0xd9, 0x08, 0x00, 0xc0, 0x0d, 0x3c, 0x00, 0xc0, 0x09, 0x38, 0x06, + 0xc0, 0x0d, 0x3c, 0x00, 0x89, 0x4d, 0x02, 0x00, 0x89, 0x40, 0x06, 0x00, + 0xc1, 0xd9, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0xc1, 0xc9, 0x30, 0x08, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x2b, 0x50, 0x35, 0x45, 0x64, 0x40, 0x35, 0x09, 0x4d, 0x34, 0x03, + 0x40, 0xcc, 0x0a, 0x05, 0xc5, 0xd9, 0x48, 0x28, 0x2b, 0x02, 0x9c, 0xc2, + 0x91, 0xcd, 0x24, 0x00, 0x09, 0x15, 0x30, 0x00, 0x2b, 0x4b, 0xb5, 0xc2, + 0x09, 0x4f, 0x1e, 0x02, 0x8d, 0x83, 0x78, 0x21, 0xc0, 0x09, 0x38, 0x06, + 0x81, 0xd9, 0x34, 0x21, 0xc1, 0xf0, 0x08, 0x1d, 0xe7, 0x92, 0xdd, 0x7c, + 0xc1, 0x49, 0x30, 0x04, 0x09, 0xeb, 0x4a, 0x12, 0x41, 0x05, 0x10, 0x05, + 0x00, 0x00, 0x10, 0x00, 0x81, 0xcb, 0x26, 0x20, 0xc7, 0xdf, 0xd8, 0xfd, + 0xa7, 0x69, 0xe3, 0x1c, 0xc1, 0xd4, 0x48, 0x0d, 0xc3, 0xdb, 0xdd, 0x37, + 0x2b, 0x6f, 0xf0, 0xb4, 0xc3, 0xdb, 0xdd, 0x37, 0x2b, 0x6f, 0xd0, 0xb4, + 0x63, 0xcf, 0xb0, 0x80, 0x0b, 0xeb, 0xf4, 0xbe, 0xc3, 0xdb, 0xdd, 0x37, + 0xa7, 0xdb, 0xb5, 0x02, 0xa7, 0xcf, 0xa7, 0x02, 0xc0, 0x9d, 0x48, 0x0d, + 0xa3, 0xeb, 0xa7, 0x1e, 0x23, 0xdf, 0xbd, 0x02, 0x8b, 0xcb, 0xbc, 0xa2, + 0xc3, 0x4f, 0xf1, 0xf8, 0xc3, 0x4f, 0xf5, 0xf8, 0x0b, 0xeb, 0xf4, 0xbe, + 0xb3, 0xcf, 0xa5, 0x02, 0xc3, 0xff, 0x9c, 0x1f, 0xa3, 0xeb, 0xa7, 0x1e, + 0x23, 0xdf, 0xbd, 0x02, 0x8b, 0xcb, 0xbc, 0x8e, 0x23, 0x69, 0xd0, 0x94, + 0x0b, 0xcb, 0xb4, 0xa2, 0xb3, 0xcd, 0xa0, 0x80, 0xc3, 0xff, 0x9c, 0x1f, + 0x63, 0xcd, 0xb0, 0x80, 0x8b, 0xcf, 0xbc, 0xaa, 0xe3, 0xdb, 0xd8, 0x32, + 0x0b, 0x6b, 0xf0, 0xb6, 0xcb, 0xeb, 0xe8, 0xa2, 0x0b, 0xcb, 0x8a, 0x83, + 0xc1, 0xf0, 0x48, 0x20, 0xe3, 0xdb, 0xd8, 0x32, 0x0b, 0x6b, 0xf4, 0xb6, + 0x0b, 0xcb, 0xb4, 0x80, 0xe3, 0xdb, 0xd8, 0x32, 0x63, 0x69, 0xc4, 0x95, + 0x0b, 0xcb, 0x94, 0x81, 0x8b, 0xef, 0xbc, 0x83, 0x0b, 0x6f, 0xf4, 0x96, + 0x0b, 0x6b, 0xdc, 0x97, 0x53, 0xcb, 0xb4, 0x86, 0x42, 0x68, 0xc0, 0x95, + 0x0a, 0xca, 0x94, 0x81, 0x8a, 0xea, 0xbc, 0xa3, 0x23, 0xc9, 0x98, 0xa4, + 0x2b, 0xc9, 0x98, 0x81, 0x43, 0x69, 0xc4, 0xb0, 0x2b, 0xc9, 0x98, 0x81, + 0x43, 0x69, 0xc4, 0xb0, 0x2b, 0xc9, 0xb0, 0x80, 0x23, 0x6d, 0xd4, 0x95, + 0x2b, 0x69, 0xd0, 0xb4, 0x0b, 0xcf, 0x94, 0x82, 0x8b, 0xef, 0xbc, 0x89, + 0xb3, 0xed, 0xe0, 0xbd, 0xc3, 0xfb, 0x9c, 0x1b, 0xc0, 0xf8, 0x48, 0x20, + 0x8b, 0xeb, 0xb8, 0xaf, 0xc1, 0xd9, 0x48, 0x2d, 0x0b, 0xcd, 0xb0, 0x82, + 0x0b, 0xcb, 0xb4, 0x80, 0xc3, 0xf9, 0x58, 0x28, 0x0b, 0xcb, 0xf4, 0x82, + 0x23, 0x69, 0xd0, 0x97, 0xc3, 0xdd, 0x1c, 0x9c, 0xc0, 0xb9, 0x48, 0x20, + 0x0b, 0xcf, 0x94, 0x80, 0x8b, 0xcb, 0xfc, 0x86, 0xe3, 0xff, 0x1c, 0x96, + 0x1b, 0x6f, 0xcc, 0x94, 0xc0, 0xd8, 0x48, 0x00, 0xc3, 0xfb, 0x9c, 0x1b, + 0xc1, 0xff, 0xdd, 0x8a, 0xc3, 0xd9, 0x1c, 0x9d, 0x23, 0x69, 0xd0, 0x95, + 0x3b, 0x6d, 0xc8, 0xb0, 0xc0, 0xf8, 0x48, 0x20, 0x0b, 0xcf, 0x94, 0x80, + 0x8b, 0xcb, 0xfc, 0xa3, 0xe3, 0xff, 0x1c, 0x96, 0xc3, 0xfb, 0x9c, 0x1b, + 0x0b, 0xc9, 0xb0, 0x82, 0x8b, 0xcb, 0xf8, 0xaf, 0xc1, 0xf9, 0x48, 0x20, + 0x0b, 0xc9, 0xb0, 0x82, 0xc1, 0xff, 0xdd, 0x8a, 0xc3, 0xd9, 0x1c, 0x9d, + 0x23, 0x69, 0xc0, 0x97, 0x0b, 0xcf, 0x94, 0x80, 0x8b, 0xcf, 0xfc, 0xaa, + 0xe3, 0xff, 0x1c, 0x96, 0x03, 0xcb, 0x9c, 0x85, 0x1b, 0xcb, 0x8c, 0x88, + 0xc0, 0xf8, 0x48, 0x20, 0x03, 0xcb, 0x94, 0x81, 0x83, 0xeb, 0xf4, 0xb8, + 0x43, 0xcb, 0x8c, 0x80, 0xab, 0xeb, 0xfd, 0x01, 0x03, 0xcb, 0x94, 0x81, + 0x43, 0xcb, 0x8c, 0x80, 0x43, 0xcb, 0x88, 0x84, 0x2b, 0xcb, 0x34, 0x80, + 0xe3, 0xff, 0x1c, 0x96, 0x1b, 0xc9, 0x88, 0x82, 0x0a, 0xc8, 0xb0, 0x82, + 0x28, 0xc8, 0xb0, 0x82, 0xc2, 0xfa, 0x9c, 0x1b, 0x0b, 0xcb, 0xb5, 0xc0, + 0x0b, 0xc9, 0xb0, 0x86, 0x43, 0xc9, 0x88, 0x82, 0x0b, 0xcb, 0xb4, 0x80, + 0xc3, 0xf9, 0x58, 0x28, 0x2b, 0xed, 0xb0, 0x92, 0xc3, 0xdd, 0x1c, 0x95, + 0xc0, 0xb9, 0x48, 0x20, 0x0b, 0x6f, 0xf4, 0x96, 0xc1, 0xd9, 0x08, 0x00, + 0xc3, 0xdf, 0x1c, 0x10, 0x2b, 0x69, 0xf0, 0x97, 0x63, 0xc9, 0xb0, 0xa2, + 0xc3, 0xdd, 0x1c, 0x9c, 0xc0, 0xb9, 0x48, 0x20, 0x2b, 0x69, 0xf0, 0x97, + 0xc3, 0xdd, 0x1c, 0x9c, 0xc0, 0xb9, 0x48, 0x20, 0xc1, 0xd9, 0x08, 0x00, + 0x0f, 0xcb, 0xb4, 0x9a, 0x2b, 0xe9, 0xb0, 0x92, 0xc3, 0xdd, 0x1c, 0x95, + 0x8a, 0x8b, 0xbc, 0x96, 0xc0, 0xb9, 0x48, 0x20, 0xc1, 0xd9, 0x08, 0x00, + 0x2b, 0xcd, 0xb0, 0xa0, 0x83, 0x4f, 0xf9, 0xfc, 0xc3, 0x4f, 0xf5, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x83, 0x4b, 0xfd, 0xfc, 0xc3, 0xf9, 0x1d, 0x9a, + 0xc3, 0x4f, 0xf1, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x69, 0xe7, 0x1c, + 0xab, 0xc0, 0xb8, 0xb0, 0xc1, 0xf0, 0x48, 0x20, 0xc3, 0x4b, 0xf5, 0xfc, + 0x63, 0xcd, 0xb8, 0x82, 0xe3, 0xcd, 0xb0, 0x82, 0xc1, 0xdd, 0x08, 0x1d, + 0x2f, 0xe9, 0xf0, 0xbf, 0x2b, 0xcd, 0xb0, 0xa0, 0xb7, 0xc9, 0xa0, 0x82, + 0x83, 0x4f, 0xf9, 0xfc, 0x23, 0xdd, 0xb8, 0x82, 0xc3, 0x5b, 0xf5, 0xfc, + 0xc3, 0xfd, 0x1d, 0x9a, 0xa7, 0x69, 0xe7, 0x1c, 0xc3, 0x4f, 0xf1, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xab, 0xc9, 0xb8, 0xb8, 0xa3, 0xed, 0xf0, 0xbf, + 0xc1, 0xd9, 0x08, 0x00, 0x2b, 0xcd, 0xb0, 0xa0, 0x83, 0x4f, 0xf9, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0xc3, 0x4b, 0xf5, 0xfc, 0xc3, 0xf9, 0x1d, 0x9a, + 0xc3, 0x4f, 0xf1, 0xfc, 0xc3, 0xf9, 0x1d, 0x9e, 0x83, 0x4b, 0xfd, 0xfc, + 0xc3, 0xfd, 0x1d, 0x9a, 0xa7, 0x69, 0xe7, 0x1c, 0xab, 0xe0, 0xb8, 0x91, + 0xc1, 0xf0, 0x48, 0x20, 0xc1, 0xd9, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xd9, 0x08, 0x00, + 0x2b, 0x4f, 0xf1, 0x39, 0xc3, 0xdb, 0xdd, 0x37, 0xc0, 0xbd, 0x08, 0x19, + 0x2b, 0x4f, 0xf1, 0x39, 0xa7, 0x69, 0xe3, 0x1c, 0xaa, 0xab, 0xb9, 0x38, + 0xc0, 0xb9, 0x48, 0x20, 0x83, 0x4f, 0xf9, 0xf8, 0xa7, 0x69, 0xe3, 0x1c, + 0xab, 0xe2, 0xb9, 0x39, 0xc1, 0xf0, 0x48, 0x20, 0xc3, 0x5f, 0xf9, 0xf8, + 0xa7, 0x69, 0xe3, 0x1c, 0xaa, 0x8b, 0xf9, 0x10, 0xc0, 0xb9, 0x48, 0x20, + 0xc3, 0x4f, 0xf1, 0xf8, 0xa7, 0x69, 0xe3, 0x1c, 0xab, 0xc2, 0xf9, 0x11, + 0xc1, 0xf0, 0x48, 0x20, 0xc1, 0xd9, 0x08, 0x00, 0x2b, 0x4f, 0xf1, 0x39, + 0x2b, 0xe9, 0xb0, 0x80, 0xc3, 0xdb, 0xdd, 0x37, 0x23, 0xdd, 0xb4, 0x80, + 0xab, 0xc9, 0xf8, 0xb4, 0xc1, 0xd9, 0x08, 0x00, 0xa7, 0x69, 0xe3, 0x1c, + 0xaa, 0x8b, 0xf9, 0x35, 0xc0, 0x9d, 0x48, 0x0d, 0x2b, 0x49, 0xf4, 0xbb, + 0xa7, 0x69, 0xe3, 0x1c, 0xab, 0xc2, 0xf9, 0x1c, 0xc1, 0xd4, 0x48, 0x0d, + 0x2b, 0x49, 0xdc, 0xbb, 0x2b, 0x69, 0xce, 0xb3, 0xc1, 0xd9, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x22, 0x42, 0xc1, 0x38, 0x22, 0x00, 0x80, 0xd8, + 0x02, 0x20, 0x84, 0x12, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xbf, 0xff, 0xbf, 0x00, 0x00, 0x80, 0x00, + 0x02, 0x40, 0x80, 0xc8, 0x09, 0xc9, 0x30, 0x00, 0xe4, 0xd9, 0x59, 0x37, + 0xe7, 0xdb, 0xdd, 0x79, 0xc0, 0x0d, 0x3c, 0x00, 0xe6, 0x9b, 0xdd, 0x78, + 0x41, 0xc9, 0x30, 0x0a, 0x40, 0x8b, 0x3c, 0x20, 0xc5, 0xd9, 0x48, 0x28, + 0xc1, 0xd9, 0x08, 0x00, 0x09, 0xcd, 0x34, 0x0d, 0xe7, 0x93, 0xdd, 0x79, + 0x00, 0x4e, 0x10, 0x00, 0xc1, 0xcd, 0x30, 0x02, 0x81, 0xcb, 0x66, 0x00, + 0xc4, 0xbd, 0x08, 0x05, 0xc1, 0xb5, 0x08, 0x2c, 0x09, 0x44, 0x34, 0x00, + 0xe7, 0x93, 0xdd, 0x78, 0xe6, 0xdb, 0xdd, 0x79, 0x80, 0x0c, 0x30, 0x11, + 0x01, 0x49, 0x14, 0x06, 0xc7, 0xdf, 0xd8, 0xfd, 0xc5, 0xd9, 0x48, 0x28, + 0xc5, 0x74, 0x78, 0x11, 0x41, 0x4f, 0x30, 0x04, 0x09, 0x05, 0x34, 0x02, + 0x01, 0x80, 0x00, 0x01, 0x23, 0x4d, 0x9c, 0xc2, 0xa1, 0x59, 0x11, 0x03, + 0xc1, 0xd0, 0x08, 0x20, 0x41, 0xc9, 0x30, 0x0a, 0xcc, 0xe8, 0x24, 0x23, + 0x19, 0x4d, 0x34, 0x01, 0x0c, 0x23, 0x54, 0x33, 0x09, 0xef, 0x18, 0x0f, + 0x2b, 0xcb, 0x94, 0xc6, 0x09, 0x4d, 0x34, 0x03, 0x41, 0xc9, 0x38, 0x06, + 0x08, 0x0f, 0x10, 0x04, 0x01, 0x80, 0x00, 0x01, 0x01, 0x49, 0x14, 0x06, + 0x91, 0xcd, 0x24, 0x00, 0x91, 0xcb, 0x22, 0x23, 0x2b, 0xcb, 0x94, 0xc6, + 0x81, 0xcd, 0x34, 0x2d, 0xc7, 0xdf, 0xd8, 0xfd, 0x00, 0xdc, 0x38, 0x00, + 0xc0, 0x0b, 0x34, 0x01, 0x45, 0x6d, 0x50, 0x35, 0xc1, 0xf9, 0x08, 0x1c, + 0x41, 0x54, 0x38, 0x05, 0x2b, 0xcb, 0x94, 0xc6, 0x81, 0xcb, 0x26, 0x10, + 0xa1, 0xd9, 0x95, 0x62, 0x2a, 0x09, 0xb0, 0xc0, 0x81, 0xc9, 0x26, 0x01, + 0xc5, 0x91, 0x48, 0x28, 0xc5, 0xd9, 0x48, 0x28, 0x85, 0x7d, 0x70, 0x11, + 0xc5, 0xd9, 0x48, 0x28, 0x45, 0x6d, 0x50, 0x35, 0x19, 0xc0, 0x08, 0x00, + 0x2b, 0xcb, 0x9c, 0xc3, 0x27, 0x6f, 0xdc, 0xf5, 0xc1, 0xcb, 0x30, 0x23, + 0x2b, 0xcf, 0x94, 0xc0, 0x45, 0x6d, 0x50, 0x35, 0x00, 0xdc, 0x38, 0x00, + 0x21, 0x4b, 0xb1, 0x44, 0x40, 0x8b, 0x3c, 0x20, 0xc1, 0xd9, 0x08, 0x00, + 0x0d, 0xc9, 0x14, 0x02, 0x45, 0x25, 0x50, 0x31, 0x08, 0x0a, 0x30, 0x04, + 0x81, 0xcb, 0x26, 0x20, 0x91, 0xcb, 0x22, 0x23, 0xc1, 0xd9, 0x48, 0x3c, + 0x09, 0x5b, 0x30, 0x00, 0x81, 0xcb, 0x34, 0x2b, 0x41, 0xc9, 0x30, 0x0a, + 0x09, 0x49, 0x14, 0x06, 0xe3, 0x5d, 0x11, 0xc0, 0x45, 0x6d, 0x54, 0x35, + 0x09, 0xcd, 0x14, 0x00, 0x05, 0x6b, 0x50, 0x37, 0x09, 0x00, 0x0e, 0x02, + 0x09, 0xcd, 0x38, 0x00, 0x8d, 0x83, 0x78, 0x21, 0x41, 0xc9, 0x38, 0x06, + 0x92, 0x99, 0x63, 0xe6, 0xc5, 0xd9, 0x48, 0x28, 0x95, 0x4b, 0x09, 0x6f, + 0x2b, 0xcb, 0x94, 0xc6, 0x0d, 0xc9, 0x14, 0x02, 0x88, 0x5c, 0x28, 0x00, + 0x2b, 0xcb, 0x9c, 0xc6, 0xc1, 0xd9, 0x48, 0x04, 0x41, 0x54, 0x38, 0x05, + 0x89, 0x4d, 0x32, 0x04, 0x84, 0x7c, 0x78, 0x11, 0x2f, 0x6f, 0xf4, 0xf3, + 0x9b, 0xf0, 0x9c, 0xd9, 0xc1, 0xd9, 0x08, 0x20, 0x91, 0xcd, 0x24, 0x00, + 0x09, 0x5d, 0x10, 0x04, 0x41, 0xdf, 0x34, 0x28, 0xc0, 0x0d, 0x3c, 0x00, + 0x27, 0x69, 0xdc, 0xf4, 0x2b, 0xcb, 0x94, 0xc6, 0xe6, 0x9b, 0xdd, 0x78, + 0xc1, 0xd9, 0x08, 0x20, 0x45, 0x6d, 0x54, 0x35, 0xc1, 0x05, 0x30, 0x00, + 0xa1, 0xd9, 0x95, 0x62, 0x91, 0xcf, 0x20, 0x02, 0x09, 0xcf, 0x1c, 0x02, + 0x41, 0xcd, 0x3c, 0x04, 0xe7, 0xdb, 0xdd, 0x79, 0x80, 0xe4, 0x70, 0x3d, + 0xc1, 0xd9, 0x08, 0x20, 0x05, 0x69, 0x50, 0x37, 0x41, 0x54, 0x38, 0x05, + 0x08, 0x8d, 0x30, 0x00, 0x45, 0x60, 0x78, 0x30, 0x81, 0xcd, 0x26, 0x00, + 0x41, 0x54, 0x38, 0x05, 0xc4, 0x3d, 0x78, 0x11, 0x41, 0xc9, 0x38, 0x06, + 0x81, 0xcf, 0x30, 0x06, 0xc1, 0xd9, 0x08, 0x20, 0xe7, 0x92, 0xdd, 0x7c, + 0x40, 0x4c, 0x14, 0x02, 0x81, 0xcf, 0x30, 0x06, 0x09, 0x4d, 0x30, 0x01, + 0x41, 0x80, 0x38, 0x28, 0xc0, 0x0d, 0x3c, 0x00, 0x27, 0x6d, 0xcc, 0xf5, + 0x09, 0x40, 0x30, 0x02, 0x09, 0xa1, 0x30, 0x00, 0x81, 0xcb, 0x26, 0x20, + 0x27, 0x6f, 0xd8, 0xf7, 0x01, 0x4d, 0x38, 0x00, 0x19, 0xc0, 0x08, 0x02, + 0x05, 0x69, 0x50, 0x37, 0x48, 0x0d, 0x30, 0x00, 0xc0, 0x0d, 0x3c, 0x00, + 0x09, 0x49, 0x14, 0x06, 0xe6, 0xda, 0xdd, 0x79, 0x41, 0x81, 0x3c, 0x08, + 0xc4, 0xfc, 0x08, 0x34, 0x81, 0xcb, 0x22, 0x22, 0xc0, 0x98, 0x08, 0x31, + 0x2b, 0xcb, 0x9c, 0xc6, 0x41, 0x90, 0x30, 0x28, 0x0d, 0xc9, 0x14, 0x02, + 0xc4, 0xfc, 0x08, 0x34, 0xc4, 0xbc, 0x48, 0x28, 0x45, 0x26, 0x54, 0x37, + 0xc5, 0xf4, 0x08, 0x09, 0x80, 0x05, 0x30, 0x11, 0x45, 0x60, 0x7c, 0x30, + 0xc1, 0x49, 0x30, 0x04, 0x81, 0xc9, 0x34, 0x23, 0xa7, 0x7d, 0xfc, 0x57, + 0xf5, 0xdd, 0x59, 0x33, 0x41, 0xcd, 0x3c, 0x04, 0x81, 0xcb, 0x26, 0x20, + 0x09, 0x4d, 0x30, 0x00, 0x24, 0x22, 0xc5, 0xbb, 0x00, 0xcc, 0x34, 0x00, + 0xe7, 0x93, 0xdd, 0x79, 0xc5, 0x6f, 0x70, 0x36, 0x09, 0x4d, 0x30, 0x03, + 0x01, 0x95, 0x3c, 0x02, 0x45, 0x6d, 0x50, 0x35, 0xe0, 0xbd, 0xdd, 0x5e, + 0x00, 0xdc, 0x38, 0x00, 0x09, 0x44, 0x34, 0x00, 0x81, 0x49, 0x22, 0x04, + 0x79, 0x9f, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0x6b, 0x54, 0x35, + 0x24, 0x26, 0xc5, 0xbf, 0x45, 0x6d, 0x54, 0x35, 0x41, 0x49, 0x04, 0x02, + 0x40, 0xd0, 0x30, 0x08, 0xc5, 0xd9, 0x48, 0x28, 0x40, 0x4c, 0x14, 0x02, + 0x2e, 0x62, 0xb4, 0xe8, 0xc0, 0x09, 0x38, 0x06, 0xc1, 0xd9, 0x08, 0x00, + 0x09, 0xcd, 0x54, 0x00, 0x09, 0xc4, 0x3c, 0x00, 0x09, 0x5b, 0x30, 0x00, + 0xc5, 0x74, 0x78, 0x11, 0xe6, 0x9b, 0xdd, 0x7c, 0x89, 0x15, 0x20, 0x00, + 0xa1, 0x59, 0x11, 0x03, 0xa7, 0x7d, 0xfc, 0x57, 0xc1, 0x91, 0x08, 0x20, + 0xc0, 0xd8, 0x08, 0x20, 0x09, 0x15, 0x30, 0x00, 0x81, 0xcb, 0x26, 0x20, + 0x09, 0x4d, 0x30, 0x01, 0xc5, 0xd1, 0x48, 0x28, 0x00, 0xcc, 0x34, 0x00, + 0x81, 0xcb, 0x26, 0x10, 0x41, 0xcd, 0x3c, 0x06, 0xc1, 0xcf, 0x30, 0x02, + 0x2b, 0xcf, 0x94, 0xc0, 0x09, 0xcd, 0x30, 0x01, 0x91, 0xc9, 0x24, 0x01, + 0x2b, 0xcb, 0x9c, 0xc3, 0x2a, 0x8b, 0x94, 0xc3, 0x2b, 0x4f, 0x94, 0xc2, + 0x08, 0x8d, 0x30, 0x00, 0xe6, 0xda, 0xdd, 0x7c, 0x45, 0x25, 0x50, 0x31, + 0x49, 0x49, 0x32, 0x00, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x20, 0x43, 0x6f, 0x70, + 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x35, 0x20, + 0x20, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x61, 0x78, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x77, 0x77, 0x77, 0x2e, + 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x61, 0x78, 0x2e, 0x63, 0x6f, 0x6d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x08, 0x8e, 0x18, 0x00, 0x91, 0xcb, 0x20, 0x03, + 0xc5, 0xd9, 0x48, 0x28, 0x2b, 0xcb, 0x9c, 0xe2, 0x3f, 0xa5, 0x3f, 0xc6, + 0x80, 0x38, 0x08, 0xe2, 0x38, 0x02, 0xe3, 0x3f, 0xa7, 0x3f, 0x86, 0x38, + 0xff, 0xe8, 0xd7, 0x00, 0x3f, 0xa6, 0x3f, 0x85, 0x38, 0x0c, 0xec, 0x3f, + 0x8f, 0x38, 0x04, 0xed, 0x3f, 0x87, 0xed, 0x3f, 0x87, 0x1c, 0x3f, 0x87, + 0x14, 0x34, 0x3f, 0x85, 0xc1, 0x3b, 0xff, 0xf9, 0xff, 0xff, 0x3f, 0x85, + 0x36, 0xd1, 0x35, 0x3f, 0x85, 0x38, 0x02, 0xd1, 0x3f, 0x85, 0x38, 0x0c, + 0xec, 0x3f, 0xc7, 0x4c, 0x3f, 0x8b, 0x3f, 0x87, 0x36, 0xb1, 0x3f, 0x8c, + 0x3f, 0x87, 0x38, 0x02, 0xb1, 0x3f, 0x85, 0x38, 0x08, 0xec, 0x3f, 0x87, + 0x38, 0x03, 0xb1, 0x3f, 0x86, 0xa0, 0x97, 0x00, 0x3f, 0x87, 0x38, 0x04, + 0xb1, 0x3f, 0x86, 0x36, 0xb0, 0x3f, 0x87, 0xec, 0x3f, 0x87, 0x38, 0x05, + 0xb1, 0x34, 0x39, 0xf0, 0x04, 0x3f, 0x87, 0x3f, 0x88, 0x34, 0x3f, 0xa5, + 0x37, 0x1e, 0x3f, 0xa6, 0x37, 0x16, 0x3f, 0xa7, 0x3f, 0xae, 0x00, 0x00, + 0x00, 0x3f, 0x89, 0x21, 0x04, 0xff, 0x71, 0x01}; +/* ++ -----------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ + diff --git a/spindebug.c b/spindebug.c new file mode 100755 index 0000000..06bb090 --- /dev/null +++ b/spindebug.c @@ -0,0 +1,592 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include +#ifdef LINUX +#include "conion.h" +#else +#include +#endif +#include +#include "interp.h" +#include "opcodes.h" + +#define OP_NONE 0 +#define OP_UNSIGNED_OBJ_OFFSET 1 +#define OP_UNSIGNED_VAR_OFFSET 2 +#define OP_UNSIGNED_LOC_OFFSET 3 +#define OP_DATA 4 +#define OP_SIGNED_JMP_OFFSET 5 +#define OP_MEMORY_OPCODE_WRITE 6 +#define OP_OBJ_CALL_PAIR 7 +#define OP_SIGNED_OFFSET 8 +#define OP_PACKED_LITERAL 9 +#define OP_BYTE_LITERAL 10 +#define OP_WORD_LITERAL 11 +#define OP_NEAR_LONG_LITERAL 12 +#define OP_LONG_LITERAL 13 +#define OP_MEMORY_OPCODE 14 +#define OP_MEMORY_OPCODE_READ 15 +#define OP_COMPACT_VAR_OFFSET 16 +#define OP_COMPACT_LOC_OFFSET 17 + +extern char *hubram; +extern int32_t memsize; +extern int32_t symflag; + +extern FILE *tracefile; + +void RemoveCRLF(char *str) +{ + int32_t len = strlen(str); + + if(len == 0) return; + + str += len-1; + + while (len > 0) + { + if (*str != 10 && *str != 13) break; + *str-- = 0; + len--; + } +} + +char *FindOpcode(int32_t pcurr, int32_t *ops_format, int32_t mode) +{ + int32_t opcode; + int32_t i; + + opcode = BYTE(pcurr); + + if (mode) + { + opcode &= 0x7f; + if (opcode >= 0x40) + opcode += 0xe0 - 0x40; + else if (opcode >= 0x20) + opcode &= 0x78; + else if (opcode >= 0x08) + opcode &= 0x7c; + else + opcode &= 0x7e; + } + else + { + if (opcode >= 0x40 && opcode <= 0x7f) opcode &= 0x63; + } + + for (i = 0; optable[i].opname; i++) + { + if (opcode != optable[i].opcode) continue; + if (mode == 0 || (optable[i].opform >> 5) >= 2) break; + } + if (!optable[i].opname) return 0; + *ops_format = optable[i].opform; + return optable[i].opname; +} + +extern char objname[100][20]; +extern int32_t methodnum[100]; +extern int32_t methodlev; + +char *FindChar(char *str, int32_t val) +{ + while (*str && *str != val) + str++; + return str; +} + +void ProcessRet(void) +{ + if (!symflag) return; + methodlev--; + fprintf(tracefile, "return %s\n\n", objname[methodlev]); +} + +static char linebuf[200]; + +void ProcessCall(int32_t subnum, int32_t mode) +{ + int32_t methnum = 0; + FILE *infile; + + if (!symflag) return; + + infile = fopen(objname[methodlev], "r"); + if (mode) + { + methodlev++; + strcpy(objname[methodlev], objname[methodlev-1]); + } + methodnum[methodlev] = subnum; + if (!infile) return; + + // Count pubs + while (fgets(linebuf, 200, infile)) + { + if (strncmp(linebuf, "PUB", 3) == 0 || strncmp(linebuf, "pub", 3) == 0) + { + methnum++; + if (methnum == subnum) + { + fprintf(tracefile, "call %s:%s\n", objname[methodlev], linebuf); + fclose(infile); + return; + } + } + } + fclose(infile); + infile = fopen(objname[methodlev], "r"); + + // Count pris + while (fgets(linebuf, 200, infile)) + { + if (strncmp(linebuf, "PRI", 3) == 0 || strncmp(linebuf, "pri", 3) == 0) + { + methnum++; + if (methnum == subnum) + { + fprintf(tracefile, "call %s:%s\n", objname[methodlev], linebuf); + fclose(infile); + return; + } + } + } +} + +void ProcessObjCall(int32_t objnum, int32_t subnum) +{ + int32_t mode = 0; + int32_t methnum = 0; + int32_t commentmode = 0; + int32_t found = 0; + FILE *infile; + + if (!symflag) return; + + infile = fopen(objname[methodlev], "r"); + methodlev++; + strcpy(objname[methodlev], objname[methodlev-1]); + methodnum[methodlev] = subnum; + if (!infile) return; + + // Count pubs and pris + while (fgets(linebuf, 200, infile)) + { + if (linebuf[0] == '}') + { + commentmode--; + if (commentmode < 0) commentmode = 0; + continue; + } + else if (linebuf[0] == '{') + { + if (*FindChar(linebuf, '}') == 0) + commentmode++; + } + if (commentmode) continue; + if (strncmp(linebuf, "PUB", 3) == 0 || strncmp(linebuf, "pub", 3) == 0 || + strncmp(linebuf, "PRI", 3) == 0 || strncmp(linebuf, "pri", 3) == 0) + { + methnum++; + } + } + fclose(infile); + infile = fopen(objname[methodlev], "r"); + + // Count objs + commentmode = 0; + while (fgets(linebuf, 200, infile)) + { + if (linebuf[0] == '}') + { + commentmode--; + if (commentmode < 0) commentmode = 0; + continue; + } + else if (linebuf[0] == '{') + { + if (*FindChar(linebuf, '}') == 0) + commentmode++; + } + if (commentmode) continue; + if (mode == 0) + { + if (strncmp(linebuf, "OBJ", 3) == 0 || strncmp(linebuf, "obj", 3) == 0) + mode = 1; + } + else + { + methnum++; + if (linebuf[0] != ' ') break; + if (methnum == objnum) + { + char *ptr1; + char *ptr2; + int32_t num; + + // Locate filename + ptr1 = FindChar(linebuf, '"'); + if (*ptr1) + ptr1++; + ptr2 = FindChar(ptr1, '"'); + if (*ptr2) ptr2--; + else + ptr2 = ptr1; + num = ptr2 - ptr1 + 1; + if (num < 1) num = 1; + memcpy(objname[methodlev], ptr1, num); + objname[methodlev][num] = 0; + if (symflag == 2) + strcat(objname[methodlev], ".spn"); + else + strcat(objname[methodlev], ".spin"); + fclose(infile); + found = 1; + break; + } + } + } + if (!found) + { + fclose(infile); + return; + } + ProcessCall(subnum, 0); +} + +static int GetOpIndex(int opcode); +static int GetExOpIndex(int opcode); + +void PrintOp(SpinVarsT *spinvars) +{ + long pcurr = spinvars->pcurr; + int32_t opcode; + int32_t opform = 0; + char *opstr; + int exop1, exop2; + int32_t val; + int32_t operand; + char *regop[] = {"ldreg", "streg", "exreg", "??reg"}; + char *regname[] = {"par", "cnt", "ina", "inb", "outa", "outb", "dira", + "dirb", "ctra", "ctrb", "frqa", "frqb", "phsa", "phsb", "vcfg", "vscl"}; + char bytestr[40], symstr[100]; + + if (spinvars->state != 1) return; + + opcode = BYTE(pcurr); + exop1 = GetOpIndex(opcode); + exop2 = -1; + opstr = FindOpcode(pcurr, &opform, 0); + + memset(bytestr, ' ', 40); + bytestr[20] = 0; + sprintf(bytestr, "%4.4x %2.2x", (unsigned int)pcurr, opcode); + symstr[0] = 0; + + switch (opform & 0x1f) + { + case OP_NONE: + strcpy(symstr, opstr); + if (strncmp(opstr, "ret", 3) == 0) + ProcessRet(); + pcurr++; + break; + case OP_UNSIGNED_OBJ_OFFSET: + case OP_UNSIGNED_VAR_OFFSET: + case OP_UNSIGNED_LOC_OFFSET: + operand = BYTE(pcurr+1); + if (operand & 0x80) + { + operand = ((operand & 0x7f) << 8) | BYTE(pcurr+2); + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x", BYTE(pcurr+1), BYTE(pcurr+2)); + pcurr += 3; + } + else + { + sprintf(bytestr + strlen(bytestr), " %2.2x", BYTE(pcurr+1)); + pcurr += 2; + } + sprintf(symstr, "%s $%x", opstr, operand); + break; + case OP_DATA: + sprintf(symstr, "%s - ******** TBD ********", opstr); + pcurr++; + break; + case OP_SIGNED_OFFSET: + case OP_SIGNED_JMP_OFFSET: + operand = BYTE(pcurr+1); + if (operand & 0x80) + { + operand = ((operand & 0x7f) << 8) | BYTE(pcurr+2); + operand = (operand << 17) >> 17; + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x", BYTE(pcurr+1), BYTE(pcurr+2)); + pcurr += 3; + } + else + { + operand = (operand << 25) >> 25; + sprintf(bytestr + strlen(bytestr), " %2.2x", BYTE(pcurr+1)); + pcurr += 2; + } + sprintf(symstr, "%s %d", opstr, operand); + break; + case OP_MEMORY_OPCODE_READ: + case OP_MEMORY_OPCODE_WRITE: + operand = (BYTE(pcurr+1) >> 5) & 3; + opstr = regop[operand]; + if (operand == 2) opform |= 1 << 5; + operand = (BYTE(pcurr+1) & 31); + sprintf(bytestr + strlen(bytestr), " %2.2x", BYTE(pcurr+1)); + if (operand <= 15) + { + sprintf(symstr, "%s $%3.3x", opstr, operand + 0x1e0); + } + else + { + sprintf(symstr, "%s %s", opstr, regname[operand-16]); + } + pcurr += 2; + break; + case OP_OBJ_CALL_PAIR: + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x", BYTE(pcurr+1), BYTE(pcurr+2)); + sprintf(symstr, "%s %d %d", opstr, BYTE(pcurr+1), BYTE(pcurr+2)); + ProcessObjCall(BYTE(pcurr+1), BYTE(pcurr+2)); + pcurr += 3; + break; + case OP_PACKED_LITERAL: + operand = BYTE(pcurr+1); + val = 2 << (operand & 31); + if (operand & 0x20) val--; + if (operand & 0x40) val = ~val; + sprintf(bytestr + strlen(bytestr), " %2.2x", operand); + sprintf(symstr, "%s $%x", opstr, val); + pcurr += 2; + break; + case OP_BYTE_LITERAL: + operand = BYTE(pcurr+1); + sprintf(bytestr + strlen(bytestr), " %2.2x", operand); + sprintf(symstr, "%s %d", opstr, operand); + if (strcmp(opstr, "call") == 0) + ProcessCall(operand, 1); + pcurr += 2; + break; + case OP_WORD_LITERAL: + operand = BYTE(pcurr+1); + operand = (operand << 8) | BYTE(pcurr+2); + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x", BYTE(pcurr+1), BYTE(pcurr+2)); + sprintf(symstr, "%s %d", opstr, operand); + pcurr += 3; + break; + case OP_NEAR_LONG_LITERAL: + operand = BYTE(pcurr+1); + operand = (operand << 8) | BYTE(pcurr+2); + operand = (operand << 8) | BYTE(pcurr+3); + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x %2.2x", + BYTE(pcurr+1), BYTE(pcurr+2), BYTE(pcurr+3)); + sprintf(symstr, "%s %d", opstr, operand); + pcurr += 4; + break; + case OP_LONG_LITERAL: + operand = BYTE(pcurr+1); + operand = (operand << 8) | BYTE(pcurr+2); + operand = (operand << 8) | BYTE(pcurr+3); + operand = (operand << 8) | BYTE(pcurr+4); + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x %2.2x %2.2x", + BYTE(pcurr+1), BYTE(pcurr+2), BYTE(pcurr+3), BYTE(pcurr+4)); + sprintf(symstr, "%s %d", opstr, operand); + pcurr += 5; + break; + case OP_MEMORY_OPCODE: + sprintf(symstr, "%s - ******** TBD ********", opstr); + pcurr++; + break; + case OP_COMPACT_VAR_OFFSET: + case OP_COMPACT_LOC_OFFSET: + operand = opcode & 0x1c; + sprintf(symstr, "%s $%x", opstr, operand); + pcurr++; + break; + } + if ((opform >> 5) == 1) + { + char *loadstr = ""; + opcode = BYTE(pcurr); + exop2 = GetExOpIndex(opcode); + if (opcode & 0x80) + { + loadstr = "load"; + opcode &= 0x7f; + } + opstr = FindOpcode(pcurr, &opform, 1); + if (opcode != 0x02) + { + sprintf(symstr + strlen(symstr), " %s %s", opstr, loadstr); + sprintf(bytestr + strlen(bytestr), " %2.2x", BYTE(pcurr)); + } + else + { + operand = BYTE(pcurr+1); + if (operand < 0x80) + { + operand = (operand << 25) >> 25; + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x", + BYTE(pcurr), BYTE(pcurr+1)); + pcurr++; + } + else + { + operand = (operand << 8) | BYTE(pcurr+2); + operand = (operand << 17) >> 17; + sprintf(bytestr + strlen(bytestr), " %2.2x %2.2x %2.2x", + BYTE(pcurr), BYTE(pcurr+1), BYTE(pcurr+2)); + pcurr += 2; + } + sprintf(symstr + strlen(symstr), " %s %d %s", opstr, operand, loadstr); + } + pcurr++; + } + bytestr[strlen(bytestr)] = ' '; + fprintf(tracefile, "%s %s\n", bytestr, symstr); + //fprintf(tracefile, "%s [%2d,%2d] %s\n", bytestr, exop1, exop2, symstr); +} + +static int opcount[256]; +static int exopcount[27][45]; + +static int GetExOpIndex(int opcode) +{ + int index; + + opcode &= 0x7f; + if (opcode >= 0x40) + index = (opcode & 0x1f) + 13; + else if (opcode >= 0x20) + index = (opcode >> 3) + 5; + else if (opcode >= 0x02) + index = (opcode >> 2) + 1; + else + index = 0; + + return index; +} +static int GetOpIndex(int opcode) +{ + int index = -1; + + if (opcode == 0x26) + index = 0; + else if ((opcode >= 0x40 && opcode <= 0x7f) && (opcode & 3) == 2) + index = ((opcode - 0x40) >> 7) + 1; + else if ((opcode >= 0x80 && opcode < 0xe0) && (opcode & 3) == 2) + index = ((opcode - 0x80) >> 2) + 3; + + return index; +} + +void ResetStats(void) +{ + memset(opcount, 0, 256 * 4); + memset(exopcount, 0, 27 * 45 * 4); +} + +void CountOp(SpinVarsT *spinvars) +{ + int pcurr = spinvars->pcurr; + int opcode = BYTE(pcurr++); + int opindex, exopindex; + + if (opcode >= 0x40 && opcode <= 0x7f) opcode &= 0x63; + opcount[opcode]++; + opindex = GetOpIndex(opcode); + if (opindex < 0) return; + if (opcode >= 0x80 && ((opcode >> 2) & 3)) + { + opcode = BYTE(pcurr++); + if (opcode & 0x80) pcurr++; + } + opcode = BYTE(pcurr); + exopindex = GetExOpIndex(opcode); + exopcount[opindex][exopindex]++; +} + +void PrintStats(void) +{ + int i, j; + int opcode; + int opindex; + int exop, k; + char *exname; + char *opname; + static char *exopname[13] = { + "store", "repeat", "repeats", "randf", "randr", "sexb", "sexw", + "postclr", "postset", "preinc", "postinc", "predec", "postdec"}; + static unsigned char exopcode[13] = { 0x00, 0x02, 0x06, 0x08, + 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38}; + + for (i = 0; i < 256; i++) + { + if (opcount[i] == 0) continue; + opcode = i; + if (opcode >= 0x40 && opcode <= 0x7f) opcode &= 0x63; + + for (j = 0; optable[j].opname; j++) + { + if (opcode == optable[j].opcode) break; + } + opname = optable[j].opname; + opindex = GetOpIndex(i); + if (opindex >= 0) + { + for (j = 0; j < 45; j++) + { + if (exopcount[opindex][j] == 0) continue; + if (j < 13) + { + exop = exopcode[j]; + exname = exopname[j]; + } + else + { + exop = j - 13 + 0xe0; + for (k = 0; optable[k].opname; k++) + { + if (exop == optable[k].opcode) break; + } + exname = optable[k].opname; + } + fprintf(tracefile, "%10d, %2.2x:%2.2x, %s:%s\n", + exopcount[opindex][j], i, exop, opname, exname); + + } + } + else + { + fprintf(tracefile, "%10d, %2.2x, %s\n", opcount[i], i, opname); + } + } +} + +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/spindebug.h b/spindebug.h new file mode 100755 index 0000000..427e2d9 --- /dev/null +++ b/spindebug.h @@ -0,0 +1,3 @@ +void ResetStats(void); +void CountOp(SpinVarsT *spinvars); +void PrintStats(void); diff --git a/spininterp.c b/spininterp.c new file mode 100755 index 0000000..8abfc6e --- /dev/null +++ b/spininterp.c @@ -0,0 +1,1313 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.21 +' Copyright (c) 2010, 2011 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include +#ifdef LINUX +#include "conion.h" +#else +#include +#endif +#include +#include +#include "interp.h" + +extern int32_t printflag; +extern PasmVarsT PasmVars[8]; +extern char *hubram; +extern int32_t memsize; +extern int32_t loopcount; +extern int32_t cycleaccurate; +extern int32_t proptwo; +extern int32_t pin_val; + +extern char lockstate[8]; +extern char lockalloc[8]; + +extern FILE *tracefile; + +int32_t ExecuteMathOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1); +int32_t ExecuteExtraOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1, int32_t mask); +void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_t lsb); + +// This routine checks for the system I/O address and +// maps it to the end of the memory +int32_t MAP_ADDR(int32_t addr) +{ + if ((addr & 0xfffffff0) == 0x12340000) + { + addr = memsize + (addr & 15); + } + else if (memsize == 65536) + { + addr &= 0xffff; + } + else if (((uint32_t)addr) >= memsize) + { + fprintf(tracefile, "MAP_ADDR: address out of bounds %8.8x\n", addr); + addr = memsize + 12; + } + //fprintf(tracefile, "MAP_ADDR: %8.8x %8.8x\n", addr, ((uint32_t *)hubram)[addr>>2]); + + return addr; +} + +int32_t GetCnt() +{ + int32_t cycles; + + if (cycleaccurate) + { + if (proptwo) + cycles = loopcount; + else + cycles = loopcount * 4; + } + else + { + int64_t millisec; + struct timeb timebuf; + + ftime(&timebuf); + millisec = timebuf.time; + millisec = (millisec * 1000) + timebuf.millitm; + millisec *= LONG(0)/1000; + cycles = millisec; + } + + return cycles; +} + +void UpdatePins(void) +{ + int32_t i; + int32_t mask1; + int32_t val = 0; + int32_t mask = 0; + + for (i = 0; i < 8; i++) + { + if (PasmVars[i].state) + { + mask1 = PasmVars[i].mem[0x1f6]; // dira + val |= mask1 & PasmVars[i].mem[0x1f4]; // outa + mask |= mask1; + } + } + pin_val = (~mask) | val; +} + +int32_t GetSignedOffset(int32_t *ppcurr) +{ + int32_t val; + int32_t pcurr = *ppcurr; + val = BYTE(pcurr++); + if (val < 0x80) + { + val = (val << 25) >> 25; + } + else + { + val = (val << 8) | BYTE(pcurr++); + val = (val << 17) >> 17; + } + *ppcurr = pcurr; + return val; +} + +int32_t GetUnsignedOffset(int32_t *ppcurr) +{ + int32_t pcurr = *ppcurr; + int32_t val; + val = BYTE(pcurr++); + if (val & 0x80) + val = ((val & 0x7f) << 8) | BYTE(pcurr++); + *ppcurr = pcurr; + return val; +} + +int32_t bitrev(int32_t val, int32_t nbits) +{ + int32_t retval = 0; + + while (nbits-- > 0) + { + retval = (retval << 1) | (val & 1); + val >>= 1; + } + + return retval; +} + +void StartCog(SpinVarsT *spinvars, int32_t par, int32_t cogid) +{ + memset(spinvars, 0, sizeof(SpinVarsT)); + spinvars->id = cogid; + spinvars->par = par; + spinvars->state = 1; + spinvars->pbase = WORD(par + 2); + spinvars->vbase = WORD(par + 4); + spinvars->dbase = WORD(par + 6); + spinvars->pcurr = WORD(par + 8); + spinvars->dcurr = WORD(par + 10); + spinvars->masklong = 0xffffffff; + spinvars->masktop = 0x80000000; + spinvars->maskwr = 0x00800000; +} + +void ExecuteLowerOp(SpinVarsT *spinvars) +{ + int32_t pcurr = spinvars->pcurr; + int32_t dcurr = spinvars->dcurr; + int32_t opcode = BYTE(pcurr++); + + if (opcode <= 3) // ldfrmr, ldfrm, ldfrmar, ldfrma + { + opcode |= spinvars->pbase; + WORD(dcurr) = opcode; + dcurr += 2; + WORD(dcurr) = spinvars->vbase; + dcurr += 2; + WORD(dcurr) = spinvars->dbase; + dcurr += 2; + WORD(dcurr) = spinvars->dcall; + spinvars->dcall = dcurr; + dcurr += 2; + LONG(dcurr) = 0; + dcurr += 4; + } + else if (opcode == 0x04) // jmp + { + int32_t jmpoff = GetSignedOffset(&pcurr); + pcurr += jmpoff; + } + else if (opcode >= 0x05 && opcode <= 0x07) // call, callobj, callobjx + { + int32_t index, pubnum; + + if (opcode > 0x05) + { + int32_t objnum = BYTE(pcurr++); + if (opcode == 0x07) + { + dcurr -= 4; + objnum += LONG(dcurr); + } + index = (objnum << 2) + spinvars->pbase; + spinvars->pbase += WORD(index); + spinvars->vbase += WORD(index+2); + } + + pubnum = BYTE(pcurr++); + spinvars->dbase = spinvars->dcall; + spinvars->dcall = WORD(spinvars->dcall); + WORD(spinvars->dbase) = pcurr; + index = (pubnum << 2) + spinvars->pbase; + pcurr = WORD(index) + spinvars->pbase; + spinvars->dbase += 2; + dcurr += WORD(index+2); + } + else if (opcode == 0x08) // tjz + { + int32_t jmpoff = GetSignedOffset(&pcurr); + + if (!LONG(dcurr-4)) + { + pcurr += jmpoff; + dcurr -= 4; + } + } + else if (opcode == 0x09) // djnz + { + int32_t jmpoff = GetSignedOffset(&pcurr); + if (--LONG(dcurr-4)) + { + pcurr += jmpoff; + } + else + dcurr -= 4; + } + else if (opcode == 0x0a) // jz + { + int32_t jmpoff = GetSignedOffset(&pcurr); + dcurr -= 4; + if (!LONG(dcurr)) + { + pcurr += jmpoff; + } + } + else if (opcode == 0x0b) // jnz + { + int32_t jmpoff = GetSignedOffset(&pcurr); + dcurr -= 4; + if (LONG(dcurr)) + { + pcurr += jmpoff; + } + } + else if (opcode >= 0x0c && opcode <= 0x15) + { + int32_t val, jmpoff, val2, val0; + if (opcode == 0x0c) // casedone + { + dcurr -= 8; + jmpoff = LONG(dcurr); + pcurr = spinvars->pbase + jmpoff; + } + else if (opcode == 0x0d) // casevalue + { + jmpoff = GetSignedOffset(&pcurr); + dcurr -= 4; + val = LONG(dcurr); + if (val == LONG(dcurr - 4)) + { + pcurr += jmpoff; + } + } + else if (opcode == 0x0e) // caserange + { + jmpoff = GetSignedOffset(&pcurr); + dcurr -= 4; + val = LONG(dcurr); + dcurr -= 4; + val2 = LONG(dcurr); + val0 = LONG(dcurr - 4); + if (val <= val2) + { + if (val <= val0 && val0 <= val2) pcurr += jmpoff; + } + else + { + if (val2 <= val0 && val0 <= val) pcurr += jmpoff; + } + } + else if (opcode == 0x0f) // lookdone + { + dcurr -= 8; + LONG(dcurr - 4) = 0; + } + else if (opcode == 0x10) // lookupval + { + dcurr -= 4; + val = LONG(dcurr); + val0 = LONG(dcurr - 4); + if (val0 < LONG(dcurr - 12)) + { + dcurr -= 8; + pcurr = spinvars->pbase + LONG(dcurr); + LONG(dcurr - 4) = 0; + } + else if (val0 == LONG(dcurr - 12)) + { + dcurr -= 8; + pcurr = spinvars->pbase + LONG(dcurr); + LONG(dcurr - 4) = val; + } + else + { + LONG(dcurr - 12)++; + } + } + else if (opcode == 0x11) // lookdnval + { + dcurr -= 4; + val = LONG(dcurr); + val0 = LONG(dcurr - 4); + if (val == val0) + { + dcurr -= 8; + pcurr = spinvars->pbase + LONG(dcurr); + } + else + { + LONG(dcurr - 12)++; + } + } + else if (opcode == 0x12) // lookuprng + { + int32_t num, count; + dcurr -= 4; + val = LONG(dcurr); + dcurr -= 4; + val2 = LONG(dcurr); + val0 = LONG(dcurr - 4); + num = val - val2; + if (num < 0) num = -num; + count = LONG(dcurr - 12); + if (val0 < count) + { + dcurr -= 8; + pcurr = spinvars->pbase + LONG(dcurr); + LONG(dcurr - 4) = 0; + } + else if (val0 - num <= count) + { + dcurr -= 8; + pcurr = spinvars->pbase + LONG(dcurr); + num = val0 - count; + if (val >= val2) + { + LONG(dcurr - 4) = val2 + num; + } + else + { + LONG(dcurr - 4) = val - num; + } + } + else + { + LONG(dcurr - 12) += num + 1; + } + } + else if (opcode == 0x13) // lookdnrng + { + dcurr -= 4; + val = LONG(dcurr); + dcurr -= 4; + val2 = LONG(dcurr); + if (val > val2) + { + val0 = val; + val = val2; + val2 = val0; + } + val0 = LONG(dcurr - 4); + if (val <= val0 && val0 <= val2) + { + dcurr -= 8; + pcurr = spinvars->pbase + LONG(dcurr); + } + else + { + LONG(dcurr - 12)++; + } + } + else if (opcode == 0x14) // pop + { + dcurr -= 4; + val = LONG(dcurr); + dcurr -= val; + } + else if (opcode == 0x15) // run + { + spinvars->lsb = pcurr; + pcurr = 0xfffc; + } + else + fprintf(tracefile, "%4.4x %2.2x - NOT IMPLEMENTED\n", pcurr - 1, opcode); + } + else if (opcode >= 0x16 && opcode <= 0x23) + { + if (opcode == 0x16) // strsize + { + char *ptr = hubram; + dcurr -= 4; + LONG(dcurr) = strlen(ptr + LONG(dcurr)); + dcurr += 4; + } + else if (opcode == 0x17) // strcomp + { + char *ptr1 = hubram; + char *ptr2 = hubram; + dcurr -= 4; + ptr1 += LONG(dcurr); + dcurr -= 4; + ptr2 += LONG(dcurr); + if (strcmp(ptr1, ptr2) == 0) + LONG(dcurr) = -1; + else + LONG(dcurr) = 0; + dcurr += 4; + } + else if (opcode == 0x18) // bytefill + { + int32_t val, num; + char *ptr = hubram; + dcurr -= 4; + num = LONG(dcurr); + dcurr -= 4; + val = LONG(dcurr); + dcurr -= 4; + ptr += LONG(dcurr); + memset(ptr, val, num); + } + else if (opcode == 0x19) // wordfill + { + int32_t val, num, addr; + dcurr -= 4; + num = LONG(dcurr); + dcurr -= 4; + val = LONG(dcurr); + dcurr -= 4; + addr = LONG(dcurr); + while (num-- > 0) + { + WORD(addr) = val; + addr += 2; + } + } + else if (opcode == 0x1a) // longfill + { + int32_t val, num, addr; + dcurr -= 4; + num = LONG(dcurr); + dcurr -= 4; + val = LONG(dcurr); + dcurr -= 4; + addr = LONG(dcurr); + while (num-- > 0) + { + LONG(addr) = val; + addr += 4; + } + } + else if (opcode == 0x1b) // waitpeq + { + dcurr -= 12; + } + else if (opcode >= 0x1c && opcode <= 0x1e ) // bytemove, wordmove, longmove + { + char *dst = hubram; + char *src = hubram; + int32_t num; + dcurr -= 4; + num = LONG(dcurr); + dcurr -= 4; + src += LONG(dcurr); + dcurr -= 4; + dst += LONG(dcurr); + if (opcode == 0x1d) + num <<= 1; + else if (opcode == 0x1e) + num <<= 2; + memmove(dst, src, num); + } + else if (opcode == 0x1f) // waitpne + { + dcurr -= 12; + } + else if (opcode == 0x20) // clkset + { + int32_t clkfreq, clkmode; + dcurr -= 4; + clkfreq = LONG(dcurr); + dcurr -= 4; + clkmode = LONG(dcurr); + if (clkmode & 0x80) + { + RebootProp(); + return; + } + LONG(0) = clkfreq; + BYTE(4) = clkmode; + } + else if (opcode == 0x21) // cogstop + { + int32_t cogid; + dcurr -= 4; + cogid = LONG(dcurr) & 7; + PasmVars[cogid].state = 0; + UpdatePins(); + } + else if (opcode == 0x22) // lockret + { + int32_t locknum; + + dcurr -= 4; + locknum = LONG(dcurr) & 7; + lockalloc[locknum] = 0; + } + else if (opcode == 0x23) // waitcnt + { + int32_t parm1; + + dcurr -= 4; + parm1 = GetCnt() - LONG(dcurr); + if (parm1 < 0 || parm1 > 20000000) + { + pcurr--; + dcurr += 4; + spinvars->state = 2; + } + else + spinvars->state = 1; + } + } + else if (opcode >= 0x24 && opcode <= 0x2f) + { + if (opcode >= 0x24 && opcode <= 0x26) // ldregx, stregx, exregx (spr) + { + int32_t operand; + dcurr -= 4; + operand = LONG(dcurr); + operand = ((opcode & 3) << 5) | 0x10 | (operand & 15); + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + ExecuteRegisterOp(spinvars, operand, 31, 0); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else if (opcode == 0x27) // waitvid + { + dcurr -= 8; + } + else if (opcode == 0x28 || opcode == 0x2c) // coginitret, coginit + { + int32_t cogid, addr, par; + dcurr -= 4; + par = LONG(dcurr); + dcurr -= 4; + addr = LONG(dcurr); + dcurr -= 4; + cogid = LONG(dcurr); + if (cogid < 0 || cogid > 7) + { + for (cogid = 0; cogid < 8; cogid++) + { + if (!PasmVars[cogid].state) break; + } + } + if (cogid < 0 || cogid > 7) // || addr != 0xf004) + cogid = -1; + if (opcode == 0x28) + { + LONG(dcurr) = cogid; + dcurr += 4; + } + if (cogid != -1) + { + if (addr == 0xf004) + { + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + StartCog((SpinVarsT *)&PasmVars[cogid].mem[0x1e0], par, cogid); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else + { + StartPasmCog(&PasmVars[cogid], par, addr, cogid); + } + UpdatePins(); + } + } + else if (opcode == 0x29 || opcode == 0x2d) // locknewret, locknew + { + int32_t locknum; + + for (locknum = 0; locknum < 8; locknum++) + { + if (!lockalloc[locknum]) + { + lockalloc[locknum] = 1; + break; + } + } + if (opcode == 0x29) + { + if (locknum == 8) locknum = -1; + LONG(dcurr) = locknum; + dcurr += 4; + } + } + // locksetret, lockclrret, lockset, lockclr + else if (opcode == 0x2a || opcode == 0x2b || opcode == 0x2e || opcode == 0x2f) + { + int32_t locknum; + + dcurr -= 4; + locknum = LONG(dcurr) & 7; + if (opcode <= 0x2b) + { + LONG(dcurr) = lockstate[locknum]; + dcurr += 4; + } + lockstate[locknum] = (opcode & 1) - 1; + } + } + else if (opcode >= 0x30 && opcode <= 0x33) // abort, abortval, ret, retval + { + int32_t retval, dbase, pbase; + + if (opcode & 1) + retval = LONG(dcurr - 4); + else + retval = LONG(spinvars->dbase); + + dbase = spinvars->dbase; + + while (1) + { + dcurr = dbase - 8; + pbase = WORD(dcurr); + dbase = WORD(dcurr + 4); + if ((opcode & 2) || (pbase & 2)) break; + } + + spinvars->pbase = pbase & 0xfffc; + spinvars->vbase = WORD(dcurr + 2); + spinvars->dbase = dbase; + pcurr = WORD(dcurr + 6); + + if (!(pbase & 1)) + { + LONG(dcurr) = retval; + dcurr += 4; + } + } + else if (opcode >= 0x34 && opcode < 0x3c) + { + if (opcode == 0x35) LONG(dcurr) = 0; // dli0 + else if (opcode == 0x36) LONG(dcurr) = 1; // dli1 + else if (opcode == 0x34) LONG(dcurr) = -1; // dlim1 + else if (opcode == 0x37) // ldlip + { + int32_t val; + int32_t operand = BYTE(pcurr++); + int32_t rotate = operand & 31; + + if (rotate == 31) + val = 1; + else + val = 2 << rotate; + + if (operand & 0x20) val--; + if (operand & 0x40) val = ~val; + LONG(dcurr) = val; + } + else // ldbi, ldwi, ldmi, ldli + { + int32_t operand = 0; + while (opcode-- >= 0x38) operand = (operand << 8) | BYTE(pcurr++); + LONG(dcurr) = operand; + } + dcurr += 4; + } + else if (opcode == 0x3d) // ldregbit, stregbit, exregbit + { + int32_t operand = BYTE(pcurr++); + int32_t bitpos; + + dcurr -= 4; + bitpos = LONG(dcurr) & 0x1f; + + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + ExecuteRegisterOp(spinvars, operand, bitpos, bitpos); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else if (opcode == 0x3e) // ldregbits, stregbits, exregbits + { + int32_t operand = BYTE(pcurr++); + int32_t msb, lsb; + + dcurr -= 4; + lsb = LONG(dcurr) & 0x1f; + dcurr -= 4; + msb = LONG(dcurr) & 0x1f; + + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + ExecuteRegisterOp(spinvars, operand, msb, lsb); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else if (opcode == 0x3f) // ldreg, streg, exreg + { + int32_t operand = BYTE(pcurr++); + + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + ExecuteRegisterOp(spinvars, operand, 31, 0); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else + { + fprintf(tracefile, "NOT PROCESSED\n"); + } + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; +} + +void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_t lsb) +{ + int32_t opcode; + int32_t parm1, parm2; + int32_t pcurr = spinvars->pcurr; + int32_t dcurr = spinvars->dcurr; + int32_t *reg = (int32_t *)spinvars; + int32_t memfunc = (operand >> 5) & 3; + int32_t revflag = 0; + int32_t mask, nbits; + + if (lsb > msb) + { + revflag = msb; + msb = lsb; + lsb = revflag; + revflag = 1; + } + + nbits = msb - lsb + 1; + + if (nbits >= 32) + mask = -1; + else + mask = (1 << nbits) - 1; + + operand &= 0x1f; + + if (memfunc == 1) // store + { + spinvars->dcurr -= 4; + if (nbits == 32 && !revflag) + { + reg[operand] = LONG(spinvars->dcurr); + } + else + { + parm1 = reg[operand]; + parm2 = LONG(spinvars->dcurr); + parm2 &= mask; + if (revflag) parm2 = bitrev(parm2, nbits); + reg[operand] = (parm1 & ~(mask << lsb)) | (parm2 << lsb); + } + if (operand == 0x14 || operand == 0x16) UpdatePins(); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else if (memfunc == 0) // load + { + if (operand == 0x11) // cnt = $1f1 + parm1 = GetCnt(); + else if (operand == 0x12) // ina = $1f2 + parm1 = pin_val; + else + parm1 = reg[operand]; + parm1 = (parm1 >> lsb) & mask; + if (revflag) parm1 = bitrev(parm1, nbits); + LONG(dcurr) = parm1; + dcurr += 4; + } + else if (memfunc == 2) // execute + { + opcode = BYTE(spinvars->pcurr++); + + if (opcode & 0x7e) + { + if (operand == 0x11) // cnt = $1f1 + parm1 = GetCnt(); + else if (operand == 0x12) // ina = $1f2 + parm1 = pin_val; + else + parm1 = reg[operand]; + } + else + parm1 = 0; // Need to double check this + + parm2 = (parm1 >> lsb) & mask; + if (revflag) parm2 = bitrev(parm2, nbits); + + parm2 = ExecuteExtraOp(spinvars, opcode, parm2, mask); + + parm2 &= mask; + if (revflag) parm2 = bitrev(parm2, nbits); + reg[operand] = (parm1 & ~(mask << lsb)) | (parm2 << lsb); + if (operand == 0x14 || operand == 0x16) UpdatePins(); + + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else + fprintf(tracefile, "Undefined register operation\n"); + + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; +} + +void ExecuteMemoryOp(SpinVarsT *spinvars) +{ + int32_t pcurr = spinvars->pcurr; + int32_t dcurr = spinvars->dcurr; + int32_t opcode, memfunc, memsize, membase, memaddr; + + opcode = BYTE(pcurr++); + memfunc = opcode & 3; + + if (opcode < 0x80) // Compact offset + { + memsize = 3; + memaddr = (opcode & 0x1c); + membase = (opcode >> 5) & 3; + } + else + { + memsize = ((opcode >> 5) & 3) + 1; + membase = (opcode & 0x0c) >> 2; + + // Check for index op + if (opcode & 0x10) + { + dcurr -= 4; + memaddr = LONG(dcurr) << (memsize - 1); + } + else + memaddr = 0; + + if (membase) + memaddr += GetUnsignedOffset(&pcurr); + else + { + dcurr -= 4; + memaddr += LONG(dcurr); + } + } + + if (membase == 1) + memaddr += spinvars->pbase; + else if (membase == 2) + memaddr += spinvars->vbase; + else if (membase == 3) + memaddr += spinvars->dbase; + + if (memfunc == 3) // la + { + LONG(dcurr) = memaddr; + dcurr += 4; + } + else if (memfunc == 0) // ld + { + if (memsize == 1) LONG(dcurr) = BYTE(memaddr); + else if (memsize == 2) LONG(dcurr) = WORD(memaddr); + else LONG(dcurr) = LONG(memaddr); + dcurr += 4; + } + else if (memfunc == 1) // st + { + dcurr -= 4; + if (memsize == 1) BYTE(memaddr) = LONG(dcurr); + else if (memsize == 2) WORD(memaddr) = LONG(dcurr); + else LONG(memaddr) = LONG(dcurr); + } + else // ex + { + int32_t parm1 = 0; + + opcode = BYTE(pcurr++); + + if (opcode & 0x7f) + { + if (memsize == 1) parm1 = BYTE(memaddr); + else if (memsize == 2) parm1 = WORD(memaddr); + else parm1 = LONG(memaddr); + } + + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + parm1 = ExecuteExtraOp(spinvars, opcode, parm1, -1); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + + if (memsize == 1) BYTE(memaddr) = parm1; + else if (memsize == 2) WORD(memaddr) = parm1; + else LONG(memaddr) = parm1; + } + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; +} + +int32_t ExecuteExtraOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1, int32_t mask) +{ + int32_t parm2; + int32_t pcurr = spinvars->pcurr; + int32_t dcurr = spinvars->dcurr; + int32_t loadflag = opcode & 0x80; + int32_t size = (opcode >> 1) & 3; + + if (size == 1) + mask = 0xff; + else if (size == 2) + mask = 0xffff; + else if (size == 3) + mask = 0xffffffff; + + opcode &= 0x7f; + + if (opcode >= 0x40 && opcode < 0x60) // math op + { + parm2 = parm1 = ExecuteMathOp(spinvars, opcode, parm1); + pcurr = spinvars->pcurr; + dcurr = spinvars->dcurr; + } + else if ((opcode & 0x7e) == 0x00) // store + { + dcurr -= 4; + parm2 = parm1 = LONG(dcurr); + } + else if ((opcode & 0x7a) == 0x02) // repeat, repeats + { + int32_t first, last, step, jmpoff; + + dcurr -= 4; + last = LONG(dcurr); + dcurr -= 4; + first = LONG(dcurr); + if (opcode == 0x06) + { + dcurr -= 4; + step = LONG(dcurr); + } + else step = 1; + jmpoff = GetSignedOffset(&pcurr); + if (last >= first) + { + parm1 += step; + if (parm1 >= first && parm1 <= last) + pcurr += jmpoff; + } + else + { + parm1 -= step; + if (parm1 <= first && parm1 >= last) + pcurr += jmpoff; + } + parm2 = parm1; + } + else if ((opcode & 0x78) == 8) // randf, randr + { + uint32_t a, c, x, y, z; + + x = parm1; + z = (opcode & 0x04) == 0; + if (!x) x = 1; + y = 32; + a = 0x17; + if (!z) a = (a >> 1) | (a << 31); + while (y--) + { + c = x & a; + while (c & 0xfffffffe) c = (c >> 1) ^ (c & 1); + if (z) + x = (x >> 1) | (c << 31); + else + x = (x << 1) | c; + } + parm2 = parm1 = x; + } + else if ((opcode & 0x7c) == 0x10) // sexb + { + parm2 = parm1 = (parm1 << 24) >> 24; + } + else if ((opcode & 0x7c) == 0x14) // sexw + { + parm2 = parm1 = (parm1 << 16) >> 16; + } + else if ((opcode & 0x7c) == 0x18) // postclr + { + parm2 = parm1; + parm1 = 0; + } + else if ((opcode & 0x7c) == 0x1c) // postset + { + parm2 = parm1; + parm1 = -1; + } + else if ((opcode & 0x78) == 0x20) // preinc + { + parm2 = ++parm1; + parm2 &= mask; + } + else if ((opcode & 0x78) == 0x28) // postinc + { + parm2 = parm1++; + parm2 &= mask; + } + else if ((opcode & 0x78) == 0x30) // predec + { + parm2 = --parm1; + parm2 &= mask; + } + else if ((opcode & 0x78) == 0x38) // postdec + { + parm2 = parm1--; + parm2 &= mask; + } + else + { + fprintf(tracefile, "NOT IMPLEMENTED\n"); + parm2 = 0; + } + + if (loadflag) + { + LONG(dcurr) = parm2; + dcurr += 4; + } + + spinvars->pcurr = pcurr; + spinvars->dcurr = dcurr; + + return parm1; +} + +int32_t ExecuteMathOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1) +{ + int32_t parm3; + int32_t parm2 = 0; + int32_t execflag = 0; + int32_t unary; + int32_t dcurr = spinvars->dcurr; + + unary = (0x810a02c0 >> (opcode & 0x1f)) & 1; + + // Get the parameters from the stack + if (opcode < 0xe0) + { + execflag = 1; + if (!unary) + { + if ((opcode >> 5) & 1) // Swap parms + { + parm2 = parm1; + dcurr -= 4; + parm1 = LONG(dcurr); + } + else + { + dcurr -= 4; + parm2 = LONG(dcurr); + } + } + opcode += 0xe0 - 0x40; + } + else + { + if (!unary) + { + dcurr -= 4; + parm2 = LONG(dcurr); + dcurr -= 4; + parm1 = LONG(dcurr); + } + else + { + dcurr -= 4; + parm1 = LONG(dcurr); + } + } + + // Execute the math op + switch (opcode) + { + case 0xe0: // ror + parm1 = (((uint32_t)parm1) >> parm2) | (parm1 << (32 - parm2)); + break; + + case 0xe1: // rol + parm1 = (((uint32_t)parm1) >> (32 - parm2)) | (parm1 << parm2); + break; + + case 0xe2: // shr + parm1 = ((uint32_t)parm1) >> parm2; + break; + + case 0xe3: // shl + parm1 <<= parm2; + break; + + case 0xe4: // min + if (parm2 > parm1) parm1 = parm2; + break; + + case 0xe5: // max + if (parm2 < parm1) parm1 = parm2; + break; + + case 0xe6: // neg + parm1 = -parm1; + break; + + case 0xe7: // com + parm1 = ~parm1; + break; + + case 0xe8: // and + parm1 &= parm2; + break; + + case 0xe9: // abs + if (parm1 < 0) parm1 = -parm1; + break; + + case 0xea: // or + parm1 |= parm2; + break; + + case 0xeb: // xor + parm1 ^= parm2; + break; + + case 0xec: // add + parm1 += parm2; + break; + + case 0xed: // sub + parm1 -= parm2; + break; + + case 0xee: // sar + parm1 >>= parm2; + break; + + case 0xef: // rev + parm1 = bitrev(parm1, parm2); + break; + + case 0xf0: // andl + parm1 = (parm1 && parm2) ? -1 : 0; + break; + + case 0xf1: // encode + for (parm2 = 32; parm2 >= 1; parm2--) + { + if (parm1 & 0x80000000) break; + parm1 <<= 1; + } + parm1 = parm2; + break; + + case 0xf4: // mul + parm1 *= parm2; + break; + + case 0xf5: // mulh + { + int64_t parm1a = parm1; + int64_t parm2a = parm2; + parm1 = (parm1a * parm2a) >> 32; + } + break; + + case 0xf2: // orl + parm1 = (parm1 || parm2) ? -1 : 0; + break; + + case 0xf3: // decode + parm1 = 1 << parm1; + break; + + case 0xf6: // div + if (parm2) + parm1 /= parm2; + else + parm1 = 0; + break; + + case 0xf7: // mod + if (parm2) + parm1 %= parm2; + else + parm1 = 0; + break; + + case 0xf8: // sqrt + parm2 = 0; + parm3 = 1 << 30; + while (parm3) + { + parm2 |= parm3; + if (parm2 <= parm1) + { + parm1 -= parm2; + parm2 += parm3; + } + else + parm2 -= parm3; + parm2 >>= 1; + parm3 >>= 2; + } + parm1 = parm2; + break; + + case 0xf9: // cmplt + parm1 = (parm1 < parm2) ? -1 : 0; + break; + + case 0xfa: // cmpgt + parm1 = (parm1 > parm2) ? -1 : 0; + break; + + case 0xfb: // cmpne + parm1 = (parm1 != parm2) ? -1 : 0; + break; + + case 0xfc: // cmpeq + parm1 = (parm1 == parm2) ? -1 : 0; + break; + + case 0xfd: // cmple + parm1 = (parm1 <= parm2) ? -1 : 0; + break; + + case 0xfe: // cmpgr + parm1 = (parm1 >= parm2) ? -1 : 0; + break; + + case 0xff: // notl + parm1 = parm1 ? 0 : -1; + break; + + default: + fprintf(tracefile, "NOT PROCESSED\n"); + } + + // Push the result back to the stack + if (!execflag) + { + LONG(dcurr) = parm1; + dcurr += 4; + spinvars->pcurr++; + } + + spinvars->dcurr = dcurr; + return parm1; +} + +void ExecuteOp(SpinVarsT *spinvars) +{ + int32_t opcode; + + if (!spinvars->state) return; + + opcode = BYTE(spinvars->pcurr); + + if (opcode < 0x40) + ExecuteLowerOp(spinvars); + else if (opcode < 0xe0) + ExecuteMemoryOp(spinvars); + else + ExecuteMathOp(spinvars, opcode, 0); +} +/* ++ -----------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/spinsim.c b/spinsim.c new file mode 100755 index 0000000..ec2a0cb --- /dev/null +++ b/spinsim.c @@ -0,0 +1,920 @@ +/******************************************************************************* +' Author: Dave Hein +' Version 0.75 +' Copyright (c) 2010 - 2014 +' See end of file for terms of use. +'******************************************************************************/ +#include +#include +#include +#include +#include +#ifdef LINUX +#include +#include +#include "conion.h" +#else +#include +#include +#endif +#include "interp.h" +#include "rom.h" +#include "spindebug.h" +#include "eeprom.h" + +// Define system I/O addresses and commands +//#define SYS_COMMAND 0x12340000 +//#define SYS_LOCKNUM 0x12340002 +//#define SYS_PARM 0x12340004 +//#define SYS_DEBUG 0x12340008 + +#define SYS_CON_PUTCH 1 +#define SYS_CON_GETCH 2 +#define SYS_FILE_OPEN 3 +#define SYS_FILE_CLOSE 4 +#define SYS_FILE_READ 5 +#define SYS_FILE_WRITE 6 +#define SYS_FILE_OPENDIR 7 +#define SYS_FILE_CLOSEDIR 8 +#define SYS_FILE_READDIR 9 +#define SYS_FILE_SEEK 10 +#define SYS_FILE_TELL 11 +#define SYS_FILE_REMOVE 12 +#define SYS_FILE_CHDIR 13 +#define SYS_FILE_GETCWD 14 +#define SYS_FILE_MKDIR 15 +#define SYS_FILE_GETMOD 16 +#define SYS_EXTMEM_READ 17 +#define SYS_EXTMEM_WRITE 18 +#define SYS_EXTMEM_ALLOC 19 + +#define GCC_REG_BASE 0 + +static char rootdir[100]; +char *hubram; +char *extram[4]; +int32_t extmemsize[4]; +uint32_t extmembase[4]; +int32_t extmemnum = 0; +char lockstate[8]; +char lockalloc[8]; + +char objname[100][20]; +int32_t methodnum[100]; +int32_t methodlev = 0; + +int32_t printflag = 0; +int32_t symflag = 0; +int32_t pasmspin = 0; +int32_t profile = 0; +int32_t memsize = 64; +int32_t cycleaccurate = 0; +int32_t loopcount = 0; +int32_t proptwo = 0; +int32_t baudrate = 0; +int32_t pin_val = -1; +int32_t gdbmode = 0; +int32_t eeprom = 0; +int32_t debugmode = 0; +int32_t printbreak = 0; + +FILE *logfile = NULL; +FILE *tracefile = NULL; +FILE *cmdfile = NULL; + +PasmVarsT PasmVars[8]; + +void PrintOp(SpinVarsT *spinvars); +void ExecuteOp(SpinVarsT *spinvars); +char *FindChar(char *str, int32_t val); +void Debug(void); +int32_t RunProp(int32_t maxloops); +void gdb(void); + +void spinsim_exit(int32_t exitcode) +{ + restore_console_io(); + exit(exitcode); +} + +void usage(void) +{ + fprintf(stderr, "Spinsim Version 0.75\n"); + fprintf(stderr, "usage: spinsim [options] file\n"); + fprintf(stderr, "The options are as follows:\n"); + fprintf(stderr, " -v# Set verbosity level\n"); + //fprintf(stderr, " -l List executed instructions\n"); + fprintf(stderr, " -l List executed instructions to \n"); + fprintf(stderr, " -p Use PASM Spin interpreter\n"); + fprintf(stderr, " -# Execute # instructions\n"); + fprintf(stderr, " -P Profile Spin opcode usage\n"); + fprintf(stderr, " -m# Set the hub memory size to # K-bytes\n"); + //fprintf(stderr, " -c Enable cycle-accurate mode for pasm cogs\n"); + fprintf(stderr, " -t Enable the Prop 2 mode\n"); + fprintf(stderr, " -b# Enable the serial port and set the baudrate to # (default 115200)\n"); + fprintf(stderr, " -gdb Operate as a GDB target over stdin/stdout\n"); + fprintf(stderr, " -L Log GDB remote comm to \n"); + fprintf(stderr, " -r Replay GDB session from \n"); + //fprintf(stderr, " -x# Set the external memory size to # K-bytes\n"); + fprintf(stderr, " -e Use eeprom.dat\n"); + fprintf(stderr, " -d Use debugger\n"); + spinsim_exit(1); +} + +void putchx(int32_t val) +{ + putchar(val); + fflush(stdout); +} + +int32_t getchx(void) +{ + uint8_t val = 0; + // GCC compiler issues warning for ignored fread return value + if(fread(&val, 1, 1, cmdfile /*stdin*/)) + if (val == 10) val = 13; + return val; +} + +char *FindExtMem(uint32_t addr, int32_t num) +{ + int i; + char *ptr = 0; + uint32_t addr1 = addr + num - 1; + uint32_t curraddr, curraddr1; + + //fprintf(stderr, "FindExtMem(%d, %d)\n", addr, num); + + for (i = 0; i < extmemnum; i++) + { + //fprintf(stderr, "i = %d\n", i); + curraddr = extmembase[i]; + curraddr1 = curraddr + extmemsize[i] - 1; + if (curraddr <= addr && addr <= curraddr1) + { + //fprintf(stderr, "1: %d %d %d\n", addr, curraddr, curraddr1); + //fprintf(stderr, "2: %d %d %d\n", addr1, curraddr, curraddr1); + if (curraddr <= addr1 && addr1 <= curraddr1) + ptr = extram[i] + addr - extmembase[i]; + break; + } + } + + return ptr; +} + +// This routine prevents us from calling kbhit too often. This improves +// the performance of the simulator when calling kbhit in a tight loop. +int kbhit1(void) +{ + static int last = 0; + + if (loopcount - last < 6000) return 0; + last = loopcount; + return kbhit(); +} + +void CheckCommand(void) +{ + int32_t parm; + int32_t command = WORD(SYS_COMMAND); + FILE *stream; + DIR *pdir; + struct dirent *pdirent; + + if (!command) return; + + parm = LONG(SYS_PARM); + + if (command == SYS_CON_PUTCH) + { + if (parm == 13) + putchx(10); + else + putchx(parm); + } + else if (command == SYS_CON_GETCH) + { + if (kbhit1()) + parm = getch(); + else + parm = -1; + LONG(SYS_PARM) = parm; + } + else if (command == SYS_FILE_OPEN) + { + char *fname; + char *fmode; + + fname = (char *)&BYTE(LONG(parm)); + fmode = (char *)&BYTE(LONG(parm+4)); + stream = fopen(fname, fmode); + LONG(SYS_PARM) = (long)stream; + } + else if (command == SYS_FILE_CLOSE) + { + if (parm) fclose((FILE *)(long)parm); + LONG(SYS_PARM) = 0; + } + else if (command == SYS_FILE_READ) + { + int32_t num; + char *buffer; + + if (!parm) LONG(SYS_PARM) = -1; + else + { + stream = (FILE *)(long)LONG(parm); + buffer = (char *)&BYTE(LONG(parm+4)); + num = LONG(parm+8); + LONG(SYS_PARM) = fread(buffer, 1, num, stream); + } + } + else if (command == SYS_FILE_WRITE) + { + int32_t num; + char *buffer; + + if (!parm) LONG(SYS_PARM) = -1; + else + { + stream = (FILE *)(long)LONG(parm); + buffer = (char *)&BYTE(LONG(parm+4)); + num = LONG(parm+8); + LONG(SYS_PARM) = fwrite(buffer, 1, num, stream); + } + } + else if (command == SYS_FILE_OPENDIR) + { + char *dname = "."; + + pdir = opendir(dname); + LONG(SYS_PARM) = (long)pdir; + } + else if (command == SYS_FILE_CLOSEDIR) + { + if (parm) closedir((DIR *)(long)parm); + LONG(SYS_PARM) = 0; + } + else if (command == SYS_FILE_READDIR) + { + int32_t *buffer; + pdir = (DIR *)(long)LONG(parm); + buffer = (int32_t *)&BYTE(LONG(parm+4)); + if (!pdir) LONG(SYS_PARM) = 0; + else + { + pdirent = readdir(pdir); + if (pdirent) + { +#ifdef LINUX + FILE *infile; + int32_t d_size = 0; + int32_t d_attr = 0; +#if 0 + int32_t d_type = pdirent->d_type; + + if (d_type & DT_DIR) d_attr |= 0x10; + if (d_type & S_IXUSR) d_attr |= 0x20; + if (!(d_type & S_IWUSR)) d_attr |= 0x01; +#endif + + if ((infile = fopen(pdirent->d_name, "r"))) + { + fseek(infile, 0, SEEK_END); + d_size = ftell(infile); + fclose(infile); + } + + buffer[0] = d_size; + buffer[1] = d_attr; +#else + buffer[0] = pdirent->d_size; + buffer[1] = pdirent->d_attr; +#endif + strcpy((char *)&buffer[2], pdirent->d_name); + } + LONG(SYS_PARM) = (long)pdirent; + } + } + else if (command == SYS_FILE_SEEK) + { + int32_t offset, whence; + stream = (FILE *)(long)LONG(parm); + offset = LONG(parm+4); + whence = LONG(parm+8); + LONG(SYS_PARM) = fseek(stream, offset, whence); + } + else if (command == SYS_FILE_TELL) + { + stream = (FILE *)(long)parm; + LONG(SYS_PARM) = ftell(stream); + } + else if (command == SYS_FILE_REMOVE) + { + char *fname = (char *)&BYTE(parm); + LONG(SYS_PARM) = remove(fname); + } + else if (command == SYS_FILE_CHDIR) + { + char *path = (char *)&BYTE(parm); + char fullpath[200]; + char *ptr; + if (path[0] == '/') + { + strcpy(fullpath, rootdir); + strcat(fullpath, path); + } + else + strcpy(fullpath, path); + + ptr = fullpath; +#ifndef LINUX + while (*ptr) + { + if (*ptr == '/') *ptr = 0x5c; + ptr++; + } +#endif + parm = chdir(fullpath); + LONG(SYS_PARM) = parm; + } + else if (command == SYS_FILE_GETCWD) + { + char *ptr; + char *str = (char *)&BYTE(LONG(parm)); + int32_t num = LONG(parm+4); + ptr = getcwd(str, num); + LONG(SYS_PARM) = LONG(parm); + } + else if (command == SYS_FILE_MKDIR) + { + //char *fname = (char *)&BYTE(parm); +#ifdef LINUX +#if 0 + LONG(SYS_PARM) = mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO); +#endif +#else + LONG(SYS_PARM) = mkdir(fname); +#endif + } + else if (command == SYS_FILE_GETMOD) + { + char *fname = (char *)&BYTE(parm); + int32_t attrib = -1; + + pdir = opendir("."); + while (pdir) + { + pdirent = readdir(pdir); + if (!pdirent) break; + if (strcmp(pdirent->d_name, fname) == 0) + { +#ifdef LINUX +#if 0 + int32_t d_type = pdirent->d_type; + attrib = 0; + if (d_type & DT_DIR) attrib |= 0x10; + if (d_type & S_IXUSR) attrib |= 0x20; + if (!(d_type & S_IWUSR)) attrib |= 0x01; +#else + attrib = 0; +#endif +#else + attrib = pdirent->d_attr; +#endif + break; + } + } + if (pdir) closedir(pdir); + LONG(SYS_PARM) = attrib; + } + else if (command == SYS_EXTMEM_READ) + { + uint32_t extaddr = (uint32_t)LONG(parm); + char *hubaddr = (char *)&BYTE(LONG(parm+4)); + int32_t num = LONG(parm+8); + char *extmemptr = FindExtMem(extaddr, num); + if (extmemptr) + { + memcpy(hubaddr, extmemptr, num); + LONG(SYS_PARM) = num; + } + else + { + LONG(SYS_PARM) = 0; + } + } + else if (command == SYS_EXTMEM_WRITE) + { + uint32_t extaddr = (int32_t)LONG(parm); + char *hubaddr = (char *)&BYTE(LONG(parm+4)); + int32_t num = LONG(parm+8); + char *extmemptr = FindExtMem(extaddr, num); + if (extmemptr) + { + memcpy(extmemptr, hubaddr, num); + LONG(SYS_PARM) = num; + } + else + { + LONG(SYS_PARM) = 0; + } + } + else if (command == SYS_EXTMEM_ALLOC) + { + uint32_t extaddr = (int32_t)LONG(parm); + int32_t num = LONG(parm+4); + uint32_t extaddr1 = extaddr + num - 1; + + if (num <= 0 || extmemnum >= 4) num = 0; + else + { + int i; + uint32_t curraddr, curraddr1; + for (i = 0; i < extmemnum; i++) + { + curraddr = extmembase[i]; + curraddr1 = curraddr + extmemsize[i] - 1; + if (curraddr <= extaddr && extaddr <= curraddr1) break; + if (curraddr <= extaddr1 && extaddr1 <= curraddr1) break; + if (extaddr <= curraddr && curraddr <= extaddr1) break; + if (extaddr <= curraddr1 && curraddr1 <= extaddr1) break; + } + if (i != extmemnum) num = 0; + else + { + extram[extmemnum] = malloc(num); + if (extram[extmemnum] == 0) num = 0; + else + { + extmemsize[extmemnum] = num; + extmembase[extmemnum] = extaddr; + extmemnum++; + } + } + } + LONG(SYS_PARM) = num; + } + WORD(SYS_COMMAND) = 0; +} + +int CheckSerialIn(void) +{ + static int state = 0; + static int count = 0; + static int val; + + if (state == 0) + { + if (kbhit1()) + { + val = getch(); + if (val == 0x1d) return 1; + val |= 0x300; + if (proptwo) + count = 80000000 / baudrate; + else + { + count = LONG(0) / baudrate; + count >>= 2; + } + //if (!proptwo) count >>= 2; + pin_val &= 0x7fffffff; + state = 1; + } + } + else if (--count <= 0) + { + if (++state > 11) + { + state = 0; + } + else + { + pin_val = (pin_val & 0x7fffffff) | ((val & 1) << 31); + val >>= 1; +#if 0 + count = LONG(0) / baudrate; + if (!proptwo) count >>= 2; +#endif + if (proptwo) + count = 80000000 / baudrate; + else + { + count = LONG(0) / baudrate; + count >>= 2; + } + } + } + return 0; +} + +void CheckSerialOut(void) +{ + int txbit = 0; + static int val; + static int state = -2; + static int count; + //static int txbit0 = 0; + + txbit = (pin_val >> 30) & 1; + + //if (txbit != txbit0) fprintf(stderr, "txbit = %d, loopcount = %d\n", txbit, loopcount); + //txbit0 = txbit; + + + if (state == -2) + { + if (txbit) + { + state = -1; + //fprintf(stderr, "Start Serial\n"); + } + } + else if (state == -1) + { + if (!txbit) + { + val = 0; + state = 0; +#if 0 + count = LONG(0) / baudrate; + if (!proptwo) count >>= 2; +#endif + if (proptwo) + count = 80000000 / baudrate; + else + { + count = LONG(0) / baudrate; + count >>= 2; + } + count += count >> 1; + } + } + else + { + if (--count <= 0) + { + if (state > 7) + { + state = -1; +#if 1 + if (val == 13) + putchx(10); + else + putchx(val); +#else + printf("<%2.2x>\n", val); +#endif + } + else + { + //fprintf(stderr, "%d", txbit); + val |= txbit << state; +#if 0 + count = LONG(0) / baudrate; + if (!proptwo) count >>= 2; +#endif + if (proptwo) + count = 80000000 / baudrate; + else + { + count = LONG(0) / baudrate; + count >>= 2; + } + state++; + } + } + } +} + +void PrintStack(SpinVarsT *spinvars) +{ + int32_t dcurr = spinvars->dcurr; + printf("PrintStack: %4.4x %8.8x %8.8x %8.8x\n", + dcurr, LONG(dcurr-4), LONG(dcurr-8), LONG(dcurr-12)); +} + +char *bootfile; + +void RebootProp(void) +{ + int32_t i; + int32_t dbase; + char *ptr; + FILE *infile; + + if (!proptwo) memset(hubram, 0, 32768); + memset(lockstate, 0, 8); + memset(lockalloc, 0, 8); + + chdir(rootdir); + + if(!gdbmode && eeprom){ + EEPromCopy(hubram); + } else + if(!gdbmode){ + infile = fopen(bootfile, "rb"); + + if (infile == 0) + { + fprintf(stderr, "Could not open %s\n", bootfile); + spinsim_exit(1); + } + + i = fread(hubram, 1, 32768, infile); + fclose(infile); + } + + // Copy in the ROM contents + if (!proptwo) + { + memcpy(hubram + 32768, romdata, 32768); + dbase = WORD(10); + LONG(dbase-8) = 0xfff9ffff; + LONG(dbase-4) = 0xfff9ffff; + LONG(dbase) = 0; + } + + WORD(SYS_COMMAND) = 0; + WORD(SYS_LOCKNUM) = 1; + lockalloc[0] = 1; + + for (i = 0; i < 8; i++) PasmVars[i].state = 0; + + if (pasmspin) + { + if (proptwo) + StartPasmCog2(&PasmVars[0], 0, 0x0e00, 0); + else + StartPasmCog(&PasmVars[0], 0x0004, 0xf004, 0); + } + else + StartCog((SpinVarsT *)&PasmVars[0].mem[0x1e0], 4, 0); + + if(!gdbmode){ + strcpy(objname[0], "xxx"); + if (bootfile) + strcpy(objname[1], bootfile); + else + strcpy(objname[1], ""); + ptr = FindChar(objname[1], '.'); + if (*ptr) + { + *ptr = 0; + if (symflag && strcmp(ptr + 1, "bin") == 0) + symflag = 2; + } + if (symflag == 2) + strcat(objname[1], ".spn"); + else + strcat(objname[1], ".spin"); + methodnum[0] = 1; + methodnum[1] = 1; + methodlev = 1; + } + + //LONG(SYS_DEBUG) = printflag; +} + +int step_chip(void) +{ + int i; + int state; + int runflag = 0; + int breakflag = 0; + SpinVarsT *spinvars; + for (i = 0; i < 8; i++) + { + state = PasmVars[i].state; + PasmVars[i].printflag = (LONG(SYS_DEBUG) >> (i*4)) & 15; + if (state & 4) + { + if (PasmVars[i].printflag && state == 5) + { + if (!proptwo) + { + fprintf(tracefile, "Cog %d: ", i); + DebugPasmInstruction(&PasmVars[i]); + } + } + if (proptwo) + { + breakflag = ExecutePasmInstruction2(&PasmVars[i]); + if (PasmVars[i].printflag && state == 5) + fprintf(tracefile, "\n"); + } + else + { + ExecutePasmInstruction(&PasmVars[i]); + if (PasmVars[i].printflag && state == 5) printf("\n"); + } + if (!breakflag && + !(printbreak && PasmVars[i].printflag && state == 5)) + runflag = 1; + } + else if (state) + { + spinvars = (SpinVarsT *)&PasmVars[i].mem[0x1e0]; + if (PasmVars[i].printflag && state == 1) + { + int32_t dcurr = spinvars->dcurr; + fprintf(tracefile, "Cog %d: %4.4x %8.8x - ", i, dcurr, LONG(dcurr - 4)); + PrintOp(spinvars); + } + if (profile) CountOp(spinvars); + ExecuteOp(spinvars); + runflag = 1; + } + } + loopcount++; + return runflag; +} + +int main(int argc, char **argv) +{ + char *ptr; + char *fname = 0; + int32_t i; + int32_t maxloops = -1; + + tracefile = stdout; + ptr = getcwd(rootdir, 100); + + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-l") == 0){ + if (i+1 == argc || argv[i+1][0] == '-') + { + fprintf(stderr, "Trace file not specified\n"); + spinsim_exit(1); + } + if (!printflag) printflag = 0xffffffff; + i++; + tracefile = fopen(argv[i], "wt"); + if(!tracefile){ + fprintf(stderr, "Unable to open trace file %s.\n", argv[i]); + spinsim_exit(1); + } + } else if (strcmp(argv[i], "-t") == 0) + { + proptwo = 1; + pasmspin = 1; + memsize = 256; + cycleaccurate = 1; + } + else if (strcmp(argv[i], "-p") == 0) + { + pasmspin = 1; + cycleaccurate = 1; + } + else if (strcmp(argv[i], "-s") == 0) + symflag = 1; + else if (strcmp(argv[i], "-P") == 0) + profile = 1; + else if (strncmp(argv[i], "-m", 2) == 0) + { + sscanf(&argv[i][2], "%d", &memsize); + } + else if (strncmp(argv[i], "-b", 2) == 0) + { + pasmspin = 1; + cycleaccurate = 1; + if (argv[i][2] == 0) + baudrate = 115200; + else + sscanf(&argv[i][2], "%d", &baudrate); + } + else if (strcmp(argv[i], "-gdb") == 0) + { + gdbmode = 1; + cycleaccurate = 1; + pasmspin = 1; + } + else if (strcmp(argv[i], "-L") == 0) + { + logfile = fopen(argv[++i], "wt"); + } + else if (strcmp(argv[i], "-r") == 0) + { + cmdfile = fopen(argv[++i], "rt"); + } + else if (strcmp(argv[i], "-e") == 0) + { + eeprom = 1; + } + else if (strncmp(argv[i], "-v", 2) == 0) + { + if (argv[i][2]) + { + sscanf(&argv[i][2], "%x", &printflag); + if (!argv[i][3]) + printflag *= 0x11111111; + } + else + printflag = 0xffffffff; + } + else if (strcmp(argv[i], "-d") == 0) + { + debugmode = 1; + } +#if 0 + else if (strncmp(argv[i], "-x", 2) == 0) + { + sscanf(&argv[i][2], "%d", &extmemsize); + } +#endif + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9') + sscanf(argv[i] + 1, "%d", &maxloops); + else if (argv[i][0] == '-') + usage(); + else if (!fname) + fname = argv[i]; + else + usage(); + } + + if (eeprom) + EEPromInit(fname); + + if(!cmdfile) cmdfile = stdin; + + // Check the hub memory size and allocate it + if (memsize < 32) + { + fprintf(stderr, "Specified memory size is too small\n"); + spinsim_exit(1); + } + if (memsize < 64) memsize = 64; + memsize <<= 10; // Multiply it by 1024 + hubram = malloc(memsize + 16 + 3); + if (!hubram) + { + fprintf(stderr, "Specified memory size is too large\n"); + spinsim_exit(1); + } + // Make sure it's long aligned +#ifdef __LP64__ + hubram = (char *)(((uint64_t)hubram) & 0xfffffffffffffffc); +#else + hubram = (char *)(((uint32_t)hubram) & 0xfffffffc); +#endif + + LONG(SYS_DEBUG) = printflag; + +#if 0 + // Check the ext memory size and allocate it if non-zero + if (extmemsize < 0) + { + fprintf(stderr, "Invalid external memory size\n"); + spinsim_exit(1); + } + else if (extmemsize) + { + extmemsize <<= 10; // Multiply it by 1024 + extram = malloc(extmemsize); + if (!extram) + { + fprintf(stderr, "Specified external memory size is too large\n"); + spinsim_exit(1); + } + } +#endif + + if (profile) ResetStats(); + + bootfile = fname; + + if (!fname && !gdbmode && !eeprom) usage(); + + RebootProp(); + initialize_console_io(); + if (gdbmode) + gdb(); + else if (debugmode) + Debug(); + else + RunProp(maxloops); + restore_console_io(); + if (eeprom) EEPromClose(); + if (profile) PrintStats(); + return 0; +} +/* ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +*/ diff --git a/spinsim.h b/spinsim.h new file mode 100755 index 0000000..aeb77a0 --- /dev/null +++ b/spinsim.h @@ -0,0 +1,13 @@ +int step_chip(void); +int CheckSerialIn(void); +void CheckCommand(void); +void putchx(int32_t val); +void CheckSerialOut(void); +void spinsim_exit(int32_t exitcode); + +#define WAIT_CNT 01 +#define WAIT_MULT 02 +#define WAIT_PIN 03 +#define WAIT_HUB 16 +#define WAIT_CACHE 17 +