diff --git a/sys/src/games/gb/cpu.c b/sys/src/games/gb/cpu.c new file mode 100644 index 000000000..278c499de --- /dev/null +++ b/sys/src/games/gb/cpu.c @@ -0,0 +1,843 @@ +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +#define lohi(L, H) (((u16int)L) | (((u16int)H) << 8)) + +u8int R[8], Fl; +u16int pc, sp, curpc; +int halt, IME, nobios; + +static void +invalid(void) +{ + sysfatal("invalid instruction %.2x (pc = %.4x)", memread(curpc), curpc); +} + +static u8int +fetch8(void) +{ + return memread(pc++); +} + +static u16int +fetch16(void) +{ + u16int r; + + r = lohi(memread(pc), memread(pc+1)); + pc += 2; + return r; +} + +static void +push8(u8int n) +{ + memwrite(--sp, n); +} + +static void +push16(u16int n) +{ + memwrite(--sp, n >> 8); + memwrite(--sp, n); +} + +static u8int +pop8(void) +{ + return memread(sp++); +} + +static u16int +pop16(void) +{ + u8int a, b; + + b = pop8(); + a = pop8(); + return lohi(b, a); +} + +static int +ld01(u8int op) +{ + u8int val, a, b; + int time; + + a = (op & 0x38) >> 3; + b = op & 7; + time = 4; + if(a == rHL && b == rHL){ + halt = 1; + return 4; + } + if(b == rHL){ + val = memread(lohi(R[rL], R[rH])); + time = 8; + }else{ + val = R[b]; + } + if(a == rHL){ + memwrite(lohi(R[rL], R[rH]), val); + time = 8; + }else{ + R[a] = val; + } + return time; +} + +static int +ldi(u8int op) +{ + u8int val, a; + + val = fetch8(); + a = (op & 0x38) >> 3; + if(a == rHL){ + memwrite(lohi(R[rL], R[rH]), val); + return 12; + }else{ + R[a] = val; + return 8; + } +} + +static int +ld16(u8int op) +{ + u16int val; + u8int a; + + val = fetch16(); + a = (op & 0x30) >> 4; + switch(a){ + case 0: + R[rB] = val >> 8; + R[rC] = val; + break; + case 1: + R[rD] = val >> 8; + R[rE] = val; + break; + case 2: + R[rH] = val >> 8; + R[rL] = val; + break; + case 3: + sp = val; + break; + } + return 12; +} + +static int +add16(u8int op) +{ + u16int val1, val2; + u8int a; + u32int val32; + + a = (op & 0x30) >> 4; + switch(a){ + case 0: + val1 = lohi(R[rC], R[rB]); + break; + case 1: + val1 = lohi(R[rE], R[rD]); + break; + case 2: + val1 = lohi(R[rL], R[rH]); + break; + default: + val1 = sp; + } + Fl &= FLAGZ; + val2 = lohi(R[rL], R[rH]); + val32 = (u32int)(val1) + (u32int)(val2); + if(val32 > 0xFFFF) + Fl |= FLAGC; + if(((val1&0xFFF)+(val2&0xFFF)) > 0xFFF) + Fl |= FLAGH; + R[rL] = val32; + R[rH] = val32 >> 8; + return 8; +} + +static int +ldin(u8int op) +{ + u16int addr; + + switch(op >> 4){ + case 0: + addr = lohi(R[rC], R[rB]); + break; + case 1: + addr = lohi(R[rE], R[rD]); + break; + default: + addr = lohi(R[rL], R[rH]); + } + if(op & 8){ + R[rA] = memread(addr); + }else{ + memwrite(addr, R[rA]); + } + if((op >> 4) > 1){ + if(op & 16) + addr--; + else + addr++; + R[rL] = addr; + R[rH] = addr >> 8; + } + return 8; +} + +static int +inc16(u8int op) +{ + u16int val; + u8int a; + + a = (op & 0x38) >> 3; + switch(a >> 1){ + case 0: + val = lohi(R[rC], R[rB]); + break; + case 1: + val = lohi(R[rE], R[rD]); + break; + case 2: + val = lohi(R[rL], R[rH]); + break; + default: + val = sp; + } + if(a & 1) + val--; + else + val++; + switch(a >> 1){ + case 0: + R[rB] = val >> 8; + R[rC] = val; + break; + case 1: + R[rD] = val >> 8; + R[rE] = val; + break; + case 2: + R[rH] = val >> 8; + R[rL] = val; + break; + default: + sp = val; + } + return 8; +} + +static int +inc8(u8int op) +{ + u8int val, a; + int time; + + a = (op & 0x38) >> 3; + if(a == rHL){ + val = memread(lohi(R[rL], R[rH])); + time = 12; + }else{ + val = R[a]; + time = 4; + } + if(a == rHL){ + memwrite(lohi(R[rL], R[rH]), val+1); + }else{ + R[a] = val + 1; + } + Fl &= FLAGC; + if(val == 0xFF) + Fl |= FLAGZ; + if((val & 0xF) == 0xF) + Fl |= FLAGH; + return time; +} + +static int +dec8(u8int op) +{ + u8int val, a; + int time; + + a = (op & 0x38) >> 3; + if(a == rHL){ + val = memread(lohi(R[rL], R[rH])); + time = 12; + }else{ + val = R[a]; + time = 4; + } + if(a == rHL){ + memwrite(lohi(R[rL], R[rH]), val - 1); + }else{ + R[a] = val - 1; + } + Fl = (Fl & FLAGC) | FLAGN; + if(val == 1) + Fl |= FLAGZ; + if((val & 0xF) == 0) + Fl |= FLAGH; + return time; +} + +static int +alu(u8int op) +{ + u8int val4, val8, a, b; + short val16; + int time; + + a = op & 7; + b = (op & 0x38) >> 3; + if((op >> 6) == 3){ + val8 = fetch8(); + time = 8; + }else if(a == rHL){ + val8 = memread(lohi(R[rL], R[rH])); + time = 8; + }else{ + val8 = R[a]; + time = 4; + } + switch(b){ + case 0: + case 1: + val16 = (ushort)(R[rA]) + (ushort)(val8); + val4 = (R[rA] & 0xF) + (val8 & 0xF); + if(b == 1 && (Fl & FLAGC)){ + val16++; + val4++; + } + Fl = 0; + val8 = val16; + if(val16 >= 0x100) + Fl |= FLAGC; + if(val4 >= 0x10) + Fl |= FLAGH; + break; + case 2: + case 3: + case 7: + val16 = (ushort)R[rA]; + val16 -= (ushort)val8; + val4 = val8 & 0xF; + if(b == 3 && (Fl & FLAGC)){ + val16--; + val4++; + } + val8 = val16; + Fl = FLAGN; + if(val16 < 0) + Fl |= FLAGC; + if(val4 > (R[rA] & 0xF)) + Fl |= FLAGH; + break; + case 4: + val8 &= R[rA]; + Fl = FLAGH; + break; + case 5: + val8 ^= R[rA]; + Fl = 0; + break; + default: + Fl = 0; + val8 |= R[rA]; + } + if(val8 == 0) + Fl |= FLAGZ; + if(b != 7) + R[rA] = val8; + return time; +} + +static int +jr(u8int op) +{ + u8int a; + u16int addr; + short step; + + a = (op & 0x38) >> 3; + switch(a){ + case 0: + return 4; + case 1: + addr = fetch16(); + memwrite(addr, sp); + memwrite(addr + 1, sp >> 8); + return 8; + } + step = (short)(schar)fetch8(); + switch(a){ + case 2: + return 4; + case 4: + if(Fl & FLAGZ) + return 8; + break; + case 5: + if((Fl & FLAGZ) == 0) + return 8; + break; + case 6: + if(Fl & FLAGC) + return 8; + break; + case 7: + if((Fl & FLAGC) == 0) + return 8; + } + pc += step; + return 8; +} + +static int +jp(u8int op) +{ + u16int addr; + + addr = fetch16(); + if(op != 0xC3){ + switch((op & 0x38) >> 3){ + case 0: + if(Fl & FLAGZ) + return 12; + break; + case 1: + if((Fl & FLAGZ) == 0) + return 12; + break; + case 2: + if(Fl & FLAGC) + return 12; + break; + case 3: + if((Fl & FLAGC) == 0) + return 12; + break; + } + } + pc = addr; + return 12; +} + +static int +call(u8int op) +{ + u16int addr; + + addr = fetch16(); + if(op != 0xCD){ + switch((op & 0x38) >> 3){ + case 0: + if(Fl & FLAGZ) + return 12; + break; + case 1: + if((Fl & FLAGZ) == 0) + return 12; + break; + case 2: + if(Fl & FLAGC) + return 12; + break; + case 3: + if((Fl & FLAGC) == 0) + return 12; + break; + } + } + push16(pc); + pc = addr; + return 12; +} + +static int +rst(u8int op) +{ + u16int addr; + + addr = op & 0x38; + push16(pc); + pc = addr; + return 32; +} + +static int +ret(u8int op) +{ + if(op != 0xC9 && op!= 0xD9){ + switch((op & 0x38) >> 3){ + case 0: + if(Fl & FLAGZ) + return 8; + break; + case 1: + if((Fl & FLAGZ) == 0) + return 8; + break; + case 2: + if(Fl & FLAGC) + return 8; + break; + case 3: + if((Fl & FLAGC) == 0) + return 8; + break; + } + } + pc = pop16(); + if(op == 0xD9) + IME = 1; + return 8; +} + +static int +push(u8int op) +{ + u8int a; + + a = (op & 0x38) >> 4; + switch(a){ + case 0: + push8(R[rB]); + push8(R[rC]); + break; + case 1: + push8(R[rD]); + push8(R[rE]); + break; + case 2: + push8(R[rH]); + push8(R[rL]); + break; + default: + push8(R[rA]); + push8(Fl); + break; + } + return 16; +} + +static int +pop(u8int op) +{ + u8int a; + + a = (op & 0x38) >> 4; + switch(a){ + case 0: + R[rC] = pop8(); + R[rB] = pop8(); + break; + case 1: + R[rE] = pop8(); + R[rD] = pop8(); + break; + case 2: + R[rL] = pop8(); + R[rH] = pop8(); + break; + default: + Fl = pop8() & 0xF0; + R[rA] = pop8(); + } + return 12; +} + +static int +shift(u8int op, int cb) +{ + u16int val; + u8int a, b; + int time; + + a = (op & 0x38) >> 3; + b = op & 7; + if(b == rHL){ + val = memread(lohi(R[rL], R[rH])); + time = 16; + }else{ + val = R[b]; + time = 8; + } + switch(a){ + case 0: + Fl = 0; + if(val & 0x80) + Fl = FLAGC; + val = (val << 1) | (val >> 7); + break; + case 1: + Fl = 0; + if(val & 1) + Fl = FLAGC; + val = (val >> 1) | (val << 7); + break; + case 2: + val <<= 1; + if(Fl & FLAGC) + val |= 1; + Fl = 0; + if(val & 0x100) + Fl = FLAGC; + break; + case 3: + if(Fl & FLAGC) + val |= 0x100; + Fl = 0; + if(val & 1) + Fl = FLAGC; + val >>= 1; + break; + case 4: + Fl = 0; + if(val & 0x80) + Fl = FLAGC; + val <<= 1; + break; + case 5: + Fl = 0; + if(val & 1) + Fl = FLAGC; + val = (val >> 1) | (val & 0x80); + break; + case 6: + val = (val << 4) | (val >> 4); + Fl = 0; + break; + default: + Fl = 0; + if(val & 1) + Fl = FLAGC; + val >>= 1; + } + if((val & 0xFF) == 0) + Fl |= FLAGZ; + if(b == rHL) + memwrite(lohi(R[rL], R[rH]), val); + else + R[b] = val; + if(!cb) + Fl &= FLAGC; + return time; +} + +static int +bit(u8int op) +{ + u8int val, a, b; + int time; + + a = (op & 0x38) >> 3; + b = op & 7; + if(b == rHL){ + val = memread(lohi(R[rL], R[rH])), + time = 16; + }else{ + val = R[b]; + time = 8; + } + Fl = (Fl & FLAGC) | FLAGH; + if((val & (1<> 3; + b = op & 7; + if(b == rHL){ + val = memread(lohi(R[rL], R[rH])); + time = 16; + }else{ + val = R[b]; + time = 8; + } + if(op & 0x40) + val |= (1 << a); + else + val &= ~(1 << a); + if(b == rHL) + memwrite(lohi(R[rL], R[rH]), val); + else + R[b] = val; + return time; +} + +static int +cb(void) +{ + u8int op; + + op = fetch8(); + if((op & 0xC0) == 0) + return shift(op, 1); + if((op & 0xC0) == 0x40) + return bit(op); + return setres(op); +} + +void +interrupt(u8int t) +{ + mem[IF] |= (1 << t); +} + +int +step(void) +{ + u8int op; + ushort val; + extern u8int daa[]; + int val32, i; + + if(halt){ + if(mem[IF] & mem[IE]) + halt = 0; + else + return 4; + } + if(IME && (mem[IF] & mem[IE])) + for(i = 0; i < 5; i++) + if(mem[IF] & mem[IE] & (1< 0xFFFF || val32 < 0) + Fl |= FLAGC; + if(((sp & 0xFFF) + (val & 0xFFF)) > 0xFFF) + Fl |= FLAGH; + sp = val; + return 16; + case 0xE9: + pc = lohi(R[rL], R[rH]); + return 4; + case 0xEA: + memwrite(fetch16(), R[rA]); + return 16; + case 0xF0: + R[rA] = memread(lohi(fetch8(), 0xFF)); + return 12; + case 0xFA: + R[rA] = memread(fetch16()); + return 16; + case 0xF2: + R[rA] = memread(lohi(R[rC], 0xFF)); + return 8; + case 0xCB: + return cb(); + case 0xF3: + IME= 0; + return 4; + case 0xF8: + val32 = sp + (schar)fetch8(); + R[rL] = val32; + R[rH] = val32 >> 8; + Fl = 0; + if(val32 < 0 || val32 > 0xFFFF) + Fl = FLAGC; + return 12; + case 0xF9: + sp = lohi(R[rL], R[rH]); + return 8; + case 0xFB: + IME = 1; + return 4; + default: + invalid(); + } + return 0; +} diff --git a/sys/src/games/gb/daa.c b/sys/src/games/gb/daa.c new file mode 100644 index 000000000..13ef4b39c --- /dev/null +++ b/sys/src/games/gb/daa.c @@ -0,0 +1,465 @@ +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +u8int daa[] = { + 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x09, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x10, 0x00, 0x11, 0x00, + 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x20, 0x00, + 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, + 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, + 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, + 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, + 0x45, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x50, 0x00, + 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, + 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, + 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x70, 0x00, 0x71, 0x00, + 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, + 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, + 0x84, 0x00, 0x85, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, + 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, + 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0x98, 0x00, + 0x99, 0x00, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x00, 0x90, 0x01, 0x10, + 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x09, 0x10, 0x10, 0x10, + 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, + 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, 0x17, 0x10, 0x18, 0x10, 0x19, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, + 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, + 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, 0x29, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, + 0x35, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x36, 0x10, 0x37, 0x10, + 0x38, 0x10, 0x39, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x40, 0x10, + 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, 0x48, 0x10, 0x49, 0x10, + 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, + 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x56, 0x10, 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, 0x60, 0x10, 0x61, 0x10, + 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, + 0x65, 0x10, 0x66, 0x10, 0x67, 0x10, 0x68, 0x10, 0x69, 0x10, 0x70, 0x10, 0x71, 0x10, 0x72, 0x10, 0x73, 0x10, + 0x74, 0x10, 0x75, 0x10, 0x70, 0x10, 0x71, 0x10, 0x72, 0x10, 0x73, 0x10, 0x74, 0x10, 0x75, 0x10, 0x76, 0x10, + 0x77, 0x10, 0x78, 0x10, 0x79, 0x10, 0x80, 0x10, 0x81, 0x10, 0x82, 0x10, 0x83, 0x10, 0x84, 0x10, 0x85, 0x10, + 0x80, 0x10, 0x81, 0x10, 0x82, 0x10, 0x83, 0x10, 0x84, 0x10, 0x85, 0x10, 0x86, 0x10, 0x87, 0x10, 0x88, 0x10, + 0x89, 0x10, 0x90, 0x10, 0x91, 0x10, 0x92, 0x10, 0x93, 0x10, 0x94, 0x10, 0x95, 0x10, 0x90, 0x10, 0x91, 0x10, + 0x92, 0x10, 0x93, 0x10, 0x94, 0x10, 0x95, 0x10, 0x96, 0x10, 0x97, 0x10, 0x98, 0x10, 0x99, 0x10, 0xA0, 0x10, + 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, 0xA0, 0x10, 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, + 0xA4, 0x10, 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, 0xA9, 0x10, 0xB0, 0x10, 0xB1, 0x10, 0xB2, 0x10, + 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB0, 0x10, 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, + 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, 0xB9, 0x10, 0xC0, 0x10, 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, + 0xC5, 0x10, 0xC0, 0x10, 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xC6, 0x10, 0xC7, 0x10, + 0xC8, 0x10, 0xC9, 0x10, 0xD0, 0x10, 0xD1, 0x10, 0xD2, 0x10, 0xD3, 0x10, 0xD4, 0x10, 0xD5, 0x10, 0xD0, 0x10, + 0xD1, 0x10, 0xD2, 0x10, 0xD3, 0x10, 0xD4, 0x10, 0xD5, 0x10, 0xD6, 0x10, 0xD7, 0x10, 0xD8, 0x10, 0xD9, 0x10, + 0xE0, 0x10, 0xE1, 0x10, 0xE2, 0x10, 0xE3, 0x10, 0xE4, 0x10, 0xE5, 0x10, 0xE0, 0x10, 0xE1, 0x10, 0xE2, 0x10, + 0xE3, 0x10, 0xE4, 0x10, 0xE5, 0x10, 0xE6, 0x10, 0xE7, 0x10, 0xE8, 0x10, 0xE9, 0x10, 0xF0, 0x10, 0xF1, 0x10, + 0xF2, 0x10, 0xF3, 0x10, 0xF4, 0x10, 0xF5, 0x10, 0xF0, 0x10, 0xF1, 0x10, 0xF2, 0x10, 0xF3, 0x10, 0xF4, 0x10, + 0xF5, 0x10, 0xF6, 0x10, 0xF7, 0x10, 0xF8, 0x10, 0xF9, 0x10, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, + 0x04, 0x10, 0x05, 0x10, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x06, 0x10, + 0x07, 0x10, 0x08, 0x10, 0x09, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, + 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, 0x17, 0x10, 0x18, 0x10, + 0x19, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x20, 0x10, 0x21, 0x10, + 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, 0x29, 0x10, 0x30, 0x10, + 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, + 0x34, 0x10, 0x35, 0x10, 0x36, 0x10, 0x37, 0x10, 0x38, 0x10, 0x39, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, + 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, + 0x46, 0x10, 0x47, 0x10, 0x48, 0x10, 0x49, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, + 0x55, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x56, 0x10, 0x57, 0x10, + 0x58, 0x10, 0x59, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x06, 0x00, + 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x21, 0x00, + 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, + 0x2B, 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, + 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3C, 0x00, + 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, + 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, + 0x4F, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00, 0x60, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, + 0x6A, 0x00, 0x6B, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, + 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7B, 0x00, + 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, + 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0x8D, 0x00, + 0x8E, 0x00, 0x8F, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, + 0x97, 0x00, 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, + 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, + 0x09, 0x10, 0x0A, 0x10, 0x0B, 0x10, 0x0C, 0x10, 0x0D, 0x10, 0x0E, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x11, 0x10, + 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, 0x17, 0x10, 0x18, 0x10, 0x19, 0x10, 0x1A, 0x10, + 0x1B, 0x10, 0x1C, 0x10, 0x1D, 0x10, 0x1E, 0x10, 0x1F, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, + 0x24, 0x10, 0x25, 0x10, 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, 0x29, 0x10, 0x2A, 0x10, 0x2B, 0x10, 0x2C, 0x10, + 0x2D, 0x10, 0x2E, 0x10, 0x2F, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, + 0x36, 0x10, 0x37, 0x10, 0x38, 0x10, 0x39, 0x10, 0x3A, 0x10, 0x3B, 0x10, 0x3C, 0x10, 0x3D, 0x10, 0x3E, 0x10, + 0x3F, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, + 0x48, 0x10, 0x49, 0x10, 0x4A, 0x10, 0x4B, 0x10, 0x4C, 0x10, 0x4D, 0x10, 0x4E, 0x10, 0x4F, 0x10, 0x50, 0x10, + 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x56, 0x10, 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, + 0x5A, 0x10, 0x5B, 0x10, 0x5C, 0x10, 0x5D, 0x10, 0x5E, 0x10, 0x5F, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, + 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x66, 0x10, 0x67, 0x10, 0x68, 0x10, 0x69, 0x10, 0x6A, 0x10, 0x6B, 0x10, + 0x6C, 0x10, 0x6D, 0x10, 0x6E, 0x10, 0x6F, 0x10, 0x70, 0x10, 0x71, 0x10, 0x72, 0x10, 0x73, 0x10, 0x74, 0x10, + 0x75, 0x10, 0x76, 0x10, 0x77, 0x10, 0x78, 0x10, 0x79, 0x10, 0x7A, 0x10, 0x7B, 0x10, 0x7C, 0x10, 0x7D, 0x10, + 0x7E, 0x10, 0x7F, 0x10, 0x80, 0x10, 0x81, 0x10, 0x82, 0x10, 0x83, 0x10, 0x84, 0x10, 0x85, 0x10, 0x86, 0x10, + 0x87, 0x10, 0x88, 0x10, 0x89, 0x10, 0x8A, 0x10, 0x8B, 0x10, 0x8C, 0x10, 0x8D, 0x10, 0x8E, 0x10, 0x8F, 0x10, + 0x90, 0x10, 0x91, 0x10, 0x92, 0x10, 0x93, 0x10, 0x94, 0x10, 0x95, 0x10, 0x96, 0x10, 0x97, 0x10, 0x98, 0x10, + 0x99, 0x10, 0x9A, 0x10, 0x9B, 0x10, 0x9C, 0x10, 0x9D, 0x10, 0x9E, 0x10, 0x9F, 0x10, 0xA0, 0x10, 0xA1, 0x10, + 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, 0xA9, 0x10, 0xAA, 0x10, + 0xAB, 0x10, 0xAC, 0x10, 0xAD, 0x10, 0xAE, 0x10, 0xAF, 0x10, 0xB0, 0x10, 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, + 0xB4, 0x10, 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, 0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, + 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10, 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, + 0xC6, 0x10, 0xC7, 0x10, 0xC8, 0x10, 0xC9, 0x10, 0xCA, 0x10, 0xCB, 0x10, 0xCC, 0x10, 0xCD, 0x10, 0xCE, 0x10, + 0xCF, 0x10, 0xD0, 0x10, 0xD1, 0x10, 0xD2, 0x10, 0xD3, 0x10, 0xD4, 0x10, 0xD5, 0x10, 0xD6, 0x10, 0xD7, 0x10, + 0xD8, 0x10, 0xD9, 0x10, 0xDA, 0x10, 0xDB, 0x10, 0xDC, 0x10, 0xDD, 0x10, 0xDE, 0x10, 0xDF, 0x10, 0xE0, 0x10, + 0xE1, 0x10, 0xE2, 0x10, 0xE3, 0x10, 0xE4, 0x10, 0xE5, 0x10, 0xE6, 0x10, 0xE7, 0x10, 0xE8, 0x10, 0xE9, 0x10, + 0xEA, 0x10, 0xEB, 0x10, 0xEC, 0x10, 0xED, 0x10, 0xEE, 0x10, 0xEF, 0x10, 0xF0, 0x10, 0xF1, 0x10, 0xF2, 0x10, + 0xF3, 0x10, 0xF4, 0x10, 0xF5, 0x10, 0xF6, 0x10, 0xF7, 0x10, 0xF8, 0x10, 0xF9, 0x10, 0xFA, 0x10, 0xFB, 0x10, + 0xFC, 0x10, 0xFD, 0x10, 0xFE, 0x10, 0xFF, 0x10, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, + 0x05, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x09, 0x10, 0x0A, 0x10, 0x0B, 0x10, 0x0C, 0x10, 0x0D, 0x10, + 0x0E, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, + 0x17, 0x10, 0x18, 0x10, 0x19, 0x10, 0x1A, 0x10, 0x1B, 0x10, 0x1C, 0x10, 0x1D, 0x10, 0x1E, 0x10, 0x1F, 0x10, + 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, + 0x29, 0x10, 0x2A, 0x10, 0x2B, 0x10, 0x2C, 0x10, 0x2D, 0x10, 0x2E, 0x10, 0x2F, 0x10, 0x30, 0x10, 0x31, 0x10, + 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x36, 0x10, 0x37, 0x10, 0x38, 0x10, 0x39, 0x10, 0x3A, 0x10, + 0x3B, 0x10, 0x3C, 0x10, 0x3D, 0x10, 0x3E, 0x10, 0x3F, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, + 0x44, 0x10, 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, 0x48, 0x10, 0x49, 0x10, 0x4A, 0x10, 0x4B, 0x10, 0x4C, 0x10, + 0x4D, 0x10, 0x4E, 0x10, 0x4F, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, + 0x56, 0x10, 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, 0x5A, 0x10, 0x5B, 0x10, 0x5C, 0x10, 0x5D, 0x10, 0x5E, 0x10, + 0x5F, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x00, 0xC0, 0x01, 0x40, + 0x02, 0x40, 0x03, 0x40, 0x04, 0x40, 0x05, 0x40, 0x06, 0x40, 0x07, 0x40, 0x08, 0x40, 0x09, 0x40, 0x0A, 0x40, + 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x40, 0x0E, 0x40, 0x0F, 0x40, 0x10, 0x40, 0x11, 0x40, 0x12, 0x40, 0x13, 0x40, + 0x14, 0x40, 0x15, 0x40, 0x16, 0x40, 0x17, 0x40, 0x18, 0x40, 0x19, 0x40, 0x1A, 0x40, 0x1B, 0x40, 0x1C, 0x40, + 0x1D, 0x40, 0x1E, 0x40, 0x1F, 0x40, 0x20, 0x40, 0x21, 0x40, 0x22, 0x40, 0x23, 0x40, 0x24, 0x40, 0x25, 0x40, + 0x26, 0x40, 0x27, 0x40, 0x28, 0x40, 0x29, 0x40, 0x2A, 0x40, 0x2B, 0x40, 0x2C, 0x40, 0x2D, 0x40, 0x2E, 0x40, + 0x2F, 0x40, 0x30, 0x40, 0x31, 0x40, 0x32, 0x40, 0x33, 0x40, 0x34, 0x40, 0x35, 0x40, 0x36, 0x40, 0x37, 0x40, + 0x38, 0x40, 0x39, 0x40, 0x3A, 0x40, 0x3B, 0x40, 0x3C, 0x40, 0x3D, 0x40, 0x3E, 0x40, 0x3F, 0x40, 0x40, 0x40, + 0x41, 0x40, 0x42, 0x40, 0x43, 0x40, 0x44, 0x40, 0x45, 0x40, 0x46, 0x40, 0x47, 0x40, 0x48, 0x40, 0x49, 0x40, + 0x4A, 0x40, 0x4B, 0x40, 0x4C, 0x40, 0x4D, 0x40, 0x4E, 0x40, 0x4F, 0x40, 0x50, 0x40, 0x51, 0x40, 0x52, 0x40, + 0x53, 0x40, 0x54, 0x40, 0x55, 0x40, 0x56, 0x40, 0x57, 0x40, 0x58, 0x40, 0x59, 0x40, 0x5A, 0x40, 0x5B, 0x40, + 0x5C, 0x40, 0x5D, 0x40, 0x5E, 0x40, 0x5F, 0x40, 0x60, 0x40, 0x61, 0x40, 0x62, 0x40, 0x63, 0x40, 0x64, 0x40, + 0x65, 0x40, 0x66, 0x40, 0x67, 0x40, 0x68, 0x40, 0x69, 0x40, 0x6A, 0x40, 0x6B, 0x40, 0x6C, 0x40, 0x6D, 0x40, + 0x6E, 0x40, 0x6F, 0x40, 0x70, 0x40, 0x71, 0x40, 0x72, 0x40, 0x73, 0x40, 0x74, 0x40, 0x75, 0x40, 0x76, 0x40, + 0x77, 0x40, 0x78, 0x40, 0x79, 0x40, 0x7A, 0x40, 0x7B, 0x40, 0x7C, 0x40, 0x7D, 0x40, 0x7E, 0x40, 0x7F, 0x40, + 0x80, 0x40, 0x81, 0x40, 0x82, 0x40, 0x83, 0x40, 0x84, 0x40, 0x85, 0x40, 0x86, 0x40, 0x87, 0x40, 0x88, 0x40, + 0x89, 0x40, 0x8A, 0x40, 0x8B, 0x40, 0x8C, 0x40, 0x8D, 0x40, 0x8E, 0x40, 0x8F, 0x40, 0x90, 0x40, 0x91, 0x40, + 0x92, 0x40, 0x93, 0x40, 0x94, 0x40, 0x95, 0x40, 0x96, 0x40, 0x97, 0x40, 0x98, 0x40, 0x99, 0x40, 0x9A, 0x40, + 0x9B, 0x40, 0x9C, 0x40, 0x9D, 0x40, 0x9E, 0x40, 0x9F, 0x40, 0xA0, 0x40, 0xA1, 0x40, 0xA2, 0x40, 0xA3, 0x40, + 0xA4, 0x40, 0xA5, 0x40, 0xA6, 0x40, 0xA7, 0x40, 0xA8, 0x40, 0xA9, 0x40, 0xAA, 0x40, 0xAB, 0x40, 0xAC, 0x40, + 0xAD, 0x40, 0xAE, 0x40, 0xAF, 0x40, 0xB0, 0x40, 0xB1, 0x40, 0xB2, 0x40, 0xB3, 0x40, 0xB4, 0x40, 0xB5, 0x40, + 0xB6, 0x40, 0xB7, 0x40, 0xB8, 0x40, 0xB9, 0x40, 0xBA, 0x40, 0xBB, 0x40, 0xBC, 0x40, 0xBD, 0x40, 0xBE, 0x40, + 0xBF, 0x40, 0xC0, 0x40, 0xC1, 0x40, 0xC2, 0x40, 0xC3, 0x40, 0xC4, 0x40, 0xC5, 0x40, 0xC6, 0x40, 0xC7, 0x40, + 0xC8, 0x40, 0xC9, 0x40, 0xCA, 0x40, 0xCB, 0x40, 0xCC, 0x40, 0xCD, 0x40, 0xCE, 0x40, 0xCF, 0x40, 0xD0, 0x40, + 0xD1, 0x40, 0xD2, 0x40, 0xD3, 0x40, 0xD4, 0x40, 0xD5, 0x40, 0xD6, 0x40, 0xD7, 0x40, 0xD8, 0x40, 0xD9, 0x40, + 0xDA, 0x40, 0xDB, 0x40, 0xDC, 0x40, 0xDD, 0x40, 0xDE, 0x40, 0xDF, 0x40, 0xE0, 0x40, 0xE1, 0x40, 0xE2, 0x40, + 0xE3, 0x40, 0xE4, 0x40, 0xE5, 0x40, 0xE6, 0x40, 0xE7, 0x40, 0xE8, 0x40, 0xE9, 0x40, 0xEA, 0x40, 0xEB, 0x40, + 0xEC, 0x40, 0xED, 0x40, 0xEE, 0x40, 0xEF, 0x40, 0xF0, 0x40, 0xF1, 0x40, 0xF2, 0x40, 0xF3, 0x40, 0xF4, 0x40, + 0xF5, 0x40, 0xF6, 0x40, 0xF7, 0x40, 0xF8, 0x40, 0xF9, 0x40, 0xFA, 0x40, 0xFB, 0x40, 0xFC, 0x40, 0xFD, 0x40, + 0xFE, 0x40, 0xFF, 0x40, 0xA0, 0x50, 0xA1, 0x50, 0xA2, 0x50, 0xA3, 0x50, 0xA4, 0x50, 0xA5, 0x50, 0xA6, 0x50, + 0xA7, 0x50, 0xA8, 0x50, 0xA9, 0x50, 0xAA, 0x50, 0xAB, 0x50, 0xAC, 0x50, 0xAD, 0x50, 0xAE, 0x50, 0xAF, 0x50, + 0xB0, 0x50, 0xB1, 0x50, 0xB2, 0x50, 0xB3, 0x50, 0xB4, 0x50, 0xB5, 0x50, 0xB6, 0x50, 0xB7, 0x50, 0xB8, 0x50, + 0xB9, 0x50, 0xBA, 0x50, 0xBB, 0x50, 0xBC, 0x50, 0xBD, 0x50, 0xBE, 0x50, 0xBF, 0x50, 0xC0, 0x50, 0xC1, 0x50, + 0xC2, 0x50, 0xC3, 0x50, 0xC4, 0x50, 0xC5, 0x50, 0xC6, 0x50, 0xC7, 0x50, 0xC8, 0x50, 0xC9, 0x50, 0xCA, 0x50, + 0xCB, 0x50, 0xCC, 0x50, 0xCD, 0x50, 0xCE, 0x50, 0xCF, 0x50, 0xD0, 0x50, 0xD1, 0x50, 0xD2, 0x50, 0xD3, 0x50, + 0xD4, 0x50, 0xD5, 0x50, 0xD6, 0x50, 0xD7, 0x50, 0xD8, 0x50, 0xD9, 0x50, 0xDA, 0x50, 0xDB, 0x50, 0xDC, 0x50, + 0xDD, 0x50, 0xDE, 0x50, 0xDF, 0x50, 0xE0, 0x50, 0xE1, 0x50, 0xE2, 0x50, 0xE3, 0x50, 0xE4, 0x50, 0xE5, 0x50, + 0xE6, 0x50, 0xE7, 0x50, 0xE8, 0x50, 0xE9, 0x50, 0xEA, 0x50, 0xEB, 0x50, 0xEC, 0x50, 0xED, 0x50, 0xEE, 0x50, + 0xEF, 0x50, 0xF0, 0x50, 0xF1, 0x50, 0xF2, 0x50, 0xF3, 0x50, 0xF4, 0x50, 0xF5, 0x50, 0xF6, 0x50, 0xF7, 0x50, + 0xF8, 0x50, 0xF9, 0x50, 0xFA, 0x50, 0xFB, 0x50, 0xFC, 0x50, 0xFD, 0x50, 0xFE, 0x50, 0xFF, 0x50, 0x00, 0xD0, + 0x01, 0x50, 0x02, 0x50, 0x03, 0x50, 0x04, 0x50, 0x05, 0x50, 0x06, 0x50, 0x07, 0x50, 0x08, 0x50, 0x09, 0x50, + 0x0A, 0x50, 0x0B, 0x50, 0x0C, 0x50, 0x0D, 0x50, 0x0E, 0x50, 0x0F, 0x50, 0x10, 0x50, 0x11, 0x50, 0x12, 0x50, + 0x13, 0x50, 0x14, 0x50, 0x15, 0x50, 0x16, 0x50, 0x17, 0x50, 0x18, 0x50, 0x19, 0x50, 0x1A, 0x50, 0x1B, 0x50, + 0x1C, 0x50, 0x1D, 0x50, 0x1E, 0x50, 0x1F, 0x50, 0x20, 0x50, 0x21, 0x50, 0x22, 0x50, 0x23, 0x50, 0x24, 0x50, + 0x25, 0x50, 0x26, 0x50, 0x27, 0x50, 0x28, 0x50, 0x29, 0x50, 0x2A, 0x50, 0x2B, 0x50, 0x2C, 0x50, 0x2D, 0x50, + 0x2E, 0x50, 0x2F, 0x50, 0x30, 0x50, 0x31, 0x50, 0x32, 0x50, 0x33, 0x50, 0x34, 0x50, 0x35, 0x50, 0x36, 0x50, + 0x37, 0x50, 0x38, 0x50, 0x39, 0x50, 0x3A, 0x50, 0x3B, 0x50, 0x3C, 0x50, 0x3D, 0x50, 0x3E, 0x50, 0x3F, 0x50, + 0x40, 0x50, 0x41, 0x50, 0x42, 0x50, 0x43, 0x50, 0x44, 0x50, 0x45, 0x50, 0x46, 0x50, 0x47, 0x50, 0x48, 0x50, + 0x49, 0x50, 0x4A, 0x50, 0x4B, 0x50, 0x4C, 0x50, 0x4D, 0x50, 0x4E, 0x50, 0x4F, 0x50, 0x50, 0x50, 0x51, 0x50, + 0x52, 0x50, 0x53, 0x50, 0x54, 0x50, 0x55, 0x50, 0x56, 0x50, 0x57, 0x50, 0x58, 0x50, 0x59, 0x50, 0x5A, 0x50, + 0x5B, 0x50, 0x5C, 0x50, 0x5D, 0x50, 0x5E, 0x50, 0x5F, 0x50, 0x60, 0x50, 0x61, 0x50, 0x62, 0x50, 0x63, 0x50, + 0x64, 0x50, 0x65, 0x50, 0x66, 0x50, 0x67, 0x50, 0x68, 0x50, 0x69, 0x50, 0x6A, 0x50, 0x6B, 0x50, 0x6C, 0x50, + 0x6D, 0x50, 0x6E, 0x50, 0x6F, 0x50, 0x70, 0x50, 0x71, 0x50, 0x72, 0x50, 0x73, 0x50, 0x74, 0x50, 0x75, 0x50, + 0x76, 0x50, 0x77, 0x50, 0x78, 0x50, 0x79, 0x50, 0x7A, 0x50, 0x7B, 0x50, 0x7C, 0x50, 0x7D, 0x50, 0x7E, 0x50, + 0x7F, 0x50, 0x80, 0x50, 0x81, 0x50, 0x82, 0x50, 0x83, 0x50, 0x84, 0x50, 0x85, 0x50, 0x86, 0x50, 0x87, 0x50, + 0x88, 0x50, 0x89, 0x50, 0x8A, 0x50, 0x8B, 0x50, 0x8C, 0x50, 0x8D, 0x50, 0x8E, 0x50, 0x8F, 0x50, 0x90, 0x50, + 0x91, 0x50, 0x92, 0x50, 0x93, 0x50, 0x94, 0x50, 0x95, 0x50, 0x96, 0x50, 0x97, 0x50, 0x98, 0x50, 0x99, 0x50, + 0x9A, 0x50, 0x9B, 0x50, 0x9C, 0x50, 0x9D, 0x50, 0x9E, 0x50, 0x9F, 0x50, 0xFA, 0x40, 0xFB, 0x40, 0xFC, 0x40, + 0xFD, 0x40, 0xFE, 0x40, 0xFF, 0x40, 0x00, 0xC0, 0x01, 0x40, 0x02, 0x40, 0x03, 0x40, 0x04, 0x40, 0x05, 0x40, + 0x06, 0x40, 0x07, 0x40, 0x08, 0x40, 0x09, 0x40, 0x0A, 0x40, 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x40, 0x0E, 0x40, + 0x0F, 0x40, 0x10, 0x40, 0x11, 0x40, 0x12, 0x40, 0x13, 0x40, 0x14, 0x40, 0x15, 0x40, 0x16, 0x40, 0x17, 0x40, + 0x18, 0x40, 0x19, 0x40, 0x1A, 0x40, 0x1B, 0x40, 0x1C, 0x40, 0x1D, 0x40, 0x1E, 0x40, 0x1F, 0x40, 0x20, 0x40, + 0x21, 0x40, 0x22, 0x40, 0x23, 0x40, 0x24, 0x40, 0x25, 0x40, 0x26, 0x40, 0x27, 0x40, 0x28, 0x40, 0x29, 0x40, + 0x2A, 0x40, 0x2B, 0x40, 0x2C, 0x40, 0x2D, 0x40, 0x2E, 0x40, 0x2F, 0x40, 0x30, 0x40, 0x31, 0x40, 0x32, 0x40, + 0x33, 0x40, 0x34, 0x40, 0x35, 0x40, 0x36, 0x40, 0x37, 0x40, 0x38, 0x40, 0x39, 0x40, 0x3A, 0x40, 0x3B, 0x40, + 0x3C, 0x40, 0x3D, 0x40, 0x3E, 0x40, 0x3F, 0x40, 0x40, 0x40, 0x41, 0x40, 0x42, 0x40, 0x43, 0x40, 0x44, 0x40, + 0x45, 0x40, 0x46, 0x40, 0x47, 0x40, 0x48, 0x40, 0x49, 0x40, 0x4A, 0x40, 0x4B, 0x40, 0x4C, 0x40, 0x4D, 0x40, + 0x4E, 0x40, 0x4F, 0x40, 0x50, 0x40, 0x51, 0x40, 0x52, 0x40, 0x53, 0x40, 0x54, 0x40, 0x55, 0x40, 0x56, 0x40, + 0x57, 0x40, 0x58, 0x40, 0x59, 0x40, 0x5A, 0x40, 0x5B, 0x40, 0x5C, 0x40, 0x5D, 0x40, 0x5E, 0x40, 0x5F, 0x40, + 0x60, 0x40, 0x61, 0x40, 0x62, 0x40, 0x63, 0x40, 0x64, 0x40, 0x65, 0x40, 0x66, 0x40, 0x67, 0x40, 0x68, 0x40, + 0x69, 0x40, 0x6A, 0x40, 0x6B, 0x40, 0x6C, 0x40, 0x6D, 0x40, 0x6E, 0x40, 0x6F, 0x40, 0x70, 0x40, 0x71, 0x40, + 0x72, 0x40, 0x73, 0x40, 0x74, 0x40, 0x75, 0x40, 0x76, 0x40, 0x77, 0x40, 0x78, 0x40, 0x79, 0x40, 0x7A, 0x40, + 0x7B, 0x40, 0x7C, 0x40, 0x7D, 0x40, 0x7E, 0x40, 0x7F, 0x40, 0x80, 0x40, 0x81, 0x40, 0x82, 0x40, 0x83, 0x40, + 0x84, 0x40, 0x85, 0x40, 0x86, 0x40, 0x87, 0x40, 0x88, 0x40, 0x89, 0x40, 0x8A, 0x40, 0x8B, 0x40, 0x8C, 0x40, + 0x8D, 0x40, 0x8E, 0x40, 0x8F, 0x40, 0x90, 0x40, 0x91, 0x40, 0x92, 0x40, 0x93, 0x40, 0x94, 0x40, 0x95, 0x40, + 0x96, 0x40, 0x97, 0x40, 0x98, 0x40, 0x99, 0x40, 0x9A, 0x40, 0x9B, 0x40, 0x9C, 0x40, 0x9D, 0x40, 0x9E, 0x40, + 0x9F, 0x40, 0xA0, 0x40, 0xA1, 0x40, 0xA2, 0x40, 0xA3, 0x40, 0xA4, 0x40, 0xA5, 0x40, 0xA6, 0x40, 0xA7, 0x40, + 0xA8, 0x40, 0xA9, 0x40, 0xAA, 0x40, 0xAB, 0x40, 0xAC, 0x40, 0xAD, 0x40, 0xAE, 0x40, 0xAF, 0x40, 0xB0, 0x40, + 0xB1, 0x40, 0xB2, 0x40, 0xB3, 0x40, 0xB4, 0x40, 0xB5, 0x40, 0xB6, 0x40, 0xB7, 0x40, 0xB8, 0x40, 0xB9, 0x40, + 0xBA, 0x40, 0xBB, 0x40, 0xBC, 0x40, 0xBD, 0x40, 0xBE, 0x40, 0xBF, 0x40, 0xC0, 0x40, 0xC1, 0x40, 0xC2, 0x40, + 0xC3, 0x40, 0xC4, 0x40, 0xC5, 0x40, 0xC6, 0x40, 0xC7, 0x40, 0xC8, 0x40, 0xC9, 0x40, 0xCA, 0x40, 0xCB, 0x40, + 0xCC, 0x40, 0xCD, 0x40, 0xCE, 0x40, 0xCF, 0x40, 0xD0, 0x40, 0xD1, 0x40, 0xD2, 0x40, 0xD3, 0x40, 0xD4, 0x40, + 0xD5, 0x40, 0xD6, 0x40, 0xD7, 0x40, 0xD8, 0x40, 0xD9, 0x40, 0xDA, 0x40, 0xDB, 0x40, 0xDC, 0x40, 0xDD, 0x40, + 0xDE, 0x40, 0xDF, 0x40, 0xE0, 0x40, 0xE1, 0x40, 0xE2, 0x40, 0xE3, 0x40, 0xE4, 0x40, 0xE5, 0x40, 0xE6, 0x40, + 0xE7, 0x40, 0xE8, 0x40, 0xE9, 0x40, 0xEA, 0x40, 0xEB, 0x40, 0xEC, 0x40, 0xED, 0x40, 0xEE, 0x40, 0xEF, 0x40, + 0xF0, 0x40, 0xF1, 0x40, 0xF2, 0x40, 0xF3, 0x40, 0xF4, 0x40, 0xF5, 0x40, 0xF6, 0x40, 0xF7, 0x40, 0xF8, 0x40, + 0xF9, 0x40, 0x9A, 0x50, 0x9B, 0x50, 0x9C, 0x50, 0x9D, 0x50, 0x9E, 0x50, 0x9F, 0x50, 0xA0, 0x50, 0xA1, 0x50, + 0xA2, 0x50, 0xA3, 0x50, 0xA4, 0x50, 0xA5, 0x50, 0xA6, 0x50, 0xA7, 0x50, 0xA8, 0x50, 0xA9, 0x50, 0xAA, 0x50, + 0xAB, 0x50, 0xAC, 0x50, 0xAD, 0x50, 0xAE, 0x50, 0xAF, 0x50, 0xB0, 0x50, 0xB1, 0x50, 0xB2, 0x50, 0xB3, 0x50, + 0xB4, 0x50, 0xB5, 0x50, 0xB6, 0x50, 0xB7, 0x50, 0xB8, 0x50, 0xB9, 0x50, 0xBA, 0x50, 0xBB, 0x50, 0xBC, 0x50, + 0xBD, 0x50, 0xBE, 0x50, 0xBF, 0x50, 0xC0, 0x50, 0xC1, 0x50, 0xC2, 0x50, 0xC3, 0x50, 0xC4, 0x50, 0xC5, 0x50, + 0xC6, 0x50, 0xC7, 0x50, 0xC8, 0x50, 0xC9, 0x50, 0xCA, 0x50, 0xCB, 0x50, 0xCC, 0x50, 0xCD, 0x50, 0xCE, 0x50, + 0xCF, 0x50, 0xD0, 0x50, 0xD1, 0x50, 0xD2, 0x50, 0xD3, 0x50, 0xD4, 0x50, 0xD5, 0x50, 0xD6, 0x50, 0xD7, 0x50, + 0xD8, 0x50, 0xD9, 0x50, 0xDA, 0x50, 0xDB, 0x50, 0xDC, 0x50, 0xDD, 0x50, 0xDE, 0x50, 0xDF, 0x50, 0xE0, 0x50, + 0xE1, 0x50, 0xE2, 0x50, 0xE3, 0x50, 0xE4, 0x50, 0xE5, 0x50, 0xE6, 0x50, 0xE7, 0x50, 0xE8, 0x50, 0xE9, 0x50, + 0xEA, 0x50, 0xEB, 0x50, 0xEC, 0x50, 0xED, 0x50, 0xEE, 0x50, 0xEF, 0x50, 0xF0, 0x50, 0xF1, 0x50, 0xF2, 0x50, + 0xF3, 0x50, 0xF4, 0x50, 0xF5, 0x50, 0xF6, 0x50, 0xF7, 0x50, 0xF8, 0x50, 0xF9, 0x50, 0xFA, 0x50, 0xFB, 0x50, + 0xFC, 0x50, 0xFD, 0x50, 0xFE, 0x50, 0xFF, 0x50, 0x00, 0xD0, 0x01, 0x50, 0x02, 0x50, 0x03, 0x50, 0x04, 0x50, + 0x05, 0x50, 0x06, 0x50, 0x07, 0x50, 0x08, 0x50, 0x09, 0x50, 0x0A, 0x50, 0x0B, 0x50, 0x0C, 0x50, 0x0D, 0x50, + 0x0E, 0x50, 0x0F, 0x50, 0x10, 0x50, 0x11, 0x50, 0x12, 0x50, 0x13, 0x50, 0x14, 0x50, 0x15, 0x50, 0x16, 0x50, + 0x17, 0x50, 0x18, 0x50, 0x19, 0x50, 0x1A, 0x50, 0x1B, 0x50, 0x1C, 0x50, 0x1D, 0x50, 0x1E, 0x50, 0x1F, 0x50, + 0x20, 0x50, 0x21, 0x50, 0x22, 0x50, 0x23, 0x50, 0x24, 0x50, 0x25, 0x50, 0x26, 0x50, 0x27, 0x50, 0x28, 0x50, + 0x29, 0x50, 0x2A, 0x50, 0x2B, 0x50, 0x2C, 0x50, 0x2D, 0x50, 0x2E, 0x50, 0x2F, 0x50, 0x30, 0x50, 0x31, 0x50, + 0x32, 0x50, 0x33, 0x50, 0x34, 0x50, 0x35, 0x50, 0x36, 0x50, 0x37, 0x50, 0x38, 0x50, 0x39, 0x50, 0x3A, 0x50, + 0x3B, 0x50, 0x3C, 0x50, 0x3D, 0x50, 0x3E, 0x50, 0x3F, 0x50, 0x40, 0x50, 0x41, 0x50, 0x42, 0x50, 0x43, 0x50, + 0x44, 0x50, 0x45, 0x50, 0x46, 0x50, 0x47, 0x50, 0x48, 0x50, 0x49, 0x50, 0x4A, 0x50, 0x4B, 0x50, 0x4C, 0x50, + 0x4D, 0x50, 0x4E, 0x50, 0x4F, 0x50, 0x50, 0x50, 0x51, 0x50, 0x52, 0x50, 0x53, 0x50, 0x54, 0x50, 0x55, 0x50, + 0x56, 0x50, 0x57, 0x50, 0x58, 0x50, 0x59, 0x50, 0x5A, 0x50, 0x5B, 0x50, 0x5C, 0x50, 0x5D, 0x50, 0x5E, 0x50, + 0x5F, 0x50, 0x60, 0x50, 0x61, 0x50, 0x62, 0x50, 0x63, 0x50, 0x64, 0x50, 0x65, 0x50, 0x66, 0x50, 0x67, 0x50, + 0x68, 0x50, 0x69, 0x50, 0x6A, 0x50, 0x6B, 0x50, 0x6C, 0x50, 0x6D, 0x50, 0x6E, 0x50, 0x6F, 0x50, 0x70, 0x50, + 0x71, 0x50, 0x72, 0x50, 0x73, 0x50, 0x74, 0x50, 0x75, 0x50, 0x76, 0x50, 0x77, 0x50, 0x78, 0x50, 0x79, 0x50, + 0x7A, 0x50, 0x7B, 0x50, 0x7C, 0x50, 0x7D, 0x50, 0x7E, 0x50, 0x7F, 0x50, 0x80, 0x50, 0x81, 0x50, 0x82, 0x50, + 0x83, 0x50, 0x84, 0x50, 0x85, 0x50, 0x86, 0x50, 0x87, 0x50, 0x88, 0x50, 0x89, 0x50, 0x8A, 0x50, 0x8B, 0x50, + 0x8C, 0x50, 0x8D, 0x50, 0x8E, 0x50, 0x8F, 0x50, 0x90, 0x50, 0x91, 0x50, 0x92, 0x50, 0x93, 0x50, 0x94, 0x50, + 0x95, 0x50, 0x96, 0x50, 0x97, 0x50, 0x98, 0x50, 0x99, 0x50, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, + 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, + 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, + 0x25, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, + 0x28, 0x00, 0x29, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x30, 0x00, + 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, + 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x50, 0x00, 0x51, 0x00, + 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, + 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, + 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, + 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, + 0x79, 0x00, 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x80, 0x00, 0x81, 0x00, + 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x90, 0x00, + 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, + 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0x98, 0x00, 0x99, 0x00, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, + 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, + 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x09, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, + 0x15, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, 0x17, 0x10, + 0x18, 0x10, 0x19, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x20, 0x10, + 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, 0x29, 0x10, + 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, + 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x36, 0x10, 0x37, 0x10, 0x38, 0x10, 0x39, 0x10, 0x40, 0x10, 0x41, 0x10, + 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, + 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, 0x48, 0x10, 0x49, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, + 0x54, 0x10, 0x55, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x56, 0x10, + 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, + 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x66, 0x10, 0x67, 0x10, 0x68, 0x10, + 0x69, 0x10, 0x70, 0x10, 0x71, 0x10, 0x72, 0x10, 0x73, 0x10, 0x74, 0x10, 0x75, 0x10, 0x70, 0x10, 0x71, 0x10, + 0x72, 0x10, 0x73, 0x10, 0x74, 0x10, 0x75, 0x10, 0x76, 0x10, 0x77, 0x10, 0x78, 0x10, 0x79, 0x10, 0x80, 0x10, + 0x81, 0x10, 0x82, 0x10, 0x83, 0x10, 0x84, 0x10, 0x85, 0x10, 0x80, 0x10, 0x81, 0x10, 0x82, 0x10, 0x83, 0x10, + 0x84, 0x10, 0x85, 0x10, 0x86, 0x10, 0x87, 0x10, 0x88, 0x10, 0x89, 0x10, 0x90, 0x10, 0x91, 0x10, 0x92, 0x10, + 0x93, 0x10, 0x94, 0x10, 0x95, 0x10, 0x90, 0x10, 0x91, 0x10, 0x92, 0x10, 0x93, 0x10, 0x94, 0x10, 0x95, 0x10, + 0x96, 0x10, 0x97, 0x10, 0x98, 0x10, 0x99, 0x10, 0xA0, 0x10, 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, + 0xA5, 0x10, 0xA0, 0x10, 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, + 0xA8, 0x10, 0xA9, 0x10, 0xB0, 0x10, 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB0, 0x10, + 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, 0xB9, 0x10, + 0xC0, 0x10, 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xC0, 0x10, 0xC1, 0x10, 0xC2, 0x10, + 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xC6, 0x10, 0xC7, 0x10, 0xC8, 0x10, 0xC9, 0x10, 0xD0, 0x10, 0xD1, 0x10, + 0xD2, 0x10, 0xD3, 0x10, 0xD4, 0x10, 0xD5, 0x10, 0xD0, 0x10, 0xD1, 0x10, 0xD2, 0x10, 0xD3, 0x10, 0xD4, 0x10, + 0xD5, 0x10, 0xD6, 0x10, 0xD7, 0x10, 0xD8, 0x10, 0xD9, 0x10, 0xE0, 0x10, 0xE1, 0x10, 0xE2, 0x10, 0xE3, 0x10, + 0xE4, 0x10, 0xE5, 0x10, 0xE0, 0x10, 0xE1, 0x10, 0xE2, 0x10, 0xE3, 0x10, 0xE4, 0x10, 0xE5, 0x10, 0xE6, 0x10, + 0xE7, 0x10, 0xE8, 0x10, 0xE9, 0x10, 0xF0, 0x10, 0xF1, 0x10, 0xF2, 0x10, 0xF3, 0x10, 0xF4, 0x10, 0xF5, 0x10, + 0xF0, 0x10, 0xF1, 0x10, 0xF2, 0x10, 0xF3, 0x10, 0xF4, 0x10, 0xF5, 0x10, 0xF6, 0x10, 0xF7, 0x10, 0xF8, 0x10, + 0xF9, 0x10, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x00, 0x90, 0x01, 0x10, + 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x09, 0x10, 0x10, 0x10, + 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, + 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, 0x17, 0x10, 0x18, 0x10, 0x19, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, + 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, + 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, 0x29, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, + 0x35, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x36, 0x10, 0x37, 0x10, + 0x38, 0x10, 0x39, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x40, 0x10, + 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, 0x48, 0x10, 0x49, 0x10, + 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, + 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x56, 0x10, 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, 0x60, 0x10, 0x61, 0x10, + 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, + 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, + 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, + 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, + 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, + 0x2F, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, + 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 0x40, 0x00, + 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, + 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, + 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, + 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, + 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, 0x00, 0x6C, 0x00, 0x6D, 0x00, + 0x6E, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, + 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, + 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, 0x90, 0x00, 0x91, 0x00, + 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, + 0x9B, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, + 0x04, 0x10, 0x05, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x09, 0x10, 0x0A, 0x10, 0x0B, 0x10, 0x0C, 0x10, + 0x0D, 0x10, 0x0E, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x11, 0x10, 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, + 0x16, 0x10, 0x17, 0x10, 0x18, 0x10, 0x19, 0x10, 0x1A, 0x10, 0x1B, 0x10, 0x1C, 0x10, 0x1D, 0x10, 0x1E, 0x10, + 0x1F, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, 0x24, 0x10, 0x25, 0x10, 0x26, 0x10, 0x27, 0x10, + 0x28, 0x10, 0x29, 0x10, 0x2A, 0x10, 0x2B, 0x10, 0x2C, 0x10, 0x2D, 0x10, 0x2E, 0x10, 0x2F, 0x10, 0x30, 0x10, + 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, 0x36, 0x10, 0x37, 0x10, 0x38, 0x10, 0x39, 0x10, + 0x3A, 0x10, 0x3B, 0x10, 0x3C, 0x10, 0x3D, 0x10, 0x3E, 0x10, 0x3F, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, + 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, 0x48, 0x10, 0x49, 0x10, 0x4A, 0x10, 0x4B, 0x10, + 0x4C, 0x10, 0x4D, 0x10, 0x4E, 0x10, 0x4F, 0x10, 0x50, 0x10, 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, + 0x55, 0x10, 0x56, 0x10, 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, 0x5A, 0x10, 0x5B, 0x10, 0x5C, 0x10, 0x5D, 0x10, + 0x5E, 0x10, 0x5F, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x66, 0x10, + 0x67, 0x10, 0x68, 0x10, 0x69, 0x10, 0x6A, 0x10, 0x6B, 0x10, 0x6C, 0x10, 0x6D, 0x10, 0x6E, 0x10, 0x6F, 0x10, + 0x70, 0x10, 0x71, 0x10, 0x72, 0x10, 0x73, 0x10, 0x74, 0x10, 0x75, 0x10, 0x76, 0x10, 0x77, 0x10, 0x78, 0x10, + 0x79, 0x10, 0x7A, 0x10, 0x7B, 0x10, 0x7C, 0x10, 0x7D, 0x10, 0x7E, 0x10, 0x7F, 0x10, 0x80, 0x10, 0x81, 0x10, + 0x82, 0x10, 0x83, 0x10, 0x84, 0x10, 0x85, 0x10, 0x86, 0x10, 0x87, 0x10, 0x88, 0x10, 0x89, 0x10, 0x8A, 0x10, + 0x8B, 0x10, 0x8C, 0x10, 0x8D, 0x10, 0x8E, 0x10, 0x8F, 0x10, 0x90, 0x10, 0x91, 0x10, 0x92, 0x10, 0x93, 0x10, + 0x94, 0x10, 0x95, 0x10, 0x96, 0x10, 0x97, 0x10, 0x98, 0x10, 0x99, 0x10, 0x9A, 0x10, 0x9B, 0x10, 0x9C, 0x10, + 0x9D, 0x10, 0x9E, 0x10, 0x9F, 0x10, 0xA0, 0x10, 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, + 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, 0xA9, 0x10, 0xAA, 0x10, 0xAB, 0x10, 0xAC, 0x10, 0xAD, 0x10, 0xAE, 0x10, + 0xAF, 0x10, 0xB0, 0x10, 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, + 0xB8, 0x10, 0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10, + 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xC6, 0x10, 0xC7, 0x10, 0xC8, 0x10, 0xC9, 0x10, + 0xCA, 0x10, 0xCB, 0x10, 0xCC, 0x10, 0xCD, 0x10, 0xCE, 0x10, 0xCF, 0x10, 0xD0, 0x10, 0xD1, 0x10, 0xD2, 0x10, + 0xD3, 0x10, 0xD4, 0x10, 0xD5, 0x10, 0xD6, 0x10, 0xD7, 0x10, 0xD8, 0x10, 0xD9, 0x10, 0xDA, 0x10, 0xDB, 0x10, + 0xDC, 0x10, 0xDD, 0x10, 0xDE, 0x10, 0xDF, 0x10, 0xE0, 0x10, 0xE1, 0x10, 0xE2, 0x10, 0xE3, 0x10, 0xE4, 0x10, + 0xE5, 0x10, 0xE6, 0x10, 0xE7, 0x10, 0xE8, 0x10, 0xE9, 0x10, 0xEA, 0x10, 0xEB, 0x10, 0xEC, 0x10, 0xED, 0x10, + 0xEE, 0x10, 0xEF, 0x10, 0xF0, 0x10, 0xF1, 0x10, 0xF2, 0x10, 0xF3, 0x10, 0xF4, 0x10, 0xF5, 0x10, 0xF6, 0x10, + 0xF7, 0x10, 0xF8, 0x10, 0xF9, 0x10, 0xFA, 0x10, 0xFB, 0x10, 0xFC, 0x10, 0xFD, 0x10, 0xFE, 0x10, 0xFF, 0x10, + 0x00, 0x90, 0x01, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04, 0x10, 0x05, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, + 0x09, 0x10, 0x0A, 0x10, 0x0B, 0x10, 0x0C, 0x10, 0x0D, 0x10, 0x0E, 0x10, 0x0F, 0x10, 0x10, 0x10, 0x11, 0x10, + 0x12, 0x10, 0x13, 0x10, 0x14, 0x10, 0x15, 0x10, 0x16, 0x10, 0x17, 0x10, 0x18, 0x10, 0x19, 0x10, 0x1A, 0x10, + 0x1B, 0x10, 0x1C, 0x10, 0x1D, 0x10, 0x1E, 0x10, 0x1F, 0x10, 0x20, 0x10, 0x21, 0x10, 0x22, 0x10, 0x23, 0x10, + 0x24, 0x10, 0x25, 0x10, 0x26, 0x10, 0x27, 0x10, 0x28, 0x10, 0x29, 0x10, 0x2A, 0x10, 0x2B, 0x10, 0x2C, 0x10, + 0x2D, 0x10, 0x2E, 0x10, 0x2F, 0x10, 0x30, 0x10, 0x31, 0x10, 0x32, 0x10, 0x33, 0x10, 0x34, 0x10, 0x35, 0x10, + 0x36, 0x10, 0x37, 0x10, 0x38, 0x10, 0x39, 0x10, 0x3A, 0x10, 0x3B, 0x10, 0x3C, 0x10, 0x3D, 0x10, 0x3E, 0x10, + 0x3F, 0x10, 0x40, 0x10, 0x41, 0x10, 0x42, 0x10, 0x43, 0x10, 0x44, 0x10, 0x45, 0x10, 0x46, 0x10, 0x47, 0x10, + 0x48, 0x10, 0x49, 0x10, 0x4A, 0x10, 0x4B, 0x10, 0x4C, 0x10, 0x4D, 0x10, 0x4E, 0x10, 0x4F, 0x10, 0x50, 0x10, + 0x51, 0x10, 0x52, 0x10, 0x53, 0x10, 0x54, 0x10, 0x55, 0x10, 0x56, 0x10, 0x57, 0x10, 0x58, 0x10, 0x59, 0x10, + 0x5A, 0x10, 0x5B, 0x10, 0x5C, 0x10, 0x5D, 0x10, 0x5E, 0x10, 0x5F, 0x10, 0x60, 0x10, 0x61, 0x10, 0x62, 0x10, + 0x63, 0x10, 0x64, 0x10, 0x65, 0x10, 0x00, 0xC0, 0x01, 0x40, 0x02, 0x40, 0x03, 0x40, 0x04, 0x40, 0x05, 0x40, + 0x06, 0x40, 0x07, 0x40, 0x08, 0x40, 0x09, 0x40, 0x0A, 0x40, 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x40, 0x0E, 0x40, + 0x0F, 0x40, 0x10, 0x40, 0x11, 0x40, 0x12, 0x40, 0x13, 0x40, 0x14, 0x40, 0x15, 0x40, 0x16, 0x40, 0x17, 0x40, + 0x18, 0x40, 0x19, 0x40, 0x1A, 0x40, 0x1B, 0x40, 0x1C, 0x40, 0x1D, 0x40, 0x1E, 0x40, 0x1F, 0x40, 0x20, 0x40, + 0x21, 0x40, 0x22, 0x40, 0x23, 0x40, 0x24, 0x40, 0x25, 0x40, 0x26, 0x40, 0x27, 0x40, 0x28, 0x40, 0x29, 0x40, + 0x2A, 0x40, 0x2B, 0x40, 0x2C, 0x40, 0x2D, 0x40, 0x2E, 0x40, 0x2F, 0x40, 0x30, 0x40, 0x31, 0x40, 0x32, 0x40, + 0x33, 0x40, 0x34, 0x40, 0x35, 0x40, 0x36, 0x40, 0x37, 0x40, 0x38, 0x40, 0x39, 0x40, 0x3A, 0x40, 0x3B, 0x40, + 0x3C, 0x40, 0x3D, 0x40, 0x3E, 0x40, 0x3F, 0x40, 0x40, 0x40, 0x41, 0x40, 0x42, 0x40, 0x43, 0x40, 0x44, 0x40, + 0x45, 0x40, 0x46, 0x40, 0x47, 0x40, 0x48, 0x40, 0x49, 0x40, 0x4A, 0x40, 0x4B, 0x40, 0x4C, 0x40, 0x4D, 0x40, + 0x4E, 0x40, 0x4F, 0x40, 0x50, 0x40, 0x51, 0x40, 0x52, 0x40, 0x53, 0x40, 0x54, 0x40, 0x55, 0x40, 0x56, 0x40, + 0x57, 0x40, 0x58, 0x40, 0x59, 0x40, 0x5A, 0x40, 0x5B, 0x40, 0x5C, 0x40, 0x5D, 0x40, 0x5E, 0x40, 0x5F, 0x40, + 0x60, 0x40, 0x61, 0x40, 0x62, 0x40, 0x63, 0x40, 0x64, 0x40, 0x65, 0x40, 0x66, 0x40, 0x67, 0x40, 0x68, 0x40, + 0x69, 0x40, 0x6A, 0x40, 0x6B, 0x40, 0x6C, 0x40, 0x6D, 0x40, 0x6E, 0x40, 0x6F, 0x40, 0x70, 0x40, 0x71, 0x40, + 0x72, 0x40, 0x73, 0x40, 0x74, 0x40, 0x75, 0x40, 0x76, 0x40, 0x77, 0x40, 0x78, 0x40, 0x79, 0x40, 0x7A, 0x40, + 0x7B, 0x40, 0x7C, 0x40, 0x7D, 0x40, 0x7E, 0x40, 0x7F, 0x40, 0x80, 0x40, 0x81, 0x40, 0x82, 0x40, 0x83, 0x40, + 0x84, 0x40, 0x85, 0x40, 0x86, 0x40, 0x87, 0x40, 0x88, 0x40, 0x89, 0x40, 0x8A, 0x40, 0x8B, 0x40, 0x8C, 0x40, + 0x8D, 0x40, 0x8E, 0x40, 0x8F, 0x40, 0x90, 0x40, 0x91, 0x40, 0x92, 0x40, 0x93, 0x40, 0x94, 0x40, 0x95, 0x40, + 0x96, 0x40, 0x97, 0x40, 0x98, 0x40, 0x99, 0x40, 0x9A, 0x40, 0x9B, 0x40, 0x9C, 0x40, 0x9D, 0x40, 0x9E, 0x40, + 0x9F, 0x40, 0xA0, 0x40, 0xA1, 0x40, 0xA2, 0x40, 0xA3, 0x40, 0xA4, 0x40, 0xA5, 0x40, 0xA6, 0x40, 0xA7, 0x40, + 0xA8, 0x40, 0xA9, 0x40, 0xAA, 0x40, 0xAB, 0x40, 0xAC, 0x40, 0xAD, 0x40, 0xAE, 0x40, 0xAF, 0x40, 0xB0, 0x40, + 0xB1, 0x40, 0xB2, 0x40, 0xB3, 0x40, 0xB4, 0x40, 0xB5, 0x40, 0xB6, 0x40, 0xB7, 0x40, 0xB8, 0x40, 0xB9, 0x40, + 0xBA, 0x40, 0xBB, 0x40, 0xBC, 0x40, 0xBD, 0x40, 0xBE, 0x40, 0xBF, 0x40, 0xC0, 0x40, 0xC1, 0x40, 0xC2, 0x40, + 0xC3, 0x40, 0xC4, 0x40, 0xC5, 0x40, 0xC6, 0x40, 0xC7, 0x40, 0xC8, 0x40, 0xC9, 0x40, 0xCA, 0x40, 0xCB, 0x40, + 0xCC, 0x40, 0xCD, 0x40, 0xCE, 0x40, 0xCF, 0x40, 0xD0, 0x40, 0xD1, 0x40, 0xD2, 0x40, 0xD3, 0x40, 0xD4, 0x40, + 0xD5, 0x40, 0xD6, 0x40, 0xD7, 0x40, 0xD8, 0x40, 0xD9, 0x40, 0xDA, 0x40, 0xDB, 0x40, 0xDC, 0x40, 0xDD, 0x40, + 0xDE, 0x40, 0xDF, 0x40, 0xE0, 0x40, 0xE1, 0x40, 0xE2, 0x40, 0xE3, 0x40, 0xE4, 0x40, 0xE5, 0x40, 0xE6, 0x40, + 0xE7, 0x40, 0xE8, 0x40, 0xE9, 0x40, 0xEA, 0x40, 0xEB, 0x40, 0xEC, 0x40, 0xED, 0x40, 0xEE, 0x40, 0xEF, 0x40, + 0xF0, 0x40, 0xF1, 0x40, 0xF2, 0x40, 0xF3, 0x40, 0xF4, 0x40, 0xF5, 0x40, 0xF6, 0x40, 0xF7, 0x40, 0xF8, 0x40, + 0xF9, 0x40, 0xFA, 0x40, 0xFB, 0x40, 0xFC, 0x40, 0xFD, 0x40, 0xFE, 0x40, 0xFF, 0x40, 0xA0, 0x50, 0xA1, 0x50, + 0xA2, 0x50, 0xA3, 0x50, 0xA4, 0x50, 0xA5, 0x50, 0xA6, 0x50, 0xA7, 0x50, 0xA8, 0x50, 0xA9, 0x50, 0xAA, 0x50, + 0xAB, 0x50, 0xAC, 0x50, 0xAD, 0x50, 0xAE, 0x50, 0xAF, 0x50, 0xB0, 0x50, 0xB1, 0x50, 0xB2, 0x50, 0xB3, 0x50, + 0xB4, 0x50, 0xB5, 0x50, 0xB6, 0x50, 0xB7, 0x50, 0xB8, 0x50, 0xB9, 0x50, 0xBA, 0x50, 0xBB, 0x50, 0xBC, 0x50, + 0xBD, 0x50, 0xBE, 0x50, 0xBF, 0x50, 0xC0, 0x50, 0xC1, 0x50, 0xC2, 0x50, 0xC3, 0x50, 0xC4, 0x50, 0xC5, 0x50, + 0xC6, 0x50, 0xC7, 0x50, 0xC8, 0x50, 0xC9, 0x50, 0xCA, 0x50, 0xCB, 0x50, 0xCC, 0x50, 0xCD, 0x50, 0xCE, 0x50, + 0xCF, 0x50, 0xD0, 0x50, 0xD1, 0x50, 0xD2, 0x50, 0xD3, 0x50, 0xD4, 0x50, 0xD5, 0x50, 0xD6, 0x50, 0xD7, 0x50, + 0xD8, 0x50, 0xD9, 0x50, 0xDA, 0x50, 0xDB, 0x50, 0xDC, 0x50, 0xDD, 0x50, 0xDE, 0x50, 0xDF, 0x50, 0xE0, 0x50, + 0xE1, 0x50, 0xE2, 0x50, 0xE3, 0x50, 0xE4, 0x50, 0xE5, 0x50, 0xE6, 0x50, 0xE7, 0x50, 0xE8, 0x50, 0xE9, 0x50, + 0xEA, 0x50, 0xEB, 0x50, 0xEC, 0x50, 0xED, 0x50, 0xEE, 0x50, 0xEF, 0x50, 0xF0, 0x50, 0xF1, 0x50, 0xF2, 0x50, + 0xF3, 0x50, 0xF4, 0x50, 0xF5, 0x50, 0xF6, 0x50, 0xF7, 0x50, 0xF8, 0x50, 0xF9, 0x50, 0xFA, 0x50, 0xFB, 0x50, + 0xFC, 0x50, 0xFD, 0x50, 0xFE, 0x50, 0xFF, 0x50, 0x00, 0xD0, 0x01, 0x50, 0x02, 0x50, 0x03, 0x50, 0x04, 0x50, + 0x05, 0x50, 0x06, 0x50, 0x07, 0x50, 0x08, 0x50, 0x09, 0x50, 0x0A, 0x50, 0x0B, 0x50, 0x0C, 0x50, 0x0D, 0x50, + 0x0E, 0x50, 0x0F, 0x50, 0x10, 0x50, 0x11, 0x50, 0x12, 0x50, 0x13, 0x50, 0x14, 0x50, 0x15, 0x50, 0x16, 0x50, + 0x17, 0x50, 0x18, 0x50, 0x19, 0x50, 0x1A, 0x50, 0x1B, 0x50, 0x1C, 0x50, 0x1D, 0x50, 0x1E, 0x50, 0x1F, 0x50, + 0x20, 0x50, 0x21, 0x50, 0x22, 0x50, 0x23, 0x50, 0x24, 0x50, 0x25, 0x50, 0x26, 0x50, 0x27, 0x50, 0x28, 0x50, + 0x29, 0x50, 0x2A, 0x50, 0x2B, 0x50, 0x2C, 0x50, 0x2D, 0x50, 0x2E, 0x50, 0x2F, 0x50, 0x30, 0x50, 0x31, 0x50, + 0x32, 0x50, 0x33, 0x50, 0x34, 0x50, 0x35, 0x50, 0x36, 0x50, 0x37, 0x50, 0x38, 0x50, 0x39, 0x50, 0x3A, 0x50, + 0x3B, 0x50, 0x3C, 0x50, 0x3D, 0x50, 0x3E, 0x50, 0x3F, 0x50, 0x40, 0x50, 0x41, 0x50, 0x42, 0x50, 0x43, 0x50, + 0x44, 0x50, 0x45, 0x50, 0x46, 0x50, 0x47, 0x50, 0x48, 0x50, 0x49, 0x50, 0x4A, 0x50, 0x4B, 0x50, 0x4C, 0x50, + 0x4D, 0x50, 0x4E, 0x50, 0x4F, 0x50, 0x50, 0x50, 0x51, 0x50, 0x52, 0x50, 0x53, 0x50, 0x54, 0x50, 0x55, 0x50, + 0x56, 0x50, 0x57, 0x50, 0x58, 0x50, 0x59, 0x50, 0x5A, 0x50, 0x5B, 0x50, 0x5C, 0x50, 0x5D, 0x50, 0x5E, 0x50, + 0x5F, 0x50, 0x60, 0x50, 0x61, 0x50, 0x62, 0x50, 0x63, 0x50, 0x64, 0x50, 0x65, 0x50, 0x66, 0x50, 0x67, 0x50, + 0x68, 0x50, 0x69, 0x50, 0x6A, 0x50, 0x6B, 0x50, 0x6C, 0x50, 0x6D, 0x50, 0x6E, 0x50, 0x6F, 0x50, 0x70, 0x50, + 0x71, 0x50, 0x72, 0x50, 0x73, 0x50, 0x74, 0x50, 0x75, 0x50, 0x76, 0x50, 0x77, 0x50, 0x78, 0x50, 0x79, 0x50, + 0x7A, 0x50, 0x7B, 0x50, 0x7C, 0x50, 0x7D, 0x50, 0x7E, 0x50, 0x7F, 0x50, 0x80, 0x50, 0x81, 0x50, 0x82, 0x50, + 0x83, 0x50, 0x84, 0x50, 0x85, 0x50, 0x86, 0x50, 0x87, 0x50, 0x88, 0x50, 0x89, 0x50, 0x8A, 0x50, 0x8B, 0x50, + 0x8C, 0x50, 0x8D, 0x50, 0x8E, 0x50, 0x8F, 0x50, 0x90, 0x50, 0x91, 0x50, 0x92, 0x50, 0x93, 0x50, 0x94, 0x50, + 0x95, 0x50, 0x96, 0x50, 0x97, 0x50, 0x98, 0x50, 0x99, 0x50, 0x9A, 0x50, 0x9B, 0x50, 0x9C, 0x50, 0x9D, 0x50, + 0x9E, 0x50, 0x9F, 0x50, 0xFA, 0x40, 0xFB, 0x40, 0xFC, 0x40, 0xFD, 0x40, 0xFE, 0x40, 0xFF, 0x40, 0x00, 0xC0, + 0x01, 0x40, 0x02, 0x40, 0x03, 0x40, 0x04, 0x40, 0x05, 0x40, 0x06, 0x40, 0x07, 0x40, 0x08, 0x40, 0x09, 0x40, + 0x0A, 0x40, 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x40, 0x0E, 0x40, 0x0F, 0x40, 0x10, 0x40, 0x11, 0x40, 0x12, 0x40, + 0x13, 0x40, 0x14, 0x40, 0x15, 0x40, 0x16, 0x40, 0x17, 0x40, 0x18, 0x40, 0x19, 0x40, 0x1A, 0x40, 0x1B, 0x40, + 0x1C, 0x40, 0x1D, 0x40, 0x1E, 0x40, 0x1F, 0x40, 0x20, 0x40, 0x21, 0x40, 0x22, 0x40, 0x23, 0x40, 0x24, 0x40, + 0x25, 0x40, 0x26, 0x40, 0x27, 0x40, 0x28, 0x40, 0x29, 0x40, 0x2A, 0x40, 0x2B, 0x40, 0x2C, 0x40, 0x2D, 0x40, + 0x2E, 0x40, 0x2F, 0x40, 0x30, 0x40, 0x31, 0x40, 0x32, 0x40, 0x33, 0x40, 0x34, 0x40, 0x35, 0x40, 0x36, 0x40, + 0x37, 0x40, 0x38, 0x40, 0x39, 0x40, 0x3A, 0x40, 0x3B, 0x40, 0x3C, 0x40, 0x3D, 0x40, 0x3E, 0x40, 0x3F, 0x40, + 0x40, 0x40, 0x41, 0x40, 0x42, 0x40, 0x43, 0x40, 0x44, 0x40, 0x45, 0x40, 0x46, 0x40, 0x47, 0x40, 0x48, 0x40, + 0x49, 0x40, 0x4A, 0x40, 0x4B, 0x40, 0x4C, 0x40, 0x4D, 0x40, 0x4E, 0x40, 0x4F, 0x40, 0x50, 0x40, 0x51, 0x40, + 0x52, 0x40, 0x53, 0x40, 0x54, 0x40, 0x55, 0x40, 0x56, 0x40, 0x57, 0x40, 0x58, 0x40, 0x59, 0x40, 0x5A, 0x40, + 0x5B, 0x40, 0x5C, 0x40, 0x5D, 0x40, 0x5E, 0x40, 0x5F, 0x40, 0x60, 0x40, 0x61, 0x40, 0x62, 0x40, 0x63, 0x40, + 0x64, 0x40, 0x65, 0x40, 0x66, 0x40, 0x67, 0x40, 0x68, 0x40, 0x69, 0x40, 0x6A, 0x40, 0x6B, 0x40, 0x6C, 0x40, + 0x6D, 0x40, 0x6E, 0x40, 0x6F, 0x40, 0x70, 0x40, 0x71, 0x40, 0x72, 0x40, 0x73, 0x40, 0x74, 0x40, 0x75, 0x40, + 0x76, 0x40, 0x77, 0x40, 0x78, 0x40, 0x79, 0x40, 0x7A, 0x40, 0x7B, 0x40, 0x7C, 0x40, 0x7D, 0x40, 0x7E, 0x40, + 0x7F, 0x40, 0x80, 0x40, 0x81, 0x40, 0x82, 0x40, 0x83, 0x40, 0x84, 0x40, 0x85, 0x40, 0x86, 0x40, 0x87, 0x40, + 0x88, 0x40, 0x89, 0x40, 0x8A, 0x40, 0x8B, 0x40, 0x8C, 0x40, 0x8D, 0x40, 0x8E, 0x40, 0x8F, 0x40, 0x90, 0x40, + 0x91, 0x40, 0x92, 0x40, 0x93, 0x40, 0x94, 0x40, 0x95, 0x40, 0x96, 0x40, 0x97, 0x40, 0x98, 0x40, 0x99, 0x40, + 0x9A, 0x40, 0x9B, 0x40, 0x9C, 0x40, 0x9D, 0x40, 0x9E, 0x40, 0x9F, 0x40, 0xA0, 0x40, 0xA1, 0x40, 0xA2, 0x40, + 0xA3, 0x40, 0xA4, 0x40, 0xA5, 0x40, 0xA6, 0x40, 0xA7, 0x40, 0xA8, 0x40, 0xA9, 0x40, 0xAA, 0x40, 0xAB, 0x40, + 0xAC, 0x40, 0xAD, 0x40, 0xAE, 0x40, 0xAF, 0x40, 0xB0, 0x40, 0xB1, 0x40, 0xB2, 0x40, 0xB3, 0x40, 0xB4, 0x40, + 0xB5, 0x40, 0xB6, 0x40, 0xB7, 0x40, 0xB8, 0x40, 0xB9, 0x40, 0xBA, 0x40, 0xBB, 0x40, 0xBC, 0x40, 0xBD, 0x40, + 0xBE, 0x40, 0xBF, 0x40, 0xC0, 0x40, 0xC1, 0x40, 0xC2, 0x40, 0xC3, 0x40, 0xC4, 0x40, 0xC5, 0x40, 0xC6, 0x40, + 0xC7, 0x40, 0xC8, 0x40, 0xC9, 0x40, 0xCA, 0x40, 0xCB, 0x40, 0xCC, 0x40, 0xCD, 0x40, 0xCE, 0x40, 0xCF, 0x40, + 0xD0, 0x40, 0xD1, 0x40, 0xD2, 0x40, 0xD3, 0x40, 0xD4, 0x40, 0xD5, 0x40, 0xD6, 0x40, 0xD7, 0x40, 0xD8, 0x40, + 0xD9, 0x40, 0xDA, 0x40, 0xDB, 0x40, 0xDC, 0x40, 0xDD, 0x40, 0xDE, 0x40, 0xDF, 0x40, 0xE0, 0x40, 0xE1, 0x40, + 0xE2, 0x40, 0xE3, 0x40, 0xE4, 0x40, 0xE5, 0x40, 0xE6, 0x40, 0xE7, 0x40, 0xE8, 0x40, 0xE9, 0x40, 0xEA, 0x40, + 0xEB, 0x40, 0xEC, 0x40, 0xED, 0x40, 0xEE, 0x40, 0xEF, 0x40, 0xF0, 0x40, 0xF1, 0x40, 0xF2, 0x40, 0xF3, 0x40, + 0xF4, 0x40, 0xF5, 0x40, 0xF6, 0x40, 0xF7, 0x40, 0xF8, 0x40, 0xF9, 0x40, 0x9A, 0x50, 0x9B, 0x50, 0x9C, 0x50, + 0x9D, 0x50, 0x9E, 0x50, 0x9F, 0x50, 0xA0, 0x50, 0xA1, 0x50, 0xA2, 0x50, 0xA3, 0x50, 0xA4, 0x50, 0xA5, 0x50, + 0xA6, 0x50, 0xA7, 0x50, 0xA8, 0x50, 0xA9, 0x50, 0xAA, 0x50, 0xAB, 0x50, 0xAC, 0x50, 0xAD, 0x50, 0xAE, 0x50, + 0xAF, 0x50, 0xB0, 0x50, 0xB1, 0x50, 0xB2, 0x50, 0xB3, 0x50, 0xB4, 0x50, 0xB5, 0x50, 0xB6, 0x50, 0xB7, 0x50, + 0xB8, 0x50, 0xB9, 0x50, 0xBA, 0x50, 0xBB, 0x50, 0xBC, 0x50, 0xBD, 0x50, 0xBE, 0x50, 0xBF, 0x50, 0xC0, 0x50, + 0xC1, 0x50, 0xC2, 0x50, 0xC3, 0x50, 0xC4, 0x50, 0xC5, 0x50, 0xC6, 0x50, 0xC7, 0x50, 0xC8, 0x50, 0xC9, 0x50, + 0xCA, 0x50, 0xCB, 0x50, 0xCC, 0x50, 0xCD, 0x50, 0xCE, 0x50, 0xCF, 0x50, 0xD0, 0x50, 0xD1, 0x50, 0xD2, 0x50, + 0xD3, 0x50, 0xD4, 0x50, 0xD5, 0x50, 0xD6, 0x50, 0xD7, 0x50, 0xD8, 0x50, 0xD9, 0x50, 0xDA, 0x50, 0xDB, 0x50, + 0xDC, 0x50, 0xDD, 0x50, 0xDE, 0x50, 0xDF, 0x50, 0xE0, 0x50, 0xE1, 0x50, 0xE2, 0x50, 0xE3, 0x50, 0xE4, 0x50, + 0xE5, 0x50, 0xE6, 0x50, 0xE7, 0x50, 0xE8, 0x50, 0xE9, 0x50, 0xEA, 0x50, 0xEB, 0x50, 0xEC, 0x50, 0xED, 0x50, + 0xEE, 0x50, 0xEF, 0x50, 0xF0, 0x50, 0xF1, 0x50, 0xF2, 0x50, 0xF3, 0x50, 0xF4, 0x50, 0xF5, 0x50, 0xF6, 0x50, + 0xF7, 0x50, 0xF8, 0x50, 0xF9, 0x50, 0xFA, 0x50, 0xFB, 0x50, 0xFC, 0x50, 0xFD, 0x50, 0xFE, 0x50, 0xFF, 0x50, + 0x00, 0xD0, 0x01, 0x50, 0x02, 0x50, 0x03, 0x50, 0x04, 0x50, 0x05, 0x50, 0x06, 0x50, 0x07, 0x50, 0x08, 0x50, + 0x09, 0x50, 0x0A, 0x50, 0x0B, 0x50, 0x0C, 0x50, 0x0D, 0x50, 0x0E, 0x50, 0x0F, 0x50, 0x10, 0x50, 0x11, 0x50, + 0x12, 0x50, 0x13, 0x50, 0x14, 0x50, 0x15, 0x50, 0x16, 0x50, 0x17, 0x50, 0x18, 0x50, 0x19, 0x50, 0x1A, 0x50, + 0x1B, 0x50, 0x1C, 0x50, 0x1D, 0x50, 0x1E, 0x50, 0x1F, 0x50, 0x20, 0x50, 0x21, 0x50, 0x22, 0x50, 0x23, 0x50, + 0x24, 0x50, 0x25, 0x50, 0x26, 0x50, 0x27, 0x50, 0x28, 0x50, 0x29, 0x50, 0x2A, 0x50, 0x2B, 0x50, 0x2C, 0x50, + 0x2D, 0x50, 0x2E, 0x50, 0x2F, 0x50, 0x30, 0x50, 0x31, 0x50, 0x32, 0x50, 0x33, 0x50, 0x34, 0x50, 0x35, 0x50, + 0x36, 0x50, 0x37, 0x50, 0x38, 0x50, 0x39, 0x50, 0x3A, 0x50, 0x3B, 0x50, 0x3C, 0x50, 0x3D, 0x50, 0x3E, 0x50, + 0x3F, 0x50, 0x40, 0x50, 0x41, 0x50, 0x42, 0x50, 0x43, 0x50, 0x44, 0x50, 0x45, 0x50, 0x46, 0x50, 0x47, 0x50, + 0x48, 0x50, 0x49, 0x50, 0x4A, 0x50, 0x4B, 0x50, 0x4C, 0x50, 0x4D, 0x50, 0x4E, 0x50, 0x4F, 0x50, 0x50, 0x50, + 0x51, 0x50, 0x52, 0x50, 0x53, 0x50, 0x54, 0x50, 0x55, 0x50, 0x56, 0x50, 0x57, 0x50, 0x58, 0x50, 0x59, 0x50, + 0x5A, 0x50, 0x5B, 0x50, 0x5C, 0x50, 0x5D, 0x50, 0x5E, 0x50, 0x5F, 0x50, 0x60, 0x50, 0x61, 0x50, 0x62, 0x50, + 0x63, 0x50, 0x64, 0x50, 0x65, 0x50, 0x66, 0x50, 0x67, 0x50, 0x68, 0x50, 0x69, 0x50, 0x6A, 0x50, 0x6B, 0x50, + 0x6C, 0x50, 0x6D, 0x50, 0x6E, 0x50, 0x6F, 0x50, 0x70, 0x50, 0x71, 0x50, 0x72, 0x50, 0x73, 0x50, 0x74, 0x50, + 0x75, 0x50, 0x76, 0x50, 0x77, 0x50, 0x78, 0x50, 0x79, 0x50, 0x7A, 0x50, 0x7B, 0x50, 0x7C, 0x50, 0x7D, 0x50, + 0x7E, 0x50, 0x7F, 0x50, 0x80, 0x50, 0x81, 0x50, 0x82, 0x50, 0x83, 0x50, 0x84, 0x50, 0x85, 0x50, 0x86, 0x50, + 0x87, 0x50, 0x88, 0x50, 0x89, 0x50, 0x8A, 0x50, 0x8B, 0x50, 0x8C, 0x50, 0x8D, 0x50, 0x8E, 0x50, 0x8F, 0x50, + 0x90, 0x50, 0x91, 0x50, 0x92, 0x50, 0x93, 0x50, 0x94, 0x50, 0x95, 0x50, 0x96, 0x50, 0x97, 0x50, 0x98, 0x50, + 0x99, 0x50 +}; \ No newline at end of file diff --git a/sys/src/games/gb/dat.h b/sys/src/games/gb/dat.h new file mode 100644 index 000000000..c35f7c902 --- /dev/null +++ b/sys/src/games/gb/dat.h @@ -0,0 +1,73 @@ +extern u16int pc, curpc, sp; +extern u8int R[8], Fl; +extern int halt, IME, bank, keys; +extern int clock, ppuclock, divclock, timerclock, syncclock, timerfreq, timer; +extern uchar mem[]; + +extern uchar *cart; +extern int mbc, rombanks, rambanks; + +enum { + rB, + rC, + rD, + rE, + rH, + rL, + rHL, + rA +}; + +enum { + FLAGC = 0x10, + FLAGH = 0x20, + FLAGN = 0x40, + FLAGZ = 0x80, +}; + +enum { + /* interrupt types */ + INTVBLANK = 0, + INTLCDC = 1, + INTTIMER = 2, + INTSIO = 3, + INTIRQ = 4, + + /* I/O registers */ + DIV = 0xFF04, + TIMA = 0xFF05, + TMA = 0xFF06, + TAC = 0xFF07, + LY = 0xFF44, + LCDC = 0xFF40, + STAT = 0xFF41, + SCY = 0xFF42, + SCX = 0xFF43, + LYC = 0xFF45, + BGP = 0xFF47, + OBP0 = 0xFF48, + OBP1 = 0xFF49, + WY = 0xFF4A, + WX = 0xFF4B, + + /* LCDC */ + BGDISP = 1, + SPRITEDISP = 2, + SPRITE16 = 4, + BGTILEMAP = 8, + BGTILEDATA = 16, + WINDOWDISP = 32, + WINDOWTILEMAP = 64, + LCDOP = 128, + + /* LCD STAT */ + MODEHBLANK = 0, + MODEVBLANK = 1, + MODEOAM = 2, + MODELCD = 3, + + /* others */ + IF = 0xFF0F, + IE = 0xFFFF, + CPUFREQ = 4194304, +}; diff --git a/sys/src/games/gb/disasm.c b/sys/src/games/gb/disasm.c new file mode 100644 index 000000000..a40b75130 --- /dev/null +++ b/sys/src/games/gb/disasm.c @@ -0,0 +1,811 @@ +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +static char *opcodes[256] = { + [0x00] "NOP", + [0x01] "LD BC,%.4x", + [0x02] "LD (BC),A", + [0x03] "INC BC", + [0x04] "INC B", + [0x05] "DEC B", + [0x06] "LD B,%.2x", + [0x07] "RLCA ", + [0x08] "LD (%.4x),SP", + [0x09] "ADD HL,BC", + [0x0A] "LD A,(BC)", + [0x0B] "DEC BC", + [0x0C] "INC C", + [0x0D] "DEC C", + [0x0E] "LD C,%.2x", + [0x0F] "RRCA ", + [0x10] "STOP", + [0x11] "LD DE,%.4x", + [0x12] "LD (DE),A", + [0x13] "INC DE", + [0x14] "INC D", + [0x15] "DEC D", + [0x16] "LD D,%.2x", + [0x17] "RLA ", + [0x18] "JR %.2x", + [0x19] "ADD HL,DE", + [0x1A] "LD A,(DE)", + [0x1B] "DEC DE", + [0x1C] "INC E", + [0x1D] "DEC E", + [0x1E] "LD E,%.2x", + [0x1F] "RRA ", + [0x20] "JR NZ,%.2x", + [0x21] "LD HL,%.4x", + [0x22] "LD (HLI),A", + [0x23] "INC HL", + [0x24] "INC H", + [0x25] "DEC H", + [0x26] "LD H,%.2x", + [0x27] "DAA ", + [0x28] "JR Z,%.2x", + [0x29] "ADD HL,HL", + [0x2A] "LD A,(HLI)", + [0x2B] "DEC HL", + [0x2C] "INC L", + [0x2D] "DEC L", + [0x2E] "LD L,%.2x", + [0x2F] "CPL ", + [0x30] "JR NC,%.2x", + [0x31] "LD SP,%.4x", + [0x32] "LD (HLD),A", + [0x33] "INC SP", + [0x34] "INC (HL)", + [0x35] "DEC (HL)", + [0x36] "LD (HL),%.2x", + [0x37] "SCF ", + [0x38] "JR C,%.2x", + [0x39] "ADD HL,SP", + [0x3A] "LD A,(HLD)", + [0x3B] "DEC SP", + [0x3C] "INC A", + [0x3D] "DEC A", + [0x3E] "LD A,%.2x", + [0x3F] "CCF ", + [0x40] "LD B,B", + [0x41] "LD B,C", + [0x42] "LD B,D", + [0x43] "LD B,E", + [0x44] "LD B,H", + [0x45] "LD B,L", + [0x46] "LD B,(HL)", + [0x47] "LD B,A", + [0x48] "LD C,B", + [0x49] "LD C,C", + [0x4A] "LD C,D", + [0x4B] "LD C,E", + [0x4C] "LD C,H", + [0x4D] "LD C,L", + [0x4E] "LD C,(HL)", + [0x4F] "LD C,A", + [0x50] "LD D,B", + [0x51] "LD D,C", + [0x52] "LD D,D", + [0x53] "LD D,E", + [0x54] "LD D,H", + [0x55] "LD D,L", + [0x56] "LD D,(HL)", + [0x57] "LD D,A", + [0x58] "LD E,B", + [0x59] "LD E,C", + [0x5A] "LD E,D", + [0x5B] "LD E,E", + [0x5C] "LD E,H", + [0x5D] "LD E,L", + [0x5E] "LD E,(HL)", + [0x5F] "LD E,A", + [0x60] "LD H,B", + [0x61] "LD H,C", + [0x62] "LD H,D", + [0x63] "LD H,E", + [0x64] "LD H,H", + [0x65] "LD H,L", + [0x66] "LD H,(HL)", + [0x67] "LD H,A", + [0x68] "LD L,B", + [0x69] "LD L,C", + [0x6A] "LD L,D", + [0x6B] "LD L,E", + [0x6C] "LD L,H", + [0x6D] "LD L,L", + [0x6E] "LD L,(HL)", + [0x6F] "LD L,A", + [0x70] "LD (HL),B", + [0x71] "LD (HL),C", + [0x72] "LD (HL),D", + [0x73] "LD (HL),E", + [0x74] "LD (HL),H", + [0x75] "LD (HL),L", + [0x76] "HALT ", + [0x77] "LD (HL),A", + [0x78] "LD A,B", + [0x79] "LD A,C", + [0x7A] "LD A,D", + [0x7B] "LD A,E", + [0x7C] "LD A,H", + [0x7D] "LD A,L", + [0x7E] "LD A,(HL)", + [0x7F] "LD A,A", + [0x80] "ADD A,B", + [0x81] "ADD A,C", + [0x82] "ADD A,D", + [0x83] "ADD A,E", + [0x84] "ADD A,H", + [0x85] "ADD A,L", + [0x86] "ADD A,(HL)", + [0x87] "ADD A,A", + [0x88] "ADC A,B", + [0x89] "ADC A,C", + [0x8A] "ADC A,D", + [0x8B] "ADC A,E", + [0x8C] "ADC A,H", + [0x8D] "ADC A,L", + [0x8E] "ADC A,(HL)", + [0x8F] "ADC A,A", + [0x90] "SUB B", + [0x91] "SUB C", + [0x92] "SUB D", + [0x93] "SUB E", + [0x94] "SUB H", + [0x95] "SUB L", + [0x96] "SUB (HL)", + [0x97] "SUB A", + [0x98] "SBC B", + [0x99] "SBC C", + [0x9A] "SBC D", + [0x9B] "SBC E", + [0x9C] "SBC H", + [0x9D] "SBC L", + [0x9E] "SBC (HL)", + [0x9F] "SBC A", + [0xA0] "AND B", + [0xA1] "AND C", + [0xA2] "AND D", + [0xA3] "AND E", + [0xA4] "AND H", + [0xA5] "AND L", + [0xA6] "AND (HL)", + [0xA7] "AND A", + [0xA8] "XOR B", + [0xA9] "XOR C", + [0xAA] "XOR D", + [0xAB] "XOR E", + [0xAC] "XOR H", + [0xAD] "XOR L", + [0xAE] "XOR (HL)", + [0xAF] "XOR A", + [0xB0] "OR B", + [0xB1] "OR C", + [0xB2] "OR D", + [0xB3] "OR E", + [0xB4] "OR H", + [0xB5] "OR L", + [0xB6] "OR (HL)", + [0xB7] "OR A", + [0xB8] "CP B", + [0xB9] "CP C", + [0xBA] "CP D", + [0xBB] "CP E", + [0xBC] "CP H", + [0xBD] "CP L", + [0xBE] "CP (HL)", + [0xBF] "CP A", + [0xC0] "RET NZ", + [0xC1] "POP BC", + [0xC2] "JP NZ,%.4x", + [0xC3] "JP %.4x", + [0xC4] "CALL NZ,%.4x", + [0xC5] "PUSH BC", + [0xC6] "ADD A,%.2x", + [0xC7] "RST 00H", + [0xC8] "RET Z", + [0xC9] "RET ", + [0xCA] "JP Z,%.4x", + [0xCB] "#CB ", + [0xCC] "CALL Z,%.4x", + [0xCD] "CALL %.4x", + [0xCE] "ADC A,%.2x", + [0xCF] "RST 08H", + [0xD0] "RET NC", + [0xD1] "POP DE", + [0xD2] "JP NC,%.4x", + [0xD3] "---", + [0xD4] "CALL NC,%.4x", + [0xD5] "PUSH DE", + [0xD6] "SUB %.2x", + [0xD7] "RST 10H", + [0xD8] "RET C", + [0xD9] "RETI", + [0xDA] "JP C,%.4x", + [0xDB] "---", + [0xDC] "CALL C,%.4x", + [0xDD] "---", + [0xDE] "SBC A,%.2x", + [0xDF] "RST 18H", + [0xE0] "LD (ff%.2x),A", + [0xE1] "POP HL", + [0xE2] "LD (C),A", + [0xE3] "---", + [0xE4] "---", + [0xE5] "PUSH HL", + [0xE6] "AND %.2x", + [0xE7] "RST 20H", + [0xE8] "ADD SP,%.2x", + [0xE9] "JP (HL)", + [0xEA] "LD (%.4x),A", + [0xEB] "---", + [0xEC] "---", + [0xED] "#ED ", + [0xEE] "XOR %.2x", + [0xEF] "RST 28H", + [0xF0] "LD A,(ff%.2x)", + [0xF1] "POP AF", + [0xF2] "LD A, (C)", + [0xF3] "DI ", + [0xF4] "---", + [0xF5] "PUSH AF", + [0xF6] "OR %.2x", + [0xF7] "RST 30H", + [0xF8] "LDHL SP,%.2x", + [0xF9] "LD SP,HL", + [0xFA] "LD A,(%.4x)", + [0xFB] "EI ", + [0xFC] "---", + [0xFD] "---", + [0xFE] "CP %.2x", + [0xFF] "RST 38H", +}; + +static int operands[256] = { + [0x00] 0, + [0x01] 2, + [0x02] 0, + [0x03] 0, + [0x04] 0, + [0x05] 0, + [0x06] 1, + [0x07] 0, + [0x08] 0, + [0x09] 0, + [0x0A] 0, + [0x0B] 0, + [0x0C] 0, + [0x0D] 0, + [0x0E] 1, + [0x0F] 0, + [0x10] 0, + [0x11] 2, + [0x12] 0, + [0x13] 0, + [0x14] 0, + [0x15] 0, + [0x16] 1, + [0x17] 0, + [0x18] 1, + [0x19] 0, + [0x1A] 0, + [0x1B] 0, + [0x1C] 0, + [0x1D] 0, + [0x1E] 1, + [0x1F] 0, + [0x20] 1, + [0x21] 2, + [0x22] 0, + [0x23] 0, + [0x24] 0, + [0x25] 0, + [0x26] 1, + [0x27] 0, + [0x28] 1, + [0x29] 0, + [0x2A] 0, + [0x2B] 0, + [0x2C] 0, + [0x2D] 0, + [0x2E] 1, + [0x2F] 0, + [0x30] 1, + [0x31] 2, + [0x32] 0, + [0x33] 0, + [0x34] 0, + [0x35] 0, + [0x36] 1, + [0x37] 0, + [0x38] 1, + [0x39] 0, + [0x3A] 2, + [0x3B] 0, + [0x3C] 0, + [0x3D] 0, + [0x3E] 1, + [0x3F] 0, + [0x40] 0, + [0x41] 0, + [0x42] 0, + [0x43] 0, + [0x44] 0, + [0x45] 0, + [0x46] 0, + [0x47] 0, + [0x48] 0, + [0x49] 0, + [0x4A] 0, + [0x4B] 0, + [0x4C] 0, + [0x4D] 0, + [0x4E] 0, + [0x4F] 0, + [0x50] 0, + [0x51] 0, + [0x52] 0, + [0x53] 0, + [0x54] 0, + [0x55] 0, + [0x56] 0, + [0x57] 0, + [0x58] 0, + [0x59] 0, + [0x5A] 0, + [0x5B] 0, + [0x5C] 0, + [0x5D] 0, + [0x5E] 0, + [0x5F] 0, + [0x60] 0, + [0x61] 0, + [0x62] 0, + [0x63] 0, + [0x64] 0, + [0x65] 0, + [0x66] 0, + [0x67] 0, + [0x68] 0, + [0x69] 0, + [0x6A] 0, + [0x6B] 0, + [0x6C] 0, + [0x6D] 0, + [0x6E] 0, + [0x6F] 0, + [0x70] 0, + [0x71] 0, + [0x72] 0, + [0x73] 0, + [0x74] 0, + [0x75] 0, + [0x76] 0, + [0x77] 0, + [0x78] 0, + [0x79] 0, + [0x7A] 0, + [0x7B] 0, + [0x7C] 0, + [0x7D] 0, + [0x7E] 0, + [0x7F] 0, + [0x80] 0, + [0x81] 0, + [0x82] 0, + [0x83] 0, + [0x84] 0, + [0x85] 0, + [0x86] 0, + [0x87] 0, + [0x88] 0, + [0x89] 0, + [0x8A] 0, + [0x8B] 0, + [0x8C] 0, + [0x8D] 0, + [0x8E] 0, + [0x8F] 0, + [0x90] 0, + [0x91] 0, + [0x92] 0, + [0x93] 0, + [0x94] 0, + [0x95] 0, + [0x96] 0, + [0x97] 0, + [0x98] 0, + [0x99] 0, + [0x9A] 0, + [0x9B] 0, + [0x9C] 0, + [0x9D] 0, + [0x9E] 0, + [0x9F] 0, + [0xA0] 0, + [0xA1] 0, + [0xA2] 0, + [0xA3] 0, + [0xA4] 0, + [0xA5] 0, + [0xA6] 0, + [0xA7] 0, + [0xA8] 0, + [0xA9] 0, + [0xAA] 0, + [0xAB] 0, + [0xAC] 0, + [0xAD] 0, + [0xAE] 0, + [0xAF] 0, + [0xB0] 0, + [0xB1] 0, + [0xB2] 0, + [0xB3] 0, + [0xB4] 0, + [0xB5] 0, + [0xB6] 0, + [0xB7] 0, + [0xB8] 0, + [0xB9] 0, + [0xBA] 0, + [0xBB] 0, + [0xBC] 0, + [0xBD] 0, + [0xBE] 0, + [0xBF] 0, + [0xC0] 0, + [0xC1] 0, + [0xC2] 2, + [0xC3] 2, + [0xC4] 2, + [0xC5] 0, + [0xC6] 1, + [0xC7] 0, + [0xC8] 0, + [0xC9] 0, + [0xCA] 2, + [0xCB] 0, + [0xCC] 2, + [0xCD] 2, + [0xCE] 1, + [0xCF] 0, + [0xD0] 0, + [0xD1] 0, + [0xD2] 2, + [0xD3] 1, + [0xD4] 2, + [0xD5] 0, + [0xD6] 1, + [0xD7] 0, + [0xD8] 0, + [0xD9] 0, + [0xDA] 2, + [0xDB] 1, + [0xDC] 2, + [0xDD] 0, + [0xDE] 1, + [0xDF] 0, + [0xE0] 1, + [0xE1] 0, + [0xE2] 0, + [0xE3] 0, + [0xE4] 2, + [0xE5] 0, + [0xE6] 1, + [0xE7] 0, + [0xE8] 0, + [0xE9] 0, + [0xEA] 2, + [0xEB] 0, + [0xEC] 2, + [0xED] 0, + [0xEE] 1, + [0xEF] 0, + [0xF0] 1, + [0xF1] 0, + [0xF2] 0, + [0xF3] 0, + [0xF4] 2, + [0xF5] 0, + [0xF6] 1, + [0xF7] 0, + [0xF8] 1, + [0xF9] 0, + [0xFA] 2, + [0xFB] 0, + [0xFC] 2, + [0xFD] 0, + [0xFE] 1, + [0xFF] 0, +}; + +static char *cbopcodes[256] = { + [0x00] "RLC B", + [0x01] "RLC C", + [0x02] "RLC D", + [0x03] "RLC E", + [0x04] "RLC H", + [0x05] "RLC L", + [0x06] "RLC (HL)", + [0x07] "RLC A", + [0x08] "RRC B", + [0x09] "RRC C", + [0x0A] "RRC D", + [0x0B] "RRC E", + [0x0C] "RRC H", + [0x0D] "RRC L", + [0x0E] "RRC (HL)", + [0x0F] "RRC A", + [0x10] "RL B", + [0x11] "RL C", + [0x12] "RL D", + [0x13] "RL E", + [0x14] "RL H", + [0x15] "RL L", + [0x16] "RL (HL)", + [0x17] "RL A", + [0x18] "RR B", + [0x19] "RR C", + [0x1A] "RR D", + [0x1B] "RR E", + [0x1C] "RR H", + [0x1D] "RR L", + [0x1E] "RR (HL)", + [0x1F] "RR A", + [0x20] "SLA B", + [0x21] "SLA C", + [0x22] "SLA D", + [0x23] "SLA E", + [0x24] "SLA H", + [0x25] "SLA L", + [0x26] "SLA (HL)", + [0x27] "SLA A", + [0x28] "SRA B", + [0x29] "SRA C", + [0x2A] "SRA D", + [0x2B] "SRA E", + [0x2C] "SRA H", + [0x2D] "SRA L", + [0x2E] "SRA (HL)", + [0x2F] "SRA A", + [0x30] "SWAP B", + [0x31] "SWAP C", + [0x32] "SWAP D", + [0x33] "SWAP E", + [0x34] "SWAP H", + [0x35] "SWAP L", + [0x36] "SWAP (HL)", + [0x37] "SWAP A", + [0x38] "SRL B", + [0x39] "SRL C", + [0x3A] "SRL D", + [0x3B] "SRL E", + [0x3C] "SRL H", + [0x3D] "SRL L", + [0x3E] "SRL (HL)", + [0x3F] "SRL A", + [0x40] "BIT 0,B", + [0x41] "BIT 0,C", + [0x42] "BIT 0,D", + [0x43] "BIT 0,E", + [0x44] "BIT 0,H", + [0x45] "BIT 0,L", + [0x46] "BIT 0,(HL)", + [0x47] "BIT 0,A", + [0x48] "BIT 1,B", + [0x49] "BIT 1,C", + [0x4A] "BIT 1,D", + [0x4B] "BIT 1,E", + [0x4C] "BIT 1,H", + [0x4D] "BIT 1,L", + [0x4E] "BIT 1,(HL)", + [0x4F] "BIT 1,A", + [0x50] "BIT 2,B", + [0x51] "BIT 2,C", + [0x52] "BIT 2,D", + [0x53] "BIT 2,E", + [0x54] "BIT 2,H", + [0x55] "BIT 2,L", + [0x56] "BIT 2,(HL)", + [0x57] "BIT 2,A", + [0x58] "BIT 3,B", + [0x59] "BIT 3,C", + [0x5A] "BIT 3,D", + [0x5B] "BIT 3,E", + [0x5C] "BIT 3,H", + [0x5D] "BIT 3,L", + [0x5E] "BIT 3,(HL)", + [0x5F] "BIT 3,A", + [0x60] "BIT 4,B", + [0x61] "BIT 4,C", + [0x62] "BIT 4,D", + [0x63] "BIT 4,E", + [0x64] "BIT 4,H", + [0x65] "BIT 4,L", + [0x66] "BIT 4,(HL)", + [0x67] "BIT 4,A", + [0x68] "BIT 5,B", + [0x69] "BIT 5,C", + [0x6A] "BIT 5,D", + [0x6B] "BIT 5,E", + [0x6C] "BIT 5,H", + [0x6D] "BIT 5,L", + [0x6E] "BIT 5,(HL)", + [0x6F] "BIT 5,A", + [0x70] "BIT 6,B", + [0x71] "BIT 6,C", + [0x72] "BIT 6,D", + [0x73] "BIT 6,E", + [0x74] "BIT 6,H", + [0x75] "BIT 6,L", + [0x76] "BIT 6,(HL)", + [0x77] "BIT 6,A", + [0x78] "BIT 7,B", + [0x79] "BIT 7,C", + [0x7A] "BIT 7,D", + [0x7B] "BIT 7,E", + [0x7C] "BIT 7,H", + [0x7D] "BIT 7,L", + [0x7E] "BIT 7,(HL)", + [0x7F] "BIT 7,A", + [0x80] "RES 0,B", + [0x81] "RES 0,C", + [0x82] "RES 0,D", + [0x83] "RES 0,E", + [0x84] "RES 0,H", + [0x85] "RES 0,L", + [0x86] "RES 0,(HL)", + [0x87] "RES 0,A", + [0x88] "RES 1,B", + [0x89] "RES 1,C", + [0x8A] "RES 1,D", + [0x8B] "RES 1,E", + [0x8C] "RES 1,H", + [0x8D] "RES 1,L", + [0x8E] "RES 1,(HL)", + [0x8F] "RES 1,A", + [0x90] "RES 2,B", + [0x91] "RES 2,C", + [0x92] "RES 2,D", + [0x93] "RES 2,E", + [0x94] "RES 2,H", + [0x95] "RES 2,L", + [0x96] "RES 2,(HL)", + [0x97] "RES 2,A", + [0x98] "RES 3,B", + [0x99] "RES 3,C", + [0x9A] "RES 3,D", + [0x9B] "RES 3,E", + [0x9C] "RES 3,H", + [0x9D] "RES 3,L", + [0x9E] "RES 3,(HL)", + [0x9F] "RES 3,A", + [0xA0] "RES 4,B", + [0xA1] "RES 4,C", + [0xA2] "RES 4,D", + [0xA3] "RES 4,E", + [0xA4] "RES 4,H", + [0xA5] "RES 4,L", + [0xA6] "RES 4,(HL)", + [0xA7] "RES 4,A", + [0xA8] "RES 5,B", + [0xA9] "RES 5,C", + [0xAA] "RES 5,D", + [0xAB] "RES 5,E", + [0xAC] "RES 5,H", + [0xAD] "RES 5,L", + [0xAE] "RES 5,(HL)", + [0xAF] "RES 5,A", + [0xB0] "RES 6,B", + [0xB1] "RES 6,C", + [0xB2] "RES 6,D", + [0xB3] "RES 6,E", + [0xB4] "RES 6,H", + [0xB5] "RES 6,L", + [0xB6] "RES 6,(HL)", + [0xB7] "RES 6,A", + [0xB8] "RES 7,B", + [0xB9] "RES 7,C", + [0xBA] "RES 7,D", + [0xBB] "RES 7,E", + [0xBC] "RES 7,H", + [0xBD] "RES 7,L", + [0xBE] "RES 7,(HL)", + [0xBF] "RES 7,A", + [0xC0] "SET 0,B", + [0xC1] "SET 0,C", + [0xC2] "SET 0,D", + [0xC3] "SET 0,E", + [0xC4] "SET 0,H", + [0xC5] "SET 0,L", + [0xC6] "SET 0,(HL)", + [0xC7] "SET 0,A", + [0xC8] "SET 1,B", + [0xC9] "SET 1,C", + [0xCA] "SET 1,D", + [0xCB] "SET 1,E", + [0xCC] "SET 1,H", + [0xCD] "SET 1,L", + [0xCE] "SET 1,(HL)", + [0xCF] "SET 1,A", + [0xD0] "SET 2,B", + [0xD1] "SET 2,C", + [0xD2] "SET 2,D", + [0xD3] "SET 2,E", + [0xD4] "SET 2,H", + [0xD5] "SET 2,L", + [0xD6] "SET 2,(HL)", + [0xD7] "SET 2,A", + [0xD8] "SET 3,B", + [0xD9] "SET 3,C", + [0xDA] "SET 3,D", + [0xDB] "SET 3,E", + [0xDC] "SET 3,H", + [0xDD] "SET 3,L", + [0xDE] "SET 3,(HL)", + [0xDF] "SET 3,A", + [0xE0] "SET 4,B", + [0xE1] "SET 4,C", + [0xE2] "SET 4,D", + [0xE3] "SET 4,E", + [0xE4] "SET 4,H", + [0xE5] "SET 4,L", + [0xE6] "SET 4,(HL)", + [0xE7] "SET 4,A", + [0xE8] "SET 5,B", + [0xE9] "SET 5,C", + [0xEA] "SET 5,D", + [0xEB] "SET 5,E", + [0xEC] "SET 5,H", + [0xED] "SET 5,L", + [0xEE] "SET 5,(HL)", + [0xEF] "SET 5,A", + [0xF0] "SET 6,B", + [0xF1] "SET 6,C", + [0xF2] "SET 6,D", + [0xF3] "SET 6,E", + [0xF4] "SET 6,H", + [0xF5] "SET 6,L", + [0xF6] "SET 6,(HL)", + [0xF7] "SET 6,A", + [0xF8] "SET 7,B", + [0xF9] "SET 7,C", + [0xFA] "SET 7,D", + [0xFB] "SET 7,E", + [0xFC] "SET 7,H", + [0xFD] "SET 7,L", + [0xFE] "SET 7,(HL)", + [0xFF] "SET 7,A", +}; + +void +disasm(u16int addr) +{ + u8int op; + int x; + + op = memread(addr); + if(op == 0xCB){ + op = memread(addr + 1); + print("%s\n", cbopcodes[op]); + return; + } + switch(operands[op]){ + case 0: + print(opcodes[op]); + break; + case 1: + print(opcodes[op], (int)(memread(addr + 1))); + break; + case 2: + x = (uint)memread(addr + 2); + x <<= 8; + x |= (uint)memread(addr + 1); + print(opcodes[op], x); + } + print("\n"); +} diff --git a/sys/src/games/gb/fns.h b/sys/src/games/gb/fns.h new file mode 100644 index 000000000..092628219 --- /dev/null +++ b/sys/src/games/gb/fns.h @@ -0,0 +1,6 @@ +u8int memread(u16int); +void memwrite(u16int, u8int); +int step(void); +void ppustep(void); +void disasm(u16int); +void interrupt(u8int); diff --git a/sys/src/games/gb/gb.c b/sys/src/games/gb/gb.c new file mode 100644 index 000000000..5ba26ea4a --- /dev/null +++ b/sys/src/games/gb/gb.c @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +uchar *cart; +int mbc, rombanks, clock, ppuclock, divclock, timerclock, syncclock, timerfreq, timer, keys; +Rectangle picr; +Image *bg; + +void +loadrom(char *file) +{ + int fd, i; + vlong len; + u8int ck; + char title[17]; + Point p; + + fd = open(file, OREAD); + if(fd < 0) + sysfatal("open: %r"); + len = seek(fd, 0, 2); + if(len < 0) + sysfatal("seek: %r"); + if(len == 0 || len > 16*1048576) + sysfatal("are you sure this is a ROM?"); + cart = malloc(len); + if(cart == nil) + sysfatal("malloc: %r"); + seek(fd, 0, 0); + if(readn(fd, cart, len) < len) + sysfatal("read: %r"); + close(fd); + + ck = 0; + for(i = 0x134; i <= 0x14C; i++) + ck -= cart[i] + 1; + if(ck != cart[0x14D]) + sysfatal("checksum mismatch: %.2x != %.2x", ck, cart[0x14D]); + memcpy(mem, cart, 32768); + memset(title, 0, sizeof(title)); + memcpy(title, cart+0x134, 16); + switch(cart[0x147]){ + case 0x00: + mbc = 0; + break; + case 0x01: + mbc = 1; + break; + case 0x13: + mbc = 3; + break; + default: + sysfatal("%s: unknown cartridge type %.2x", file, cart[0x147]); + } + switch(cart[0x148]){ + case 0: case 1: case 2: + case 3: case 4: case 5: + case 6: case 7: + rombanks = 2 << (uint)cart[0x148]; + break; + case 52: + rombanks = 72; + break; + case 53: + rombanks = 80; + break; + case 54: + rombanks = 96; + break; + } + if(len < rombanks * 0x4000) + sysfatal("cartridge image is too small, %.4x < %.4x", (int)len, rombanks * 0x4000); + + initdraw(nil, nil, title); + open("/dev/mouse", OREAD); + originwindow(screen, Pt(0, 0), screen->r.min); + p = divpt(addpt(screen->r.min, screen->r.max), 2); + picr = (Rectangle){subpt(p, Pt(80, 72)), addpt(p, Pt(80, 72))}; + bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF); + draw(screen, screen->r, bg, nil, ZP); +} + +void +keyproc(void *) +{ + int fd; + char buf[256], *s; + Rune r; + + fd = open("/dev/kbd", OREAD); + if(fd < 0) + sysfatal("open: %r"); + for(;;){ + if(read(fd, buf, 256) <= 0) + sysfatal("read /dev/kbd: %r"); + if(buf[0] == 'c' && strchr(buf, 'q')) + threadexitsall(nil); + if(buf[0] != 'k' && buf[0] != 'K') + continue; + s = buf + 1; + keys = 0; + while(*s != 0){ + s += chartorune(&r, s); + switch(r){ + case 'q': + threadexitsall(nil); + case Kdown: + keys |= 1<<3; + break; + case Kup: + keys |= 1<<2; + break; + case Kleft: + keys |= 1<<1; + break; + case Kright: + keys |= 1<<0; + break; + case 'x': + keys |= 1<<4; + break; + case 'z': + keys |= 1<<5; + break; + case Kshift: + keys |= 1<<6; + break; + case 10: + keys |= 1<<7; + break; + } + } + } +} + +void +threadmain(int argc, char** argv) +{ + int t, count; + vlong old, new, diff; + + ARGBEGIN{ + default: + sysfatal("unknown flag -%c", ARGC()); + }ARGEND; + if(argc == 0) + sysfatal("argument missing"); + pc = 0x100; + sp = 0xFFFE; + R[rA] = 0x01; + R[rC] = 0x13; + R[rE] = 0xD8; + R[rL] = 0x4D; + R[rH] = 0x01; + Fl = 0xB0; + loadrom(argv[0]); + proccreate(keyproc, nil, 8192); + count = 0; + old = nsec(); + for(;;){ + if(pc == 0x231 && count++) + break; + t = step(); + clock += t; + ppuclock += t; + divclock += t; + timerclock += t; + syncclock += t; + if(ppuclock >= 456){ + ppustep(); + ppuclock -= 456; + } + if(divclock >= 256){ + mem[DIV]++; + divclock = 0; + } + if(timer && timerclock >= timerfreq){ + mem[TIMA]++; + if(mem[TIMA] == 0){ + mem[TIMA] = mem[TMA]; + interrupt(INTTIMER); + } + timerclock = 0; + } + if(syncclock >= CPUFREQ / 100){ + new = nsec(); + diff = new - old; + diff = 10000000 - diff; + diff /= 1000000; + if(diff > 0) + sleep(diff); + old = new; + syncclock = 0; + } + } +} diff --git a/sys/src/games/gb/mem.c b/sys/src/games/gb/mem.c new file mode 100644 index 000000000..9a186c290 --- /dev/null +++ b/sys/src/games/gb/mem.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +uchar mem[65536]; +int bank; + +u8int +memread(u16int p) +{ + extern int keys; + + if((p & 0xFF80) == 0xFF00) + switch(p){ + case 0xFF00: + if((mem[0xFF00] & (1<<5)) == 0) + return (mem[0xFF00] & 0xF0) | ~(keys >> 4); + if((mem[0xFF00] & (1<<6)) == 0) + return (mem[0xFF00] & 0xF0) | ~(keys & 0x0F); + return (mem[0xFF00] & 0xF0) | 0x0F; + } + return mem[p]; +} + +void +memwrite(u16int p, u8int v) +{ + if(p < 0x8000){ + switch(mbc){ + case 0: + return; + case 1: + switch(p >> 13){ + case 1: + if(v == 0) + v++; + bank = v; + if(bank >= rombanks) + sysfatal("invalid ROM bank %d selected (pc = %.4x)", bank, curpc); + memcpy(mem + 0x4000, cart + 0x4000 * bank, 0x4000); + return; + + } + return; + case 3: + switch(p >> 13){ + case 1: + bank = v; + if(bank >= rombanks) + sysfatal("invalid ROM bank %d selected (pc = %.4x)", bank, curpc); + memcpy(mem + 0x4000, cart + 0x4000 * bank, 0x4000); + return; + } + return; + default: + sysfatal("mbc %d unimplemented", mbc); + } + } + if((p & 0xFF80) == 0xFF00) + switch(p){ + case 0xFF04: + v = 0; + break; + case 0xFF07: + timer = (v & 4) != 0; + switch(v & 3){ + case 0: + timerfreq = 1024; + break; + case 1: + timerfreq = 16; + break; + case 2: + timerfreq = 64; + break; + default: + timerfreq = 256; + } + break; + case 0xFF41: + v &= ~7; + v |= mem[p] & 7; + break; + case 0xFF46: + memcpy(mem + 0xFE00, mem + (((int)v) << 8), 0xA0); + break; + } + mem[p] = v; +} diff --git a/sys/src/games/gb/mkfile b/sys/src/games/gb/mkfile new file mode 100644 index 000000000..823f64cad --- /dev/null +++ b/sys/src/games/gb/mkfile @@ -0,0 +1,15 @@ + +#include +#include +#include +#include "dat.h" +#include "fns.h" + +uchar pic[160*144*4]; + +static void +resolvetile(u8int tx, u8int ty, u8int toy, int window, u8int* tnl1, u8int *tnl2) +{ + u16int tni, tnli; + u8int tn; + + tni = 0x9800 + 32 * ((u16int)ty) + ((u16int)tx); + if(window){ + if(mem[LCDC] & WINDOWTILEMAP) + tni += 0x400; + }else + if(mem[LCDC] & BGTILEMAP) + tni += 0x400; + tn = mem[tni]; + if(mem[LCDC] & BGTILEDATA) + tnli = 0x8000 + 16 * (u16int)tn; + else + tnli = 0x9000 + 16 * (u16int)(schar)tn; + *tnl1 = mem[tnli + 2 * ((u16int)toy)]; + *tnl2 = mem[tnli + 2 * ((u16int)toy) + 1]; +} + +static void +pixel(int x, int y, int val, int back) +{ + val = (3 - val) * 0x55; + pic[y*160*4 + x*4] = val; + pic[y*160*4 + x*4 + 1] = val; + pic[y*160*4 + x*4 + 2] = val; + pic[y*160*4 + x*4 + 3] = back ? 0 : 0xFF; +} + +static void +pixelbelow(int x, int y, int val) +{ + if(pic[y*160*4 + x*4 + 3] == 0) + pixel(x, y, val, 0); +} + +static void +zeropic(void) +{ + int i; + + for(i = 0; i < sizeof pic; i++) + pic[i] = ((i & 3) == 3) ? 0 : 0xFF; +} + +static void +drawbg(void) +{ + u8int Y, x, y, ty, toy, tx, tox, tnl1, tnl2, pal, val,h; + + Y = mem[LY]; + y = Y + mem[SCY]; + ty = y / 8; + toy = y % 8; + tx = mem[SCX] / 8; + tox = mem[SCX] % 8; + resolvetile(tx, ty, toy, 0, &tnl1, &tnl2); + tnl1 <<= (tox+1) % 8; + tnl2 <<= (tox+1) % 8; + pal = mem[BGP]; + for(x = 0; x < 160; x++){ + tox++; + if((tox % 8) == 0){ + tx++; + resolvetile(tx%32, ty, toy, 0, &tnl1, &tnl2); + } + val = ((tnl1 & 0x80) >> 6) | ((tnl2 & 0x80) >> 5); + h = val == 0; + val = (pal >> val) & 3; + pixel(x, Y, val, h); + tnl1 <<= 1; + tnl2 <<= 1; + } +} + +static void +drawsprites(void) +{ + u8int x, y, tnl1, tnl2, dx, ddx, val, pal; + schar dy; + u16int tnli; + int i; + struct { u8int y, x, t, f; } *s; + + y = mem[LY]; + s = (void*)(mem + 0xFE00); + for(i = 0; i < 40; i++, s++){ + if(s->y == 0 && s->x == 0) + continue; + dy = y - s->y + 16; + if(dy < 0 || dy >= 8) + continue; + pal = (s->f & (1<<4)) ? mem[OBP1] : mem[OBP0]; + if(s->f & (1<<6)) + dy = 7 - dy; + tnli = 0x8000 + 2 * (u16int)dy + 16 * (u16int) s->t; + tnl1 = mem[tnli]; + tnl2 = mem[tnli + 1]; + x = s->x - 9; + for(dx = 0; dx < 8; dx++, x++){ + ddx = dx; + if((s->f & (1<<5)) == 0) + ddx = 7 - dx; + val = ((tnl1 >> ddx) & 1) | (((tnl2 >> ddx) & 1) << 1); + if(val == 0) + continue; + val = (pal >> (2 * val)) & 3; + if(x >= 160) + break; + if(s->f & (1<<7)){ + pixelbelow(x, y, val); + }else + pixel(x, y, val, 0); + } + } +} + +static void +drawwindow(void) +{ + u8int wx, wy, Y, y, ty, toy, tx, tox, tnl1, tnl2, x, val, pal; + if(mem[WX] < 7) + return; + wx = mem[WX] - 7; + wy = mem[WY]; + Y = mem[LY]; + if(Y < wy) + return; + y = Y - wy; + ty = y / 8; + toy = y % 8; + tx = 0; + tox = 0; + resolvetile(tx, ty, toy, 1, &tnl1, &tnl2); + pal = mem[BGP]; + for(x = wx; x < 160; x++){ + tox++; + if((tox & 7) == 0){ + tx++; + resolvetile(tx, ty, toy, 1, &tnl1, &tnl2); + } + val = ((tnl1 & 0x80) >> 6) | ((tnl2 & 0x80) >> 5); + val = (pal >> val) & 3; + pixel(x, Y, val, 0); + tnl1 <<= 1; + tnl2 <<= 1; + } +} + +void +ppustep(void) +{ + extern Rectangle picr; + + if(mem[LY] == 144){ + mem[STAT] &= ~3; + mem[STAT] |= 1; + interrupt(INTVBLANK); + } + if(mem[LY] == mem[LYC]){ + mem[STAT] |= 4; + if(mem[STAT] & 64) + interrupt(INTLCDC); + }else + mem[STAT] &= ~4; + if(mem[LY] < 144 && (mem[LCDC] & LCDOP)){ + mem[STAT] &= ~3; + if(mem[LCDC] & BGDISP) + drawbg(); + if(mem[LCDC] & WINDOWDISP) + drawwindow(); + if(mem[LCDC] & SPRITEDISP) + drawsprites(); + } + mem[LY]++; + if(mem[LY] > 160){ + mem[LY] = 0; + if(mem[LCDC] & LCDOP){ + loadimage(screen, picr, pic, sizeof(pic)); + flushimage(display, 1); + zeropic(); + } + } +} diff --git a/sys/src/games/mkfile b/sys/src/games/mkfile index 1440daa85..6a8f32f9e 100644 --- a/sys/src/games/mkfile +++ b/sys/src/games/mkfile @@ -22,6 +22,7 @@ BIN=/$objtype/bin/games DIRS=\ blabs\ doom\ + gb\ mahjongg\ mines\ music\