From bdd3741b1090c00b8383b1cf6b203458bf6057f4 Mon Sep 17 00:00:00 2001 From: David Betz Date: Sun, 22 Mar 2015 13:30:10 -0400 Subject: [PATCH] Initial push of the contents of Dave Hein's latest release. --- Makefile | 27 + README.md | 135 ++ conio.spin | 136 ++ conion.c | 73 + conion.h | 11 + debug.c | 222 +++ eeprom.c | 223 +++ eeprom.h | 4 + fileio.spin | 189 +++ gdb.c | 418 +++++ interp.h | 151 ++ opcodes.h | 250 +++ p1spin/Simple_Serial.spin | Bin 0 -> 19402 bytes p1spin/dry11.spin | 243 +++ p1spin/p1spin.spin | 2069 +++++++++++++++++++++++ p1spin/spasm.txt | 351 ++++ p1spin/test.binary | Bin 0 -> 12436 bytes p1spin/test.spin | 14 + pasmdebug.c | 231 +++ pasmdebug2.c | 448 +++++ pasmsim.c | 742 ++++++++ pasmsim2.c | 3377 +++++++++++++++++++++++++++++++++++++ pfth103_p2/bufser.fth | 89 + pfth103_p2/changes.txt | 94 ++ pfth103_p2/chess.fth | 608 +++++++ pfth103_p2/chkcore.fth | 145 ++ pfth103_p2/chkcorex.fth | 57 + pfth103_p2/comus.fth | 29 + pfth103_p2/fds.fth | 88 + pfth103_p2/i2c.fth | 217 +++ pfth103_p2/init.fth | 400 +++++ pfth103_p2/license.txt | 22 + pfth103_p2/pfth.TXT | 1 + pfth103_p2/pfth.obj | Bin 0 -> 20352 bytes pfth103_p2/pfth.spin | 1606 ++++++++++++++++++ pfth103_p2/primes.fth | 62 + pfth103_p2/propwords.fth | 40 + pfth103_p2/rc4.fth | 42 + pfth103_p2/rc4time.fth | 49 + pfth103_p2/readme.txt | 244 +++ pfth103_p2/see.fth | 65 + pfth103_p2/serial.fth | 20 + pfth103_p2/starting.fth | 65 + pfth103_p2/time.fth | 2 + pfth103_p2/toggle.fth | 33 + rom.h | 2756 ++++++++++++++++++++++++++++++ spindebug.c | 592 +++++++ spindebug.h | 3 + spininterp.c | 1313 ++++++++++++++ spinsim.c | 920 ++++++++++ spinsim.h | 13 + 51 files changed, 18889 insertions(+) create mode 100755 Makefile create mode 100755 README.md create mode 100755 conio.spin create mode 100755 conion.c create mode 100755 conion.h create mode 100755 debug.c create mode 100755 eeprom.c create mode 100755 eeprom.h create mode 100755 fileio.spin create mode 100755 gdb.c create mode 100755 interp.h create mode 100755 opcodes.h create mode 100755 p1spin/Simple_Serial.spin create mode 100755 p1spin/dry11.spin create mode 100755 p1spin/p1spin.spin create mode 100755 p1spin/spasm.txt create mode 100755 p1spin/test.binary create mode 100755 p1spin/test.spin create mode 100755 pasmdebug.c create mode 100755 pasmdebug2.c create mode 100755 pasmsim.c create mode 100755 pasmsim2.c create mode 100755 pfth103_p2/bufser.fth create mode 100755 pfth103_p2/changes.txt create mode 100755 pfth103_p2/chess.fth create mode 100755 pfth103_p2/chkcore.fth create mode 100755 pfth103_p2/chkcorex.fth create mode 100755 pfth103_p2/comus.fth create mode 100755 pfth103_p2/fds.fth create mode 100755 pfth103_p2/i2c.fth create mode 100755 pfth103_p2/init.fth create mode 100755 pfth103_p2/license.txt create mode 100755 pfth103_p2/pfth.TXT create mode 100755 pfth103_p2/pfth.obj create mode 100755 pfth103_p2/pfth.spin create mode 100755 pfth103_p2/primes.fth create mode 100755 pfth103_p2/propwords.fth create mode 100755 pfth103_p2/rc4.fth create mode 100755 pfth103_p2/rc4time.fth create mode 100755 pfth103_p2/readme.txt create mode 100755 pfth103_p2/see.fth create mode 100755 pfth103_p2/serial.fth create mode 100755 pfth103_p2/starting.fth create mode 100755 pfth103_p2/time.fth create mode 100755 pfth103_p2/toggle.fth create mode 100755 rom.h create mode 100755 spindebug.c create mode 100755 spindebug.h create mode 100755 spininterp.c create mode 100755 spinsim.c create mode 100755 spinsim.h 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 0000000000000000000000000000000000000000..a7a8f2bfaafd5d1a95d9466cca62bf018299b1a5 GIT binary patch literal 19402 zcmeI4S#MR>8HTs$UDZmtsMK8K;?#;8lhlAo+RUj8*n|Xwg-r%kX$7`1ZafeS7&85z zUiLQWkIFA-`#$SEpVwOZ?BjDh5Td5qGG`BKee<*?{`2pbnwOfFe-hWPn_r3+sOjli zYBrj!=3cYetm$dC*=?RQ+s#UIx4GZ!=x(QZsCTqm)0>UvmRk0jOX>bmde>_nH8ahb z<~6-P?DcX}Q!^`U4}^P1@OPWH1n;7rHbh^qxvY1$MA@1s{DYns(-){&REy1KJ<+t4 zzI~8r?=>H%FPn+(EkUH;2ZC@%SFc$Ry!*npAwHqJP0d9?xhHJ!y)JAI)MiQ)oYwF8 z=A5oS>25JWK`xuRdz^4wNisa6uSdVy)Sv-$v?kcA`rS!9+({hr{!WrwPgJ5QxQ#Yw za7`LIIxV$qehPLRb`!to0lqB-bAL;GcUv>^$kvSh?#nz@AP}!8xV(nd52khj-&kySkvz9NkT= zu%Wxc0OT#vzNzPp3fet=r3W?-{euusOCF({`0X{z!rBw|Qd96ao}Q4=R-$NI^sJ~K zbXfwxu(aB=fv@D27+{YupZLyv;&M}Q?V(!3)8kge+mROjuJH9q+auCiW5YUnIdw|i=W4WihmPBHWIciy>V3J{evV!tckCV$Q#X)zN;q+)FJVF1joxOpk;yGK{kc z_KQZ*CiIk4j^_EHdLk1%>OrzlAZ_Ulc5cYoE+ccjs@CX+eDFlSukY*ToctQT_e-}~v`T93D7YwHPXSBWk z6Bd93y5zLFZ<&YF(<5PZq$CP~VJ~THGihck(X`(GV%u30esqcEkP%)oDD(6B8Zswd zo>wl#Go4r8=zl$m%(2$({X7ub3Z z^WBqY&j<^#o5;W0AqBo8g;`N%DZE)of$HKQ%X8#w*EqQnuq3d1$13W&Cj}J|m*bcC zj9odtb;X_qdBKue!6EI4!Ir1BO=U&?$StdJ2}1_wMFUgZCtyf#+} zdx8OvP`s%xcamhj(6jk}L(!k8^S+`tIr@*q(~88G2Bn|sK{JLlf@q2C>_ngVJM$gT@$q1+CuJ2DMz|mB-T!+9OkGl%}8F`ed(_1$(4<*FGfCP z4NA?)`)x@YXxuR_*%L>O*Qb^Y_Am88*;UUPuK1Y73aZV*K zq0+(IutG+Ft`)+Y&ZhTe>}RBB|6(-ge8KoI^FlU*UcNFOAtLdw=^&a+_wyJyJ%R?7 zsf%i$p1l}WqX*Pm(&vsKyLt@|bM8ixRHm*5Jc6d~W44EH)LZme61DI#p*vg2bTLM{ zkm$aoe~~r)^2q0OvT(+N^z*pT6*tunF@LXLA%tG$nopDm7gCO%6TY|hH5M&QQC&+? zQ&3fBx(=d>){cp1(-^VV;zD1G#M^_fCGlETv^`~YduRCbO+BO4Zt09iN6GgvdJYr0 z{#iw?VGsx3kB5V3NB(GInU+-VOA^2>XHv?{5Ph8?+7JdQ%5k^;_N&Qe$o1T0-Ln1E z-E&m0HWWX1!-BF=@Va}Jy}E7U)MVEfZBhC4g~{)J7$%cO-(H-&qWF1Ty1693WKMy| zb!vpPy7@kcis3ZyWi%DT`0k=)QI`0^UlK2e>249n#t!ov1H8MJ)>7Q z&)t2HV)V=K>$~orqk7da@)Oi`Q#kyKdmlcRud>I|b$D?3$tK-V=U$Vc~RDr&(%=dZok6(<&IDU)n zINKGW+gj}IdDIAf5XIf{>$d+c&uLTM-ScU9PRZ4{TI}X_d^>;pnb~>CZCmE$xAMN5 z+iu(HvdR(`_uW08hE%D&I)9$G^B%>UK%>raoWm&85uOP=cK7A zX+aAmEkO?&tZQP^m1m0IQ9o8{j(?T(4B}<(>XvjDl(p9=Ojmm?>8$AbT34p`D0D)Z zXVO;Eyd<-B%$k+69eJ*uSu*BZp){zqr`Gl#E2Qi{f!|*9PJ;);DirgBN4cOj!QL9DgP_*5mI4p>285 z@36nMU9F}lij;|%=rMEzT;_yX?JQ~fR(qHZi*rNJWlkAvPfjWlsy|#s%Q?ktbjy-dm z@`)U^O4|Sm>wf%R(At!vAC~nXX$3p!X@#9Ng4p4L9TOAXnh241>M{TBc!~ts+d)hr zcCdmHed=1m>s-B52|`W|dQIu)8-FVBxvy_>>S?P6tj z1hyXQ-m&s)KW0}G-&tFQZuE?%S>a{ha&WSnEECQ17de&)jZNk#3Z3mZ$_i$^-|G00 zbZ{hea6E;^$PuOe{=a5BZq0^emlhB)cB*9=whKm|-bE7;;e7JPE}IXZ$-iOMVYQ{N zkw;=Anr*z)^SVf>GTW>fvZ znHbu*rXI`%Uuw24GLUyKxfZHn9H!o`p`BEwsJ+)X&>&|q201RR^>Fv-CUP}(A*b^g zU9j_uJj$*mk1?nba`r}crCz{_Crs^+KbQk3_410m{q8e=DLf@8pXLVq>2hdrxjb=3tJl}~J6*39XY;U^W8EVBvK z>upGUEvazzHeFHgNP52cTgr0h27c?^qd>&2c2%Wu?kZv!^VcPJ%qqlKHuxGwO{Op) zZ0y6G8K5WVjJCCvlcVAb__}1t3}4n&P-lH)T6!7*(a!Rj5ZqDHJ*ytX?LpXwk(ep2 zdw8!gwAd1AS;IkC(;$`fGF>4X%>uGGnsg=1jzq6n{lgoO4RaV4I4re}yPf!2)vA7@P1lhmvv#_&azVu?>{uZTc z&PJE#0f{HnyFO9J=}dN}bDEqHD%oo_%}Dw5PM-OQOt!8Tj5NFtnm+Vr28UBm-gnK+ zFx5BtnZI?lpxS1=ffMF2n?jZ}HT2{p6O}fxDv!-Mv&2{S=zDgbu@8I3S-D|01FHGr zoy=hm*q^vM{q`TfXe)EVBH zZMuLAB-XPyRUL9^_hzL9jnzB_c3^rG12@)zPk#VEXD7`uX3xp~6{p3WH^ahhWwxYjo%ytNyBGfC zc~a&PiECvHu=Vi<_}w03f5PkVN5|;+e@Qs+<^RzG%Ny-sXH=8?n3c)1)_6DmkioJ} zqRvV3OQ~vF*8iTunNr?dNww6Xo~}0^>FJW*UefyswOHzZpGZ;S<5XY0uXZ<6on;s| z)b5&|KUG^-WIXfqq1s;)EMgs}XTZV98K7R*J-B_I=1RgzJ9=DH1$R^ZxWBA-7y9_F zsh8_J`cdnd(q+A8mDn5(${}P>(+f^hGOykXdb%OZ@AtWx71k@F11z5=4(8K6<4AKb z-{)agy%&=-m(}8;XuX=AczaVY7uAjmm6PB|qo;qb>ksbc_1#>~B?^$^8MWY@+abA+ z^v4&p2Ys9o&iu|M>7bPxeSVN^`wAIcRJ%oS1m4Sn22}c96=g^OiCjq3!aGv9nw~PZ z)-5`kRf~lr8%_u>=RabOJpAt(NJ>>3eQvzL68sx~TqFlB~kApdLwJb9}{O z(Ebhm8#a}(Vy{S^R$L(iET1oyJm*odeRC4FZA%U-g&yNZ|0P}F6ImaF9%d+EpB}Fa rQp*XKIq`+0uzTcac|^}PWGv;dmu1ksV{%x9{lE79`IHw1_hkMTbZJ&B literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..224a3bbd28bfadb23f650c6ffb7be1e2b2aab92a GIT binary patch literal 12436 zcmeH{-D_M$6u@V8XSTbOq)pS(7P^$1WJ%VrNjGgym7x`hcNZ1h;FagQ;FBF9>A+>jJ(l7F2j_tr&cO< zN!TG_D+#Bpfzq*4)>~b}^bV$5F!kxk)LT=qIM7PgCaZOTEUx+ivA(o+c`Y)A7Qog zvV(4d0Vg%%M-}$)KqpivDe_Ti0NZ(`kS(%= zq+t^e@er=M1s}4&W?hp|gIDY@HW*~O7ie^70CL;{rm!Pp&l}HF?6_(SRP1O1`b*_j z8FAXwKy+-CIh3WERVHz+qZ-=*MGXF6bE=*|_Hw9U$OsB<~bi%Y!tEiY=$Qjr&peW0#Pfw#_@idGT+7gNsCs~sd=w~LOp@?8hy zgSXRxV9{AJDBMQ9P|8i`N`>h{>0;?2BU+4jbre%w4C}1)9OCI~R$6ne(FQob&lo67 zXFCcd!59x%V&mK}r%Pa;M(=2f1u+`D<=u|y28 zSi3YQ2s-T!yEl?*|7;%-^9Y)}T8*jjK<4ol6bJnZ$lHjZMGzlGXg4PR`h3D$!{ZMs z5etSW*F(#dpyiHAIB^J^@S1Vx=6+xjqyw4g%=qI5Zng{tlC?XF5rG&HmYx!Til4JbtTP8~aLIb`KNC3q=H>QR=5~mpAfV zem@@jyhKT0O67?)reLF+60Yy7u@-EoVD?QWt|RBJ8BY=~ziamOefSM>i+6JC5o?C0 ft!hLaO02OnkkL45Y0y;^!yk|sZ2ZN*IRO4U0DUhr literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d1b94ac655eaded4c5e69d30a1d0412993047000 GIT binary patch literal 20352 zcmeHOe{5XGaegO})bT9ZDlNwne<({zh-LAIj+Cq@^b>W8M8`sCk)i0=trgJ6yGQY& zfKno@(^aa_^I|po1fV_>?d2=8q-_fIIizE?fZs(fBkr} z6McyDql5l;T5f!D8htVkxB0ERylZP)hS9gvZ+W}Zzx~=C&qMnR@TAWV|LAz;@BjFC zhJ74N#!C9hFC}iQZB6=_mSki4i;1UTW=Yo!%S7 znQqzXdkOH3=8eW94Sy-;TjsoD5o%{>>QNi@`-M zw(pFCe;s4H@}HxO{+Yz~wbxpb=_lgwE$d*d$s2Dbl9eaCAs#wE&?_igWdRA zB6$k1l^D$LceF9yzF7HvvGUe$Wo59~asFE6?FI(6Fe z9zR1k^qFbd*_cl4@{{empnK?g?cv6&?J?Q@s9kNF^u&hS)kYsq`Yp6^$IItI&*^IK z_D1IF{f*51fU)2Gs9y@}*Jx8u{55QiZ60ipFltbN$U0WNVELms2 zeQgb~6VB^5@EBWX8(|L*?+1Ug)2xflclb%^zg_LRrBiJhwtq8`!n`{oyH0Yg0$d-rksQyB~VR`$hB>IDBUX{E&|XWPT;_ z<+W`o|Me@B*A73EgdKc}<6tec*)r@<+7mk()1>wD2XxNa&b6<87X4r9TzmbqiOXvS zK9h8lDab0>7<~Y;ZfW!Tzq`$+&-UoY{vG-hd7+Iu|2^uw)6cYGJjl%B{L?!cGpQYG zZ$7ePat3kWNV3hJ{s2z4AWD z@-gs!^!7uu@E12$u!hD^KkWM5*yVYj@Akawc&^}?#d8zS3Z6wg*AZ*^3_h&SP2+iM z@4WL4W99lb@d2AZn-bWRz#S!!9vMA!_^~7JKl*{}d@dg>+!5*jByhDQSSi%uO1zhM zueN+*xlr#x`ReY~*6e(_T1OeK#Jj$Gbz86!o?yFntg?VqU_iXpKpt$ED z$0xh5w(JFPFWUKc4mjh55^(gd*nM?NzT!ze^IpgR_{D6k&h|9wpXt8ZTC0m1!alD6 zXFgjCh_eIFm%FcSdm*UKmuo?Y^9}S{fSHgt8S8$}`)>DYOTJpJ{2^dJ>t5ZOU#@tE zP<|Wm+Qn?;2+Cg1YD=Y%yYLkhx1(Gw7mIJ8ysKw*%Q)otXDIJOxe6iu1SKcW15&uS~+D;!PRf| zT-~-ru}r&l@K?Gnch91AfA6KlpoRDJ z&UOuUwRnenJ?~WSr(5PezEmOp(VmsAK`i2Pppz>vmmHlz^xxSt*p={JLBE7&dRAq; zO7Eq%Y%T{2)A0s-*1C`4AbL%-|jm+-E29d(@HofJAoep$}3C?77ssGG7j5KiFlw@9tK~t%BPv@BOi@UGDkWo@>w;=k*VJUfz@MeQnP- zck}mFcca(uV%z1O*Y*s8_RF^YR(BC~N{M(F+WW$uOKr7_1vpGA`>tD{zoUz~-ud3u z*12N2jAiR>Nf3MU?|+j7MvV1_rmthn6bq#b;|s;?`I;Fu1LpCL)R-wOEd}`kys9}m zV(4y7CXScuQ?zqtB%L-4r-pvhJRWuINOh#nnc2m_AR50Auy;^HbEOz81*N({aFmWU zQ!g7jjf)2E*z}+4H!yLc)JWh&v1m%mOY=dsX0p}56iNnB)nrMaP&1Wsp;RB%u})1q zar(@JIXN*oY0jShl?l!x7Zi)N!b^cUtPHchl&xJbhio0IN!mxFy0nk5P6j@B;_T^@ z=Irc=lOHzEOwF7+OS08+9kQb9*KU|#)r=U%1qF;EbQpokkH~aXL=^ofkZ}dv2rc{4 z2I+W6Y1)@%iENlBCr+H2m@y|#o}4&)c4|i08qb#@<4}p?^X2@Dn7P$yDZ3Pmuhb1$ z%Vhv%OB%mJ2FZZ(Ew(^Juw=Ul2;HJ4M@aY-u#D>v!|??mJh&#y3*~CHrQ($teemhi zlbDjsq*h+8<^qGfz%V(0^2@u~wQF`{#d2?L)q(^)uC z8g@3HuLiZ6DK8jik~FjmqHd*J3d|$XXt6#|9CiYY+$)+gu4N0>ityo2(lo*3@j) zDpN*h*Ogt?34cJi0Q}vs1hkM8@nb{Bxe{8jw*LlO#UP8+0W|PWOpkAsKLqV$U2qsN z&A7IY+crz18N+GJy={E8p=tby$rB$sE52%c^7NSx(^J_zNqxfzA}6`YWz5mE#8CAN zVgTcec@BRRn9am72BSCp;AsTBbLQk?wsby#T=Rh@HApBHs^ukv{oKNGDaR}cr#FFA z$ca>poUEl@{Fr{-#4+7)AYL;wDMb8_mb zrzXzKN`G@^>KQZpu}-a8IB`E<#A80v5H7xlzCKN zPvcNi|2S?`j`xAG?0Bx-y*WD`a3PoUow>QWHETh8h!N!ahSXodH(~<^k4OimO%)oK zkzblvh6u455yPq^%e3QDQ%`?zazb}SG~Y2(8)phG+aMU4(q1}X4oHKHv@F%MHsuG@ zW=3@TBb+090};W^gI%g8-aHg*KCrPlHd6lJ#^!^u-Z%{1h(KUC{@n7x*d9(iDOi#7 zO%4AT0gAvR@C%{Jj_rVK4h0#!a&za4AAz{-Vsum~AuL&rLam#Fx@1*Mcj6w1R&aC6 z!YHY8?2xNbmAy<&II~Q1J7m*hwpmS}BrJ!FuuWKDftF)2^FnaFDuf4Nh{kYoYNp8) z2Kt1xjEKXIZMRtmNlr$VA4m@W2-6^aP)B{v#;P>juP}@xljppctp!v;TvG#;zf2aS z1iQ9$uo^6pvLuwirCyy_(a&KEIGi9FtaOCSb={Zm(tkOUkR!0Lv~HR>SO@EeaGatR zM4dqWmQNA8Evw`axn`$MP3giq;JCr^A@4dl;q<^kqpdO_Sug_k_ZkM0g#~E7dF_sw z#d0xkast)q?$xCb^DClVi7yt<`kTlI_txwlX>UxKm?Zb$u|#OEP2GgEkdcfm3XbQZ zowX6`k!pqWB~X$Tg4iVtM;4i#uZeY8gtRJiC}y+u7b^k!GqiJ%T*mMMMh2BsH*!d*K#RCLV23hs=~Q~ z(PO;Is9`0XHhEDp-m>9f7J_c{!6E_SUpPwZVTYC(2&~H;8IXwzd}K&^N_n(T1trU_ zFFG6>a4TvQE>--7qN{&9n$|zbaIHhJUJ%+=%#2Rjowg0QLk>B&8G{-?l@AP_ub3u_ zP;>xebO&=hk_u1lVkc8sBI*`Gis&P|NTBe>LHU?3QbEE}Zcy71$VTEQq>VH$;#9F& zkDv!E4cz_3M9Hhb8e8-r3O25@7Az4A%uLAv6dp{;O@@K4IC)JsMEO9Dg=)FP1Ki`*spy=g6Yn@8&r9ovW$QB4eLuA|V8q1ryi~gJ$af^& zG)|#}GuJx$a$V533gS|BMg6@v4$+CoI9l#Y$meCKaq+%np$S98%R4r%OChk1LwkHj zyRt6Jz1MRsS9RlYI<$R|#hSDwO94YfC3+DRMmQ9`13KyAv+wnz3C|!DO%4@dL1VhB z!KH9hkT)Dtnz+iqQjZcP>k49S*tyPdy3hqSxj2PisRX&Y(F=HLhzBJy!a|n&85@X~ zvegSX%(6lXor()iT(0>Fdg6kS_l%ZAsZgN1B4x3cwR z+`-A5CCgEqGHyupw91};(fUJ!c2_3RAy=QShd%2n;|q=};)QGxgTDLN+l2qF11~Pu z7ZI#v8bh>)A=(CvS>`lcog<9myIbnYHuMl-AZX}%isiFaLn6&f#gdJ!t^b6|^6;I= zjIUd9O*tfFFFc8par>>(at$dR@myXf)6A)PuJd8IA)}uY(S-hokYl0ebq*H5jTZ*? z2u+BHeTPKW4HT5}cC6;R8;Kjd!IOy~RkDCP#11T!QeLJ(2AfCIb7aYm_0~toIGXlW zXB|s9_3;{oL%u^}j^fP5;Rrz*5q4Tfd3e8ztB=Oxs#;8Z4UCzwQdw?^V_7+g^Gkpl zR`Q^Ej#e5wB$DHy{4sHD`b#HwEV_Bl!z0gg44BMq$Glz1TY0KAh+;<)d6yR2? zHrP4w6FVGN>rPKj--ctcGQZ3#Z3&|VlU@*!bB~T?h}@oX9JVPiikRRbxP>SSSA(_b zHNMcmXN}>`My}jJM(;XENjy2O9;_=D0og?0cz-PM92VyZ6*8HR%@pO}zci{YMx zHioISAFmfqELW6VHxB9s^xZsaEQ*jS;` zAh#4ZU48SVwhJi^V*!8Mu}5c}Y;o+OK@X60`u8U1?xdUU&~Zj&KLm5pI;U_&f=LhXj^6eWhVlJ~ zGHijs!4YnV1C|`Zqpn|u?YxVQv6E32adsQ=ld<>G79_k#--u0NfpKD)M?9e*bgM)z zBld_^M#Q$x#9p;Kk|t!9-S~G7F)}_~g+~No^`RuvmKs^4 zVVd#)GV&5B@frJ+Dz5(6q=n*gO5dq6NWSoTAtTLzAIfsq}m*-@PKOfXD2DsA0X{Fs+ zlFB@G(n#55C*^Wef|nQYtqBH^|KZ|}#5gK)ZG3?s44{aNm;hYbpsfTy#B&7{Wv@OY z?h^U3yzQQyjnH+ux`c$+{>L2YGJXu#7q+{93|X8l57E83hqOnBkY?$KqXY6mC!vSv z3Hgl5T-br&!x2au2rTiFD;CO#QhHb+!p7MHfh8k{3NaABOqQsJ1k^e0J4C@KDs4cP zjostcB%{3)nF;X4&c+b 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 +