/* Compile with gcc 2600.c `sdl-config --cflags --libs` Run and press Enter to start the game Use arrow keys and space to control the game */ #include #include #include #include typedef uint8_t u8int; typedef uint16_t u16int; typedef uint32_t u32int; typedef int8_t s8int; extern u16int pc, curpc; extern u8int rP; extern int nrdy, trace; extern int keys; extern int ppux, ppuy; extern u8int p0x, p1x, m0x, m1x, blx; extern u16int coll; extern u8int reg[64]; enum { FLAGC = 1<<0, FLAGZ = 1<<1, FLAGI = 1<<2, FLAGD = 1<<3, FLAGB = 1<<4, FLAGV = 1<<6, FLAGN = 1<<7, }; enum { VSYNC, VBLANK, WSYNC, RSYNC, NUSIZ0, NUSIZ1, COLUP0, COLUP1, COLUPF, COLUBK, CTRLPF, REFP0, REFP1, PF0, PF1, PF2, RESP0, RESP1, RESM0, RESM1, RESBL, AUDC0, AUDC1, AUDF0, AUDF1, AUDV0, AUDV1, GRP0, GRP1, ENAM0, ENAM1, ENABL, HMP0, HMP1, HMM0, HMM1, HMBL, VDELP0, VDELP1, VDELBL, RESMP0, RESMP1, HMOVE, HMCLR, CXCLR, }; u8int memread(u16int); void memwrite(u16int, u8int); void io(void); void flush(void); enum { PICW = 320, PICH = 222, BILLION = 1000*1000*1000, MILLION = 1000*1000, HZ = 3579545, RATE = 44100, SAMPDIV = HZ / 3 / RATE, }; u16int pc, curpc; u8int rA, rX, rY, rS, rP; int nrdy; static u8int fetch8(void) { return memread(pc++); } static u16int fetch16(void) { u16int r; r = memread(pc++); r |= memread(pc++) << 8; return r; } static void push8(u8int v) { memwrite(0x100 | rS--, v); } static void push16(u16int v) { memwrite(0x100 | rS--, v >> 8); memwrite(0x100 | rS--, v); } static u8int pop8(void) { return memread(0x100 | ++rS); } static u16int pop16(void) { u16int v; v = memread(0x100 | ++rS); v |= memread(0x100 | ++rS) << 8; return v; } #define imm() fetch8() #define zp() memread(fetch8()) #define zpX() memread(azpX(rX)) #define zpY() memread(azpX(rY)) #define abso() memread(fetch16()) #define absX() memread(aabsX(rX, 0)) #define absY() memread(aabsX(rY, 0)) #define indX() memread(aindX()) #define indY() memread(aindY(0)) static u16int azpX(u8int a) { u8int v; v = fetch8(); memread(v); return v + a; } static u16int aabsX(u8int a, int wr) { u16int v, c; v = fetch16(); c = (u8int)v + a & 0x100; v += a; if(c != 0 || wr) memread(v - c); return v; } static u16int aindX(void) { u8int r; u16int a; r = fetch8(); memread(r); r += rX; a = memread(r++); a |= memread(r) << 8; return a; } static u16int aindY(int wr) { u8int r; u16int a, c; r = fetch8(); a = memread(r++) + rY; c = a & 0x100; a += memread(r) << 8; if(c != 0 || wr) memread(a - c); return a; } static void adc(u8int d) { int r; if((rP & FLAGD) != 0){ r = (rA & 0xf) + (d & 0xf) + (rP & FLAGC); if(r > 0x09) r += 0x06; if(r > 0x1f) r -= 0x10; r += (rA & 0xf0) + (d & 0xf0); }else r = rA + d + (rP & FLAGC); rP &= ~(FLAGN | FLAGZ | FLAGV | FLAGC); if((~(rA ^ d) & (rA ^ r)) & 0x80) rP |= FLAGV; if((rP & FLAGD) != 0 && r > 0x9f) r += 0x60; if(r > 0xFF) rP |= FLAGC; if(r & 0x80) rP |= FLAGN; rA = r; if(rA == 0) rP |= FLAGZ; } static u8int nz(u8int d) { rP &= ~(FLAGN | FLAGZ); if(d & 0x80) rP |= FLAGN; if(d == 0) rP |= FLAGZ; return d; } static void asl(u16int a) { u8int v; rP &= ~(FLAGN | FLAGZ | FLAGC); v = memread(a); memwrite(a, v); if(v & 0x80) rP |= FLAGC; v <<= 1; if(v == 0) rP |= FLAGZ; if(v & 0x80) rP |= FLAGN; memwrite(a, v); } static void lsr(u16int a) { u8int v; rP &= ~(FLAGN | FLAGZ | FLAGC); v = memread(a); memwrite(a, v); rP |= v & 1; v >>= 1; if(v == 0) rP |= FLAGZ; if(v & 0x80) rP |= FLAGN; memwrite(a, v); } static void branch(void) { s8int t; u16int npc; t = fetch8(); memread(pc); npc = pc + t; if((npc ^ pc) >> 8) memread(pc & 0xff00 | npc & 0xff); pc = npc; } static void cmp(u8int a, u8int d) { rP &= ~(FLAGN | FLAGZ | FLAGC); if(a == d) rP |= FLAGZ; if(a >= d) rP |= FLAGC; if((a - d) & 0x80) rP |= FLAGN; } static void dec(u16int a) { u8int v; v = memread(a); memwrite(a, v); memwrite(a, nz(v - 1)); } static void inc(u16int a) { u8int v; v = memread(a); memwrite(a, v); v = nz(v + 1); memwrite(a, v); } static void rol(u16int a) { u8int v, b; v = memread(a); memwrite(a, v); b = rP & FLAGC; rP &= ~(FLAGC | FLAGN | FLAGZ); if(v & 0x80) rP |= FLAGC; v = (v << 1) | b; if(v & 0x80) rP |= FLAGN; if(v == 0) rP |= FLAGZ; memwrite(a, v); } static void ror(u16int a) { u8int v, b; v = memread(a); memwrite(a, v); b = rP & FLAGC; rP &= ~(FLAGC | FLAGN | FLAGZ); rP |= v & 1; v = (v >> 1) | (b << 7); if(v & 0x80) rP |= FLAGN; if(v == 0) rP |= FLAGZ; memwrite(a, v); } static void sbc(u8int d) { int r; if((rP & FLAGD) != 0){ d = ~d; r = (rA & 0xf) + (d & 0xf) + (rP & FLAGC); if(r < 0x10) r -= 0x06; if(r < 0) r += 0x10; r += (rA & 0xf0) + (d & 0xf0); }else r = rA + (u8int)~d + (rP & FLAGC); rP &= ~(FLAGZ | FLAGV | FLAGC | FLAGN); if(((rA ^ d) & (rA ^ r)) & 0x80) rP |= FLAGV; if(r > 0xFF) rP |= FLAGC; else if((rP & FLAGD) != 0) r -= 0x60; rA = r; if(rA == 0) rP |= FLAGZ; if(rA & 0x80) rP |= FLAGN; } static void interrupt(int nmi, int brk) { fetch8(); push16(pc); push8(rP | 0x20 | (brk << 4)); pc = memread(0xFFFA | (!nmi << 2)); pc |= memread(0xFFFB | (!nmi << 2)) << 8; rP |= FLAGI; } void step(void) { u8int op; u16int a, v; if(nrdy){ io(); return; } curpc = pc; op = fetch8(); switch(op){ case 0x00: fetch8(); interrupt(0, 1); return; case 0x01: nz(rA |= indX()); return; case 0x05: nz(rA |= zp()); return; case 0x06: asl(fetch8()); return; case 0x08: memread(pc); push8(rP | 0x30); return; case 0x09: nz(rA |= imm()); return; case 0x0A: rP &= ~(FLAGN | FLAGZ | FLAGC); if(rA & 0x80) rP |= FLAGC; rA <<= 1; if(rA == 0) rP |= FLAGZ; if(rA & 0x80) rP |= FLAGN; memread(pc); return; case 0x0D: nz(rA |= abso()); return; case 0x0E: asl(fetch16()); return; case 0x10: if((rP & FLAGN) == 0) branch(); else fetch8(); return; case 0x11: nz(rA |= indY()); return; case 0x15: nz(rA |= zpX()); return; case 0x16: asl(azpX(rX)); return; case 0x18: rP &= ~FLAGC; memread(pc); return; case 0x19: nz(rA |= absY()); return; case 0x1D: nz(rA |= absX()); return; case 0x1E: asl(aabsX(rX, 1)); return; case 0x20: v = fetch8(); memread(rS|0x100); push16(pc); pc = fetch8() << 8 | v; return; case 0x21: nz(rA &= indX()); return; case 0x24: a = memread(fetch8()); rP &= ~(FLAGN | FLAGZ | FLAGV); rP |= a & 0xC0; if((a & rA) == 0) rP |= FLAGZ; return; case 0x25: nz(rA &= zp()); return; case 0x26: rol(fetch8()); return; case 0x28: memread(pc); memread(0x100|rS); rP = pop8() & 0xcf; return; case 0x29: nz(rA &= imm()); return; case 0x2A: a = rP & FLAGC; rP &= ~(FLAGC | FLAGZ | FLAGN); if(rA & 0x80) rP |= FLAGC; rA = (rA << 1) | a; if(rA & 0x80) rP |= FLAGN; if(rA == 0) rP |= FLAGZ; memread(pc); return; case 0x2C: a = memread(fetch16()); rP &= ~(FLAGN | FLAGZ | FLAGV); rP |= a & 0xC0; if((a & rA) == 0) rP |= FLAGZ; return; case 0x2D: nz(rA &= abso()); return; case 0x2E: rol(fetch16()); return; case 0x30: if((rP & FLAGN) != 0) branch(); else fetch8(); return; case 0x31: nz(rA &= indY()); return; case 0x35: nz(rA &= zpX()); return; case 0x36: rol(azpX(rX)); return; case 0x38: rP |= FLAGC; memread(pc); return; case 0x39: nz(rA &= absY()); return; case 0x3E: rol(aabsX(rX, 1)); return; case 0x3D: nz(rA &= absX()); return; case 0x40: fetch8(); memread(rS|0x100); rP = pop8() & 0xcf; pc = pop16(); return; case 0x41: nz(rA ^= indX()); return; case 0x45: nz(rA ^= zp()); return; case 0x46: lsr(fetch8()); return; case 0x48: memread(pc); push8(rA); return; case 0x49: nz(rA ^= imm()); return; case 0x4A: rP &= ~(FLAGN | FLAGZ | FLAGC); rP |= rA & 1; rA >>= 1; if(rA == 0) rP |= FLAGZ; if(rA & 0x80) rP |= FLAGN; memread(pc); return; case 0x4C: pc = fetch16(); return; case 0x4D: nz(rA ^= abso()); return; case 0x4E: lsr(fetch16()); return; case 0x51: nz(rA ^= indY()); return; case 0x56: lsr(azpX(rX)); return; case 0x58: rP &= ~FLAGI; memread(pc); return; case 0x50: if((rP & FLAGV) == 0) branch(); else fetch8(); return; case 0x55: nz(rA ^= zpX()); return; case 0x59: nz(rA ^= absY()); return; case 0x5D: nz(rA ^= absX()); return; case 0x5E: lsr(aabsX(rX, 1)); return; case 0x60: fetch8(); memread(rS | 0x100); pc = pop16(); fetch8(); return; case 0x61: adc(indX()); return; case 0x65: adc(zp()); return; case 0x66: ror(fetch8()); return; case 0x68: memread(pc); memread(0x100|rS); nz(rA = pop8()); return; case 0x69: adc(imm()); return; case 0x6A: a = rP & FLAGC; rP &= ~(FLAGC | FLAGN | FLAGZ); rP |= rA & 1; rA = (rA >> 1) | (a << 7); if(rA & 0x80) rP |= FLAGN; if(rA == 0) rP |= FLAGZ; memread(pc); return; case 0x6C: v = fetch16(); pc = memread(v) | (memread((v & 0xFF00) | (u8int)(v+1)) << 8); return; case 0x6D: adc(abso()); return; case 0x6E: ror(fetch16()); return; case 0x70: if((rP & FLAGV) != 0) branch(); else fetch8(); return; case 0x71: adc(indY()); return; case 0x75: adc(zpX()); return; case 0x76: ror(azpX(rX)); return; case 0x78: rP |= FLAGI; memread(pc); return; case 0x79: adc(absY()); return; case 0x7D: adc(absX()); return; case 0x7E: ror(aabsX(rX, 1)); return; case 0x81: memwrite(aindX(), rA); return; case 0x84: memwrite(fetch8(), rY); return; case 0x85: memwrite(fetch8(), rA); return; case 0x86: memwrite(fetch8(), rX); return; case 0x88: nz(--rY); memread(pc); return; case 0x8A: nz(rA = rX); memread(pc); return; case 0x8C: memwrite(fetch16(), rY); return; case 0x8D: memwrite(fetch16(), rA); return; case 0x8E: memwrite(fetch16(), rX); return; case 0x90: if((rP & FLAGC) == 0) branch(); else fetch8(); return; case 0x91: memwrite(aindY(1), rA); return; case 0x94: memwrite(azpX(rX), rY); return; case 0x95: memwrite(azpX(rX), rA); return; case 0x96: memwrite(azpX(rY), rX); return; case 0x98: nz(rA = rY); memread(pc); return; case 0x99: memwrite(aabsX(rY, 1), rA); return; case 0x9A: rS = rX; memread(pc); return; case 0x9D: memwrite(aabsX(rX, 1), rA); return; case 0xA0: nz(rY = imm()); return; case 0xA1: nz(rA = indX()); return; case 0xA2: nz(rX = imm()); return; case 0xA4: nz(rY = zp()); return; case 0xA5: nz(rA = zp()); return; case 0xA6: nz(rX = zp()); return; case 0xA8: nz(rY = rA); memread(pc); return; case 0xA9: nz(rA = imm()); return; case 0xAA: nz(rX = rA); memread(pc); return; case 0xAC: nz(rY = abso()); return; case 0xAE: nz(rX = abso()); return; case 0xAD: nz(rA = abso()); return; case 0xB0: if((rP & FLAGC) != 0) branch(); else fetch8(); return; case 0xB1: nz(rA = indY()); return; case 0xB4: nz(rY = zpX()); return; case 0xB5: nz(rA = zpX()); return; case 0xB6: nz(rX = zpY()); return; case 0xB8: rP &= ~FLAGV; memread(pc); return; case 0xB9: nz(rA = absY()); return; case 0xBA: nz(rX = rS); memread(pc); return; case 0xBC: nz(rY = absX()); return; case 0xBD: nz(rA = absX()); return; case 0xBE: nz(rX = absY()); return; case 0xC1: cmp(rA, indX()); return; case 0xC5: cmp(rA, zp()); return; case 0xC9: cmp(rA, imm()); return; case 0xCD: cmp(rA, abso()); return; case 0xD0: if((rP & FLAGZ) == 0) branch(); else fetch8(); return; case 0xD1: cmp(rA, indY()); return; case 0xD5: cmp(rA, zpX()); return; case 0xD8: rP &= ~FLAGD; memread(pc); return; case 0xD9: cmp(rA, absY()); return; case 0xDD: cmp(rA, absX()); return; case 0xC0: cmp(rY, imm()); return; case 0xC4: cmp(rY, zp()); return; case 0xC6: dec(fetch8()); return; case 0xC8: nz(++rY); memread(pc); return; case 0xCA: nz(--rX); memread(pc); return; case 0xCC: cmp(rY, abso()); return; case 0xCE: dec(fetch16()); return; case 0xD6: dec(azpX(rX)); return; case 0xDE: dec(aabsX(rX, 1)); return; case 0xE0: cmp(rX, imm()); return; case 0xE1: sbc(indX()); return; case 0xE4: cmp(rX, zp()); return; case 0xE5: sbc(zp()); return; case 0xE6: inc(fetch8()); return; case 0xE8: nz(++rX); memread(pc); return; case 0xE9: sbc(imm()); return; case 0xEA: memread(pc); return; case 0xEC: cmp(rX, abso()); return; case 0xED: sbc(abso()); return; case 0xEE: inc(fetch16()); return; case 0xF0: if((rP & FLAGZ) != 0) branch(); else fetch8(); return; case 0xF1: sbc(indY()); return; case 0xF5: sbc(zpX()); return; case 0xF6: inc(azpX(rX)); return; case 0xF8: rP |= FLAGD; memread(pc); return; case 0xF9: sbc(absY()); return; case 0xFD: sbc(absX()); return; case 0xFE: inc(aabsX(rX, 1)); return; default: fprintf(stderr, "undefined %#x (pc %#x)\n", op, curpc); return; } } int ppux, ppuy; u8int pic[PICW*PICH*4*9]; int col, pri; u8int p0x, p1x, m0x, m1x, blx; u16int coll; u8int disp; enum { SRCPF, SRCP0, SRCP1, SRCM0, SRCM1, SRCBL, }; void pixeldraw(u8int v) { u32int c; union { u32int l; u32int c[4]; } u; u32int *p; static u32int col[] = { 0x000000, 0x404040, 0x6C6C6C, 0x909090, 0xB0B0B0, 0xC8C8C8, 0xDCDCDC, 0xECECEC, 0x444400, 0x646410, 0x848424, 0xA0A034, 0xB8B840, 0xD0D050, 0xE8E85C, 0xFCFC68, 0x702800, 0x844414, 0x985C28, 0xAC783C, 0xBC8C4C, 0xCCA05C, 0xDCB468, 0xECC878, 0x841800, 0x983418, 0xAC5030, 0xC06848, 0xD0805C, 0xE09470, 0xECA880, 0xFCBC94, 0x880000, 0x9C2020, 0xB03C3C, 0xC05858, 0xD07070, 0xE08888, 0xECA0A0, 0xFCB4B4, 0x78005C, 0x8C2074, 0xA03C88, 0xB0589C, 0xC070B0, 0xD084C0, 0xDC9CD0, 0xECB0E0, 0x480078, 0x602090, 0x783CA4, 0x8C58B8, 0xA070CC, 0xB484DC, 0xC49CEC, 0xD4B0FC, 0x140084, 0x302098, 0x4C3CAC, 0x6858C0, 0x7C70D0, 0x9488E0, 0xA8A0EC, 0xBCB4FC, 0x000088, 0x1C209C, 0x3840B0, 0x505CC0, 0x6874D0, 0x7C8CE0, 0x90A4EC, 0xA4B8FC, 0x00187C, 0x1C3890, 0x3854A8, 0x5070BC, 0x6888CC, 0x7C9CDC, 0x90B4EC, 0xA4C8FC, 0x002C5C, 0x1C4C78, 0x386890, 0x5084AC, 0x689CC0, 0x7CB4D4, 0x90CCE8, 0xA4E0FC, 0x003C2C, 0x1C5C48, 0x387C64, 0x509C80, 0x68B494, 0x7CD0AC, 0x90E4C0, 0xA4FCD4, 0x003C00, 0x205C20, 0x407C40, 0x5C9C5C, 0x74B474, 0x8CD08C, 0xA4E4A4, 0xB8FCB8, 0x143800, 0x345C1C, 0x507C38, 0x6C9850, 0x84B468, 0x9CCC7C, 0xB4E490, 0xC8FCA4, 0x2C3000, 0x4C501C, 0x687034, 0x848C4C, 0x9CA864, 0xB4C078, 0xCCD488, 0xE0EC9C, 0x442800, 0x644818, 0x846830, 0xA08444, 0xB89C58, 0xD0B46C, 0xE8CC7C, 0xFCE08C, }; c = col[v >> 1]; u.c[0] = c; u.c[1] = c >> 8; u.c[2] = c >> 16; u.c[3] = 0xff; p = (u32int *) &pic[ppuy * PICW * 4 * 2 * 2 + ppux * 4 * 4]; p[0] = u.l; p[1] = u.l; p[2] = u.l; p[3] = u.l; p[640] = u.l; p[641] = u.l; p[642] = u.l; p[643] = u.l; } static void pixel(u8int v, int p, int s) { if(p > pri){ col = v; pri = p; } disp |= 1<= 20) if((reg[CTRLPF] & 1) != 0) x = 39 - x; else x = x - 20; if(x < 4){ if((reg[PF0] & 0x10<>x) == 0) return; }else if((reg[PF2] & 1<= 8) return; break; case 1: if(x >= 8 && (x < 16 || x >= 24)) return; break; case 2: if(x >= 8 && (x < 32 || x >= 40)) return; break; case 3: if(x >= 40 || ((x & 15) >= 8)) return; break; case 4: if(x >= 8 && (x < 64 || x >= 72)) return; break; case 5: if(x >= 16) return; x >>= 1; break; case 6: if(x >= 72 || ((x & 31) >= 8)) return; break; case 7: if(x >= 32) return; x >>= 2; break; } x &= 7; if((reg[REFP0 + n] & 8) == 0) x ^= 7; if((c & 1<= 1<<(reg[NUSIZ0] >> 4 & 3) || (reg[ENAM0 + n] & 2) == 0) return; pixel(reg[COLUP0 + n], 3 - n, SRCM0 + n); } static void ball(void) { int x; x = ppux - blx; if(x < 0 || x >= 1<<(reg[CTRLPF] >> 4 & 3) || (reg[ENABL] & 2) == 0) return; pixel(reg[COLUPF], (reg[CTRLPF] & 4) + 1, SRCBL); } void tiastep(void) { static u16int colltab[64] = { 0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0080, 0x8000, 0x80a0, 0x0000, 0x0200, 0x0001, 0x0221, 0x0002, 0x0282, 0x8003, 0x82a3, 0x0000, 0x0800, 0x0008, 0x0828, 0x0004, 0x0884, 0x800c, 0x88ac, 0x4000, 0x4a00, 0x4009, 0x4a29, 0x4006, 0x4a86, 0xc00f, 0xcaaf, 0x0000, 0x2000, 0x0010, 0x2030, 0x0040, 0x20c0, 0x8050, 0xa0f0, 0x0100, 0x2300, 0x0111, 0x2331, 0x0142, 0x23c2, 0x8153, 0xa3f3, 0x0400, 0x2c00, 0x0418, 0x2c38, 0x0444, 0x2cc4, 0x845c, 0xacfc, 0x4500, 0x6f00, 0x4519, 0x6f39, 0x4546, 0x6fc6, 0xc55f, 0xefff, }; if(ppuy < PICH && ppux < 160){ col = reg[COLUBK]; pri = 0; disp = 0; playfield(); player(0); player(1); missile(0); missile(1); ball(); coll |= colltab[disp]; pixeldraw(col); } if(ppux == 160) nrdy = 0; if(++ppux == 228){ ppuy++; ppux = 0; } } int sdiv[2], fdiv[2], cdiv[2], ch[2], sr[2] = {-1,-1}; #define div(n) if(++cdiv[i] < n) break; cdiv[i] = 0 short sbuf[2000*2], *sbufp; static void channel(int i) { sdiv[i] += HZ/114; for(; sdiv[i] >= RATE; sdiv[i] -= RATE) if(fdiv[i] >= (reg[AUDF0 + i] & 31)){ fdiv[i] = 0; switch(reg[AUDC0 + i] & 15){ case 0: ch[i] = 1; break; case 2: div(15); case 1: ch[i] = sr[i] & 1; sr[i] = sr[i] >> 1 & 7 | (sr[i] << 2 ^ sr[i] << 3) & 8; break; case 4: case 5: ch[i] ^= 1; break; case 12: case 13: div(3); ch[i] ^= 1; break; case 6: case 10: div(16); ch[i] ^= 1; break; case 14: div(46); ch[i] ^= 1; break; case 15: div(6); case 7: case 9: ch[i] = sr[i] & 1; sr[i] = sr[i] >> 1 & 15 | (sr[i] << 2 ^ sr[i] << 4) & 16; break; case 8: ch[i] = sr[i] & 1; sr[i] = sr[i] >> 1 & 255 | (sr[i] << 4 ^ sr[i] << 8) & 256; break; case 3: ch[i] = sr[i] & 1; sr[i] = sr[i] & 15 | sr[i] >> 1 & 240 | (sr[i] << 2 ^ sr[i] << 3) & 256; if((sr[i] & 256) != 0) sr[i] = sr[i] & 496 | sr[i] >> 1 & 7 | (sr[i] << 2 ^ sr[i]) << 3 & 8; break; } }else fdiv[i]++; } void sample(void) { int d; if(sbufp == NULL) return; channel(0); channel(1); d = ch[0] * (reg[AUDV0] & 15) + ch[1] * (reg[AUDV1] & 15); if(sbufp < sbuf + sizeof(sbuf)/2 - 1){ *sbufp++ = d * 1000; *sbufp++ = d * 1000; } } SDL_mutex *olock; SDL_cond *ofull, *oempty; short obuf[2*4096]; int obufr, obufw; #define obufn (sizeof(obuf)/2) void audiocall(void *v, u8int *s, int len) { int i; SDL_LockMutex(olock); for(i = 0; i < len / 2; i++){ if(obufr == obufw) SDL_CondWait(oempty, olock); *s++ = obuf[obufr]; *s++ = obuf[obufr] >> 8; if((obufw + 1) % obufn == obufr) SDL_CondSignal(ofull); obufr = (obufr + 1) % obufn; } SDL_UnlockMutex(olock); } int audioout(void) { int n; short *p; if(sbufp == NULL) return -1; if(sbufp == sbuf) return 0; SDL_LockMutex(olock); for(p = sbuf; p < sbufp; p++){ n = (obufw + 1) % obufn; if(n == obufr) SDL_CondWait(ofull, olock); obuf[obufw] = *p; if(obufr == obufw) SDL_CondSignal(oempty); obufw = n; } sbufp = sbuf; SDL_UnlockMutex(olock); return 0; } extern u8int rom[4096]; u8int ram[128], reg[64]; u8int timer, timerun, timerspeed; u16int timerpre; u8int grp0d, grp1d, enabld; int keys; u8int tiaread(u8int a) { if(a < 8) return coll >> (a << 1 & 14) << 6; if(a == 0xc) return ~keys << 3 & 0x80; return 0x80; } void tiawrite(u8int a, u8int v) { switch(a){ case VSYNC: if((v & 2) != 0) flush(); return; case VBLANK: if((v & 1) == 0) ppuy = 0; break; case WSYNC: nrdy = 1; break; case RESP0: p0x = ppux >= 160 ? 3 : ppux+1; break; case RESP1: p1x = ppux >= 160 ? 3 : ppux+1; break; case RESM0: m0x = ppux >= 160 ? 2 : ppux+1; break; case RESM1: m1x = ppux >= 160 ? 2 : ppux+1; break; case RESBL: blx = ppux >= 160 ? 2 : ppux+1; break; case HMOVE: p0x = (p0x - ((s8int) reg[HMP0] >> 4)) % 160; p1x = (p1x - ((s8int) reg[HMP1] >> 4)) % 160; m0x = (m0x - ((s8int) reg[HMM0] >> 4)) % 160; m1x = (m1x - ((s8int) reg[HMM1] >> 4)) % 160; blx = (blx - ((s8int) reg[HMBL] >> 4)) % 160; break; case HMCLR: reg[HMP0] = reg[HMP1] = reg[HMM0] = reg[HMM1] = reg[HMBL] = 0; break; case GRP0: if((reg[VDELP1] & 1) != 0) reg[GRP1] = grp1d; if((reg[VDELP0] & 1) != 0){ grp0d = v; return; } break; case GRP1: if((reg[VDELP0] & 1) != 0) reg[GRP0] = grp0d; if((reg[VDELBL] & 1) != 0) reg[ENABL] = enabld; if((reg[VDELP1] & 1) != 0){ grp1d = v; return; } break; case ENABL: if((reg[VDELBL] & 1) != 0){ enabld = v; return; } break; case CXCLR: coll = 0; break; } reg[a] = v; } u8int ioread(u8int a) { u8int v; switch(a){ case 0: return ~(keys << 4); case 2: return keys >> 5 ^ 3 | 1<<3; case 4: timerspeed = 0; return timer; case 5: v = timerun; timerun &= ~(1<<6); return v; } return 0; } void iowrite(u8int a, u8int v) { switch(a){ case 4: timerpre = 1; goto timer; case 5: timerpre = 8; goto timer; case 6: timerpre = 64; goto timer; case 7: timerpre = 1024; timer: timerun &= ~(1<<7); timerspeed = v == 0; timer = v - 1; break; } } u8int memread(u16int a) { u8int v; if((a & 0x1000) != 0) v = rom[a & 0xfff]; else if((a & 1<<7) == 0) v = tiaread(a & 0xf); else if((a & 1<<9) == 0) v = ram[a & 0x7f]; else v = ioread(a & 7); io(); return v; } void memwrite(u16int a, u8int v) { if((a & 0x1000) != 0) ; else if((a & 1<<7) == 0) tiawrite(a & 0x3f, v); else if((a & 1<<9) == 0) ram[a & 0x7f] = v; else iowrite(a & 7, v); io(); } void timerstep(void) { static int cl; cl++; if((timerspeed || (cl & timerpre - 1) == 0) && timer-- == 0){ timerspeed = 1; timerun |= 3<<6; } } void io(void) { static int snddiv; timerstep(); tiastep(); tiastep(); tiastep(); if(++snddiv == SAMPDIV){ snddiv = 0; sample(); } } SDL_Surface *scr; int main() { SDL_AudioSpec spec; if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0){ fprintf(stderr, "SDL_Init: %s\n", SDL_GetError()); return 1; } scr = SDL_SetVideoMode(640, 480, 32, 0); if(scr == NULL){ fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError()); return 1; } memset(&spec, 0, sizeof(spec)); spec.freq = 44100; spec.format = AUDIO_S16; spec.channels = 2; spec.samples = 1024; spec.callback = audiocall; if(SDL_OpenAudio(&spec, NULL) >= 0){ sbufp = sbuf; olock = SDL_CreateMutex(); ofull = SDL_CreateCond(); oempty = SDL_CreateCond(); SDL_PauseAudio(0); } pc = memread(0xFFFC) | memread(0xFFFD) << 8; rP = FLAGI; for(;;) step(); } void flush(void) { SDL_Event ev; static u32int old; u32int newt; int diff; SDL_LockSurface(scr); memcpy((u8int*)scr->pixels + (480 - PICH*2) * PICW * 4, pic, PICW*PICH*4*4); SDL_UnlockSurface(scr); SDL_UpdateRect(scr, 0, 0, 0, 0); while(SDL_PollEvent(&ev)) switch(ev.type){ case SDL_QUIT: SDL_Quit(); exit(0); case SDL_KEYDOWN: switch(ev.key.keysym.sym){ case SDLK_UP: keys |= 1<<0; break; case SDLK_DOWN: keys |= 1<<1; break; case SDLK_LEFT: keys |= 1<<2; break; case SDLK_RIGHT: keys |= 1<<3; break; case SDLK_RETURN: keys |= 1<<5; break; case SDLK_TAB: keys |= 1<<6; break; case ' ': keys |= 1<<4; break; } break; case SDL_KEYUP: switch(ev.key.keysym.sym){ case SDLK_ESCAPE: SDL_Quit(); exit(0); case SDLK_UP: keys &= ~(1<<0); break; case SDLK_DOWN: keys &= ~(1<<1); break; case SDLK_LEFT: keys &= ~(1<<2); break; case SDLK_RIGHT: keys &= ~(1<<3); break; case SDLK_RETURN: keys &= ~(1<<5); break; case SDLK_TAB: keys &= ~(1<<6); break; case ' ': keys &= ~(1<<4); break; } break; } if(audioout() < 0){ newt = SDL_GetTicks(); if(old != 0){ diff = 1000/60 - (newt - old); if(diff >= 1) SDL_Delay(diff); } old = newt; } } /* The code below is SPACE INVADERS, Copyright 1980 Atari, Inc. */ u8int rom[4096] = { 0x85, 0x2b, 0xa5, 0x84, 0x30, 0x00, 0x29, 0x0f, 0xaa, 0xca, 0x10, 0xfd, 0xb1, 0xf8, 0xaa, 0xb1, 0xee, 0x85, 0x1b, 0xb1, 0xf0, 0x85, 0x1c, 0xb1, 0xf2, 0x85, 0x1b, 0xb1, 0xf4, 0x85, 0x1c, 0xb1, 0xf6, 0x85, 0x1b, 0x8a, 0x85, 0x1c, 0x85, 0x1b, 0xc6, 0x89, 0x88, 0x48, 0x68, 0x48, 0x68, 0xb1, 0xf8, 0xaa, 0xb1, 0xee, 0x85, 0x1b, 0xb1, 0xf0, 0x85, 0x1c, 0xb1, 0xf2, 0x85, 0x1b, 0xb1, 0xf4, 0x85, 0x1c, 0xb1, 0xf6, 0x85, 0x1b, 0x8a, 0x85, 0x1c, 0x85, 0x1b, 0xa5, 0x89, 0xc9, 0x04, 0x90, 0x04, 0xa9, 0x00, 0xb0, 0x03, 0xea, 0xa9, 0x02, 0x8d, 0x1f, 0x00, 0x88, 0x10, 0xae, 0xc8, 0x84, 0x1b, 0x84, 0x1c, 0x84, 0x2b, 0x84, 0x1b, 0x84, 0x1c, 0x85, 0x02, 0xc6, 0x89, 0xa5, 0x89, 0xc9, 0x04, 0x90, 0x04, 0xa9, 0x00, 0xb0, 0x03, 0xea, 0xa9, 0x02, 0x85, 0x1f, 0xa4, 0x80, 0xa5, 0x02, 0x05, 0x03, 0x0a, 0x30, 0x06, 0xea, 0xea, 0xea, 0xea, 0x10, 0x07, 0xa5, 0x82, 0x19, 0xdc, 0xfc, 0x85, 0x82, 0x85, 0x2c, 0x88, 0xc6, 0x8c, 0x10, 0x09, 0xa9, 0x00, 0x85, 0x25, 0x85, 0x26, 0x4c, 0x09, 0xf1, 0x20, 0xe9, 0xfd, 0x84, 0x80, 0xb9, 0x92, 0x00, 0x85, 0xf8, 0xa2, 0xf4, 0x46, 0xf8, 0x90, 0x07, 0xb9, 0xd6, 0xfc, 0x65, 0x8b, 0xd0, 0x04, 0x48, 0x68, 0xa9, 0x00, 0x95, 0xfa, 0xe8, 0xe8, 0x30, 0xeb, 0xc6, 0x89, 0xa5, 0x89, 0xc9, 0x04, 0x90, 0x04, 0xa9, 0x00, 0xb0, 0x03, 0xea, 0xa9, 0x02, 0x85, 0x1f, 0xa5, 0xc8, 0x29, 0x38, 0x4a, 0x4a, 0x4a, 0xc5, 0x80, 0xd0, 0x16, 0xa5, 0xc8, 0x29, 0x07, 0x0a, 0xaa, 0xa5, 0xc8, 0x2a, 0x2a, 0x2a, 0x29, 0x03, 0xa8, 0xb9, 0x1e, 0xfd, 0x95, 0xee, 0x4c, 0xfa, 0xf0, 0xa2, 0x05, 0xca, 0x10, 0xfd, 0x85, 0x2b, 0x20, 0xb2, 0xfd, 0xa2, 0x06, 0xca, 0x10, 0xfd, 0xa0, 0x09, 0x4c, 0x00, 0xf0, 0xc6, 0x8e, 0x30, 0x06, 0x20, 0xb2, 0xfd, 0x4c, 0x09, 0xf1, 0x24, 0x98, 0x70, 0x03, 0x4c, 0xb2, 0xf1, 0xa5, 0xdd, 0x85, 0x06, 0xa9, 0x01, 0x85, 0x8e, 0xa9, 0x00, 0x85, 0xef, 0x85, 0xf1, 0x85, 0xf3, 0xa9, 0xab, 0x85, 0xee, 0xa9, 0xb4, 0x85, 0xf0, 0xa9, 0xbd, 0x85, 0xf2, 0xa9, 0x11, 0x85, 0x02, 0x85, 0x2b, 0x85, 0xf4, 0xa5, 0x85, 0x85, 0x20, 0x29, 0x0f, 0xa8, 0x88, 0x10, 0xfd, 0x85, 0x10, 0xc6, 0x89, 0xa5, 0x89, 0xc9, 0x04, 0xa9, 0x02, 0x90, 0x01, 0x4a, 0x85, 0x1f, 0x85, 0x02, 0x85, 0x2a, 0xa0, 0x00, 0xa5, 0x85, 0x10, 0x02, 0xa5, 0x85, 0x29, 0x0f, 0xaa, 0xca, 0xca, 0xca, 0x10, 0xfd, 0xb1, 0xee, 0x85, 0x1b, 0xea, 0xb1, 0xf0, 0x85, 0x1b, 0xb1, 0xf2, 0x85, 0x1b, 0xc6, 0xf4, 0x30, 0x12, 0xa5, 0xf4, 0x4a, 0x90, 0x08, 0xc8, 0xa9, 0x20, 0x4a, 0xd0, 0xfd, 0xf0, 0xe2, 0x20, 0xe9, 0xfd, 0x10, 0xdd, 0xa9, 0x00, 0x85, 0x1b, 0x85, 0x02, 0xa5, 0x02, 0x0a, 0x29, 0x80, 0x05, 0x82, 0x85, 0x82, 0x85, 0x2c, 0x20, 0xe9, 0xfd, 0x85, 0x2b, 0x85, 0x02, 0x85, 0x02, 0xc6, 0x8e, 0x30, 0x06, 0x20, 0xb2, 0xfd, 0x4c, 0xa8, 0xf1, 0x24, 0x98, 0x10, 0x03, 0x4c, 0x82, 0xf2, 0x20, 0xe9, 0xfd, 0x85, 0x2b, 0x85, 0x02, 0xa5, 0xdf, 0x85, 0x06, 0xa5, 0x86, 0x85, 0x20, 0x29, 0x0f, 0xa8, 0x88, 0x10, 0xfd, 0x85, 0x10, 0x85, 0x02, 0xa5, 0xe0, 0x85, 0x07, 0xa5, 0x87, 0x85, 0x21, 0x29, 0x0f, 0xa8, 0x88, 0x10, 0xfd, 0x85, 0x11, 0x85, 0x02, 0x85, 0x2a, 0x20, 0xe9, 0xfd, 0xa9, 0x00, 0x2c, 0x82, 0x02, 0x10, 0x02, 0xa9, 0x05, 0x85, 0x05, 0xa9, 0x00, 0x50, 0x02, 0xa9, 0x05, 0x85, 0x04, 0xa5, 0x98, 0x29, 0x10, 0xf0, 0x02, 0xa9, 0x0a, 0x85, 0xf4, 0xa5, 0x98, 0x29, 0x20, 0xf0, 0x02, 0xa9, 0x0a, 0x85, 0xf6, 0xa5, 0xaa, 0x4a, 0x85, 0x02, 0x90, 0x17, 0xa6, 0xc9, 0xbd, 0x16, 0xfd, 0x85, 0xf8, 0xa9, 0xff, 0x85, 0xf9, 0xa5, 0xca, 0x29, 0x08, 0xd0, 0x04, 0x85, 0xf4, 0x85, 0xf6, 0x10, 0x25, 0xa9, 0x00, 0x85, 0xf8, 0xa5, 0xca, 0x4a, 0x4a, 0x4a, 0xa5, 0xaa, 0x29, 0x04, 0xf0, 0x08, 0xa9, 0x1e, 0xb0, 0x02, 0xa9, 0x14, 0x85, 0xf4, 0xa5, 0xaa, 0x29, 0x02, 0xf0, 0x08, 0xa9, 0x14, 0xb0, 0x02, 0xa9, 0x1e, 0x85, 0xf6, 0xa2, 0x09, 0xa0, 0x09, 0x85, 0x02, 0xa9, 0x00, 0x85, 0x0d, 0xb1, 0xf4, 0x85, 0x1b, 0xb1, 0xf6, 0x85, 0x1c, 0x8a, 0x4a, 0xa8, 0xb1, 0xf8, 0x85, 0x0d, 0x8a, 0x4a, 0x90, 0x0d, 0xc6, 0x89, 0xa5, 0x89, 0xc9, 0x04, 0xa9, 0x02, 0x90, 0x01, 0x4a, 0x85, 0x1f, 0xca, 0x8a, 0xa8, 0x10, 0xd5, 0x85, 0x02, 0xa9, 0x00, 0x85, 0x04, 0x85, 0x05, 0x85, 0x0d, 0x85, 0x1f, 0x85, 0x1b, 0x85, 0x1c, 0xa5, 0xe4, 0x85, 0x09, 0xa5, 0x81, 0x85, 0x10, 0xa2, 0x04, 0xca, 0x10, 0xfd, 0x85, 0x11, 0x85, 0x2b, 0xa9, 0xe0, 0x85, 0x21, 0x85, 0x02, 0x85, 0x2a, 0xa9, 0xc0, 0x85, 0x1b, 0x85, 0x1c, 0xa2, 0x04, 0xa9, 0x00, 0x95, 0xf3, 0xca, 0xd0, 0xfb, 0x20, 0x08, 0xfe, 0xe8, 0x20, 0x08, 0xfe, 0xa5, 0xaa, 0x29, 0x81, 0xd0, 0x2f, 0x24, 0x02, 0x50, 0x06, 0xa9, 0x04, 0x24, 0xaa, 0xf0, 0x0b, 0xca, 0x24, 0x03, 0x50, 0x20, 0xa9, 0x02, 0x24, 0xaa, 0xd0, 0x1a, 0x05, 0xaa, 0x85, 0xaa, 0x85, 0xc6, 0x20, 0x75, 0xfe, 0xa9, 0x06, 0x20, 0x7e, 0xfe, 0xa5, 0xc7, 0xd0, 0x08, 0x24, 0xdb, 0x50, 0x04, 0xa9, 0x02, 0x95, 0xf4, 0x85, 0x02, 0xad, 0x84, 0x02, 0xd0, 0xfb, 0x85, 0x1b, 0x85, 0x1c, 0xa9, 0xc8, 0x8d, 0x95, 0x02, 0xa9, 0x00, 0x85, 0xf1, 0xaa, 0xa5, 0x82, 0x10, 0x5f, 0xa5, 0xca, 0x4a, 0x90, 0x02, 0xa2, 0x04, 0xb5, 0xd1, 0xc9, 0x49, 0x90, 0x04, 0xc9, 0x58, 0x90, 0x01, 0xe8, 0xe0, 0x03, 0x90, 0x0c, 0xa9, 0x09, 0x85, 0xef, 0xa9, 0xff, 0x85, 0xf2, 0xa9, 0x7f, 0xd0, 0x0a, 0xa9, 0xff, 0x85, 0xef, 0xa9, 0x01, 0x85, 0xf2, 0xa9, 0xf6, 0x95, 0xd1, 0xb5, 0xd3, 0xa0, 0x03, 0x18, 0xe5, 0x9b, 0x88, 0x18, 0x69, 0xe0, 0x10, 0xfa, 0x69, 0x20, 0xaa, 0xb9, 0x13, 0xfd, 0x85, 0xf0, 0xa4, 0xef, 0x98, 0x18, 0x65, 0xf2, 0xa8, 0xbd, 0x4c, 0xff, 0x49, 0xff, 0x31, 0xf0, 0xf0, 0xf2, 0x20, 0x8f, 0xfd, 0x88, 0x20, 0x8b, 0xfd, 0xc8, 0xc8, 0x20, 0x8b, 0xfd, 0xa5, 0xca, 0x4a, 0xb0, 0x03, 0x4c, 0x29, 0xf4, 0x24, 0x82, 0x50, 0x26, 0xa5, 0xc8, 0x29, 0x39, 0xc9, 0x39, 0xf0, 0x1e, 0xa9, 0x39, 0x85, 0xc8, 0xa2, 0x01, 0xa5, 0x98, 0x29, 0x04, 0xd0, 0x01, 0xca, 0xa9, 0x04, 0x85, 0xc6, 0x4a, 0x24, 0xdb, 0x50, 0x01, 0x4a, 0x95, 0xf4, 0xa9, 0x05, 0x20, 0x8b, 0xfe, 0xa9, 0x06, 0x85, 0xf0, 0xc6, 0xf0, 0x10, 0x03, 0x4c, 0xcf, 0xf4, 0xa6, 0xf0, 0xa5, 0x82, 0x3d, 0xdc, 0xfc, 0xf0, 0xf0, 0xa0, 0x01, 0xa9, 0x35, 0x38, 0xfd, 0x31, 0xfd, 0x18, 0x65, 0x90, 0xc9, 0x52, 0xb0, 0x63, 0xc5, 0xd5, 0xb0, 0x07, 0x69, 0x0d, 0xc5, 0xd5, 0x90, 0x01, 0x88, 0x84, 0xee, 0xa6, 0xee, 0xa0, 0xff, 0xa5, 0x9a, 0x18, 0x69, 0xfd, 0xc8, 0x69, 0x10, 0xd5, 0xd7, 0x90, 0xf9, 0x84, 0xef, 0xa6, 0xf0, 0xb9, 0xdc, 0xfc, 0x35, 0x92, 0xf0, 0x3b, 0x55, 0x92, 0x95, 0x92, 0xa4, 0xee, 0xb9, 0xde, 0xfc, 0xa0, 0x01, 0x25, 0x98, 0xd0, 0x01, 0x88, 0xbd, 0x2b, 0xfd, 0x99, 0xf6, 0x00, 0xa9, 0x02, 0x20, 0x7e, 0xfe, 0xc6, 0x91, 0xd0, 0x0a, 0xa5, 0xaa, 0x09, 0x08, 0x85, 0xaa, 0xa9, 0x61, 0x85, 0xca, 0x20, 0xed, 0xfb, 0x8a, 0x0a, 0x0a, 0x0a, 0x05, 0xef, 0x85, 0xc8, 0xa9, 0xf6, 0xa4, 0xee, 0x99, 0xd5, 0x00, 0x4c, 0xa4, 0xf3, 0x4a, 0xb0, 0x2d, 0xa5, 0xc8, 0x29, 0x39, 0xc9, 0x39, 0xf0, 0x25, 0xa5, 0x9e, 0xc9, 0xb4, 0xf0, 0x1f, 0xa5, 0x98, 0x4a, 0xb0, 0x06, 0xc6, 0x9e, 0xd0, 0x16, 0xf0, 0x08, 0xe6, 0x9e, 0xa5, 0x9e, 0xc9, 0x98, 0x90, 0x0c, 0xa9, 0xb4, 0x85, 0x9e, 0xa9, 0x00, 0x85, 0xcc, 0xa9, 0x04, 0x85, 0xc6, 0xad, 0x80, 0x02, 0xa8, 0x0a, 0x0a, 0x0a, 0x0a, 0x85, 0xee, 0x29, 0x80, 0x85, 0x81, 0xa5, 0xdb, 0xc9, 0x90, 0xd0, 0x08, 0x24, 0xaa, 0x50, 0x0e, 0xa4, 0xee, 0x70, 0x0a, 0x29, 0x02, 0xf0, 0x06, 0x98, 0x29, 0x40, 0x05, 0x81, 0xa8, 0xa2, 0x01, 0xa5, 0xaa, 0x3d, 0x60, 0xfd, 0xd0, 0x18, 0x24, 0xee, 0x30, 0x02, 0xf6, 0x9c, 0x70, 0x02, 0xd6, 0x9c, 0xb5, 0x9c, 0xc9, 0x76, 0x90, 0x02, 0xd6, 0x9c, 0xc9, 0x23, 0xb0, 0x02, 0xf6, 0x9c, 0x84, 0xee, 0xca, 0x10, 0xdc, 0xa5, 0xca, 0x4a, 0x4a, 0x4a, 0xb0, 0x23, 0xa5, 0xdc, 0x4a, 0x90, 0x1e, 0xa5, 0xaa, 0x29, 0x10, 0xf0, 0x0a, 0xe6, 0x9b, 0xa5, 0x9b, 0xc9, 0x35, 0x90, 0x10, 0xb0, 0x08, 0xc6, 0x9b, 0xa5, 0x9b, 0xc9, 0x21, 0xb0, 0x06, 0xa5, 0xaa, 0x49, 0x10, 0x85, 0xaa, 0xad, 0x84, 0x02, 0xd0, 0xfb, 0xa9, 0x02, 0x85, 0x01, 0x85, 0x02, 0x24, 0xaa, 0x30, 0x13, 0xf8, 0xa2, 0x01, 0xb5, 0xe8, 0x18, 0x75, 0xf6, 0x95, 0xe8, 0xb5, 0xe6, 0x75, 0xf4, 0x95, 0xe6, 0xca, 0x10, 0xf0, 0xd8, 0x85, 0x02, 0xa5, 0xca, 0x29, 0x07, 0xd0, 0x12, 0xa5, 0xc8, 0x18, 0x69, 0x40, 0x85, 0xc8, 0xc9, 0x40, 0xb0, 0x07, 0x20, 0xf1, 0xfb, 0xa9, 0x30, 0x85, 0xc8, 0xa9, 0x02, 0x85, 0x02, 0x85, 0x00, 0x85, 0x02, 0x85, 0x02, 0xa9, 0x30, 0x8d, 0x96, 0x02, 0xa9, 0x00, 0x85, 0x02, 0x85, 0x00, 0xa5, 0xca, 0x4a, 0x90, 0x23, 0xa2, 0x01, 0xb5, 0xd5, 0xc9, 0x79, 0xd0, 0x04, 0xa9, 0xf6, 0x95, 0xd5, 0xb5, 0xd5, 0xc9, 0xec, 0xb0, 0x0c, 0xb5, 0xd5, 0x69, 0xfe, 0xc9, 0x03, 0xb0, 0x02, 0xa9, 0xf6, 0x95, 0xd5, 0xca, 0x10, 0xe1, 0x30, 0x59, 0xa5, 0xca, 0x29, 0x0f, 0xc9, 0x0f, 0xf0, 0x05, 0x20, 0xfb, 0xfd, 0x85, 0xda, 0xa5, 0xdc, 0x29, 0x04, 0x4a, 0x4a, 0x4a, 0xa9, 0x01, 0xaa, 0x90, 0x01, 0x0a, 0x85, 0x81, 0xb5, 0xd1, 0xc9, 0xec, 0xb0, 0x34, 0xa5, 0xdc, 0x29, 0x02, 0xf0, 0x1f, 0xa5, 0xda, 0xe0, 0x00, 0xf0, 0x02, 0x0a, 0x0a, 0x0a, 0x90, 0x14, 0x10, 0x0a, 0xb5, 0xd3, 0xc9, 0x81, 0xb0, 0x0c, 0xf6, 0xd3, 0xd0, 0x08, 0xb5, 0xd3, 0xc9, 0x17, 0x90, 0x02, 0xd6, 0xd3, 0xb5, 0xd1, 0x18, 0x65, 0x81, 0x95, 0xd1, 0xc9, 0x6c, 0x90, 0x04, 0xa9, 0xf6, 0x95, 0xd1, 0xca, 0x10, 0xc3, 0xc6, 0xca, 0xf0, 0x03, 0x4c, 0x8c, 0xf6, 0xa5, 0xc7, 0xf0, 0x04, 0xe6, 0xc7, 0xe6, 0xc7, 0x24, 0xe5, 0x30, 0x6d, 0xa5, 0xaa, 0x29, 0x08, 0xf0, 0x2a, 0x45, 0xaa, 0x85, 0xaa, 0xa6, 0x99, 0xbd, 0x0f, 0xfd, 0x85, 0x90, 0xe0, 0x03, 0xb0, 0x02, 0xe6, 0x99, 0x24, 0x98, 0x30, 0x0f, 0x20, 0xfa, 0xfe, 0xa5, 0xaa, 0x29, 0x06, 0xd0, 0x0c, 0xa5, 0xaa, 0x09, 0x01, 0x85, 0xaa, 0xa9, 0x40, 0x85, 0xca, 0xd0, 0x3a, 0x24, 0x98, 0x10, 0x0e, 0x24, 0xa7, 0x30, 0x22, 0xa5, 0xdb, 0xc9, 0x10, 0xd0, 0x1c, 0xa9, 0x00, 0xf0, 0x31, 0xa5, 0xaa, 0x29, 0x01, 0xf0, 0x25, 0x45, 0xaa, 0x85, 0xaa, 0xa9, 0x50, 0x85, 0xd9, 0xa9, 0x05, 0x85, 0xc6, 0xa5, 0xc9, 0xd0, 0x4f, 0xe6, 0xc9, 0xa5, 0xe5, 0x09, 0x80, 0x85, 0xe5, 0xa5, 0xc7, 0xd0, 0x09, 0xa9, 0xbf, 0x85, 0xc7, 0x10, 0x03, 0x4c, 0x89, 0xf6, 0xa5, 0xaa, 0x29, 0x06, 0xf0, 0x40, 0x09, 0x01, 0x45, 0xaa, 0x85, 0xaa, 0xa9, 0x23, 0x85, 0x9c, 0xa9, 0x75, 0x85, 0x9d, 0xa5, 0xdb, 0xc9, 0x10, 0xd0, 0x1e, 0x24, 0xa7, 0x30, 0x1a, 0xa2, 0x0a, 0xb4, 0x90, 0xb5, 0x9f, 0x95, 0x90, 0x94, 0x9f, 0xca, 0x10, 0xf5, 0x20, 0x3a, 0xff, 0xa5, 0xaa, 0x49, 0x40, 0x85, 0xaa, 0x29, 0x40, 0xd0, 0x02, 0xc6, 0xc9, 0xa9, 0x40, 0x85, 0xca, 0xa9, 0xb4, 0x85, 0x9e, 0xa9, 0x00, 0x85, 0xcc, 0xc6, 0xc6, 0xd0, 0x1d, 0xa5, 0x91, 0xc9, 0x07, 0x90, 0x17, 0x20, 0xfb, 0xfd, 0x29, 0x01, 0x45, 0x98, 0x85, 0x98, 0x4a, 0xa9, 0x98, 0x90, 0x02, 0xa9, 0x00, 0x85, 0x9e, 0xa9, 0x04, 0x20, 0x8b, 0xfe, 0x4c, 0x75, 0xf8, 0xa5, 0xca, 0x4a, 0xb0, 0x03, 0x4c, 0xdb, 0xf7, 0xad, 0x82, 0x02, 0x29, 0x03, 0xc9, 0x02, 0xd0, 0x06, 0x20, 0xb2, 0xfe, 0x4c, 0x44, 0xf7, 0xad, 0x82, 0x02, 0x29, 0x02, 0xf0, 0x09, 0xa5, 0xaa, 0x85, 0xed, 0x30, 0x3e, 0x4c, 0x47, 0xf7, 0xa9, 0xb1, 0x85, 0xc7, 0x24, 0xaa, 0x30, 0x0e, 0xa5, 0xaa, 0x29, 0xb0, 0x09, 0x80, 0x85, 0xed, 0x20, 0xc0, 0xfe, 0x4c, 0x44, 0xf7, 0xe6, 0xed, 0xa5, 0xed, 0xc9, 0x0f, 0x90, 0x1d, 0xad, 0x82, 0x02, 0x4a, 0xa9, 0x0d, 0x90, 0x02, 0xa9, 0x02, 0x85, 0xed, 0xa5, 0x98, 0x29, 0xf3, 0x85, 0x98, 0xa5, 0xdc, 0x18, 0x69, 0x91, 0xf0, 0x02, 0x69, 0x70, 0x85, 0xdc, 0xa5, 0xaa, 0x09, 0x80, 0x85, 0xaa, 0xa5, 0xdc, 0x4a, 0x4a, 0x4a, 0x4a, 0x85, 0xec, 0xa8, 0xb9, 0x4b, 0xfd, 0x85, 0xdb, 0xa5, 0x98, 0x29, 0xcf, 0x19, 0x52, 0xfd, 0x85, 0x98, 0xa9, 0xaa, 0x85, 0xe7, 0xa9, 0xa2, 0x85, 0xe9, 0xa0, 0x00, 0x98, 0x38, 0x65, 0xdc, 0xc9, 0x0a, 0x90, 0x06, 0xc8, 0xe9, 0x0a, 0x4c, 0x19, 0xf7, 0x79, 0x39, 0xfd, 0x85, 0xe8, 0xa5, 0xdc, 0xc9, 0x63, 0xa9, 0xaa, 0x90, 0x02, 0xa9, 0xa1, 0x85, 0xe6, 0xa5, 0xdc, 0xc9, 0x10, 0xb0, 0x02, 0xc6, 0xe9, 0xc9, 0x09, 0xb0, 0x04, 0x69, 0xa1, 0x85, 0xe8, 0x4c, 0x75, 0xf8, 0xa5, 0xca, 0x4a, 0xb0, 0x03, 0x4c, 0xdb, 0xf7, 0xa5, 0xc7, 0xd0, 0xf9, 0x24, 0x98, 0x30, 0x12, 0xa5, 0xaa, 0x29, 0x07, 0xd0, 0x0c, 0xa5, 0xdb, 0x29, 0x10, 0xf0, 0x58, 0xa5, 0xd5, 0xc9, 0xec, 0xb0, 0x03, 0x4c, 0xd8, 0xf7, 0xa5, 0xdb, 0xc9, 0x14, 0xf0, 0x08, 0xc9, 0x90, 0xd0, 0x09, 0x24, 0xaa, 0x50, 0x21, 0x24, 0x0d, 0x4c, 0x9d, 0xf7, 0xa5, 0xdb, 0x10, 0x0a, 0xc6, 0xd9, 0xd0, 0x06, 0x24, 0xaa, 0x50, 0x14, 0x70, 0x1e, 0x24, 0xaa, 0x70, 0x16, 0xa5, 0xdb, 0x29, 0x20, 0xf0, 0x04, 0x24, 0x0d, 0x10, 0x04, 0x24, 0x0c, 0x30, 0x39, 0xa5, 0x98, 0x29, 0xfb, 0xa2, 0x00, 0x10, 0x0a, 0x24, 0x0d, 0x30, 0x2d, 0xa2, 0x01, 0xa5, 0x98, 0x09, 0x04, 0x85, 0x98, 0xa0, 0x00, 0x20, 0xaf, 0xfb, 0x4c, 0xd8, 0xf7, 0xa0, 0x01, 0xa2, 0x01, 0xa5, 0x98, 0x39, 0xde, 0xfc, 0xd0, 0x01, 0xca, 0xb9, 0xd5, 0x00, 0xc9, 0xec, 0x90, 0x07, 0xb5, 0x0c, 0x30, 0x03, 0x20, 0xaf, 0xfb, 0x88, 0x10, 0xe5, 0x4c, 0x75, 0xf8, 0xa5, 0xaa, 0x29, 0x07, 0xd0, 0xf7, 0xa8, 0xa5, 0x91, 0xf0, 0xf2, 0xa9, 0xeb, 0x85, 0xee, 0xc5, 0xd2, 0xb0, 0xea, 0x20, 0xfb, 0xfd, 0x10, 0x1a, 0x29, 0x03, 0x0a, 0x85, 0xee, 0xa5, 0xea, 0x4a, 0x4a, 0xaa, 0x8a, 0x38, 0x65, 0xee, 0x29, 0x07, 0xaa, 0xbd, 0xdc, 0xfc, 0x25, 0xeb, 0xf0, 0xf2, 0xd0, 0x2f, 0xa5, 0x98, 0x29, 0x04, 0xf0, 0x01, 0xc8, 0xa2, 0x05, 0xbd, 0xdc, 0xfc, 0x25, 0xeb, 0xf0, 0x10, 0xa5, 0x9a, 0x18, 0x69, 0xfd, 0x18, 0x7d, 0x39, 0xfd, 0xd9, 0x9c, 0x00, 0x90, 0x06, 0x86, 0xee, 0xca, 0x10, 0xe6, 0xe8, 0xa5, 0xea, 0x29, 0x10, 0xd0, 0x05, 0xa5, 0xee, 0x30, 0x01, 0xaa, 0x86, 0xef, 0xbd, 0xdc, 0xfc, 0x85, 0xf0, 0xa2, 0xff, 0xe8, 0xe0, 0x06, 0xb0, 0x2b, 0xb5, 0x92, 0x25, 0xf0, 0xf0, 0xf5, 0xa9, 0x3c, 0x65, 0x90, 0xfd, 0x31, 0xfd, 0x85, 0xd2, 0x38, 0xe5, 0xd1, 0xc9, 0x10, 0x90, 0x11, 0xc9, 0xf1, 0xb0, 0x0d, 0xa4, 0xef, 0xa5, 0x9a, 0x79, 0x39, 0xfd, 0x69, 0x04, 0x85, 0xd4, 0xd0, 0x04, 0xa9, 0xf6, 0x85, 0xd2, 0xa5, 0xaa, 0x29, 0x07, 0xd0, 0x7a, 0x24, 0x98, 0x30, 0x76, 0xa0, 0xff, 0xa5, 0x91, 0xf0, 0x70, 0xc8, 0xd9, 0xe4, 0xfc, 0x90, 0xfa, 0xb9, 0xf6, 0xfc, 0x85, 0xee, 0xb9, 0xed, 0xfc, 0x85, 0xef, 0xa5, 0xca, 0x29, 0x3f, 0x85, 0xf0, 0x18, 0x65, 0xef, 0xc9, 0x41, 0xb0, 0x53, 0xa5, 0xf0, 0xf0, 0x09, 0xc5, 0xef, 0x90, 0x4b, 0xe5, 0xef, 0x4c, 0xa4, 0xf8, 0x24, 0x8b, 0xa9, 0x09, 0x70, 0x02, 0xa9, 0xff, 0x85, 0x8b, 0xa9, 0x01, 0x20, 0x7e, 0xfe, 0xa5, 0x98, 0x29, 0x02, 0xf0, 0x0f, 0xa5, 0x9a, 0x18, 0x65, 0xee, 0x85, 0x9a, 0xc5, 0x8d, 0x90, 0x26, 0xa5, 0x8d, 0xd0, 0x0d, 0xa5, 0x9a, 0x38, 0xe5, 0xee, 0x85, 0x9a, 0xc9, 0x17, 0xb0, 0x17, 0xa9, 0x17, 0x85, 0x9a, 0xa5, 0x98, 0x49, 0x02, 0x85, 0x98, 0x30, 0x0b, 0x24, 0xaa, 0x30, 0x07, 0xa5, 0x90, 0x18, 0x69, 0x05, 0x85, 0x90, 0xa9, 0x05, 0x85, 0x8c, 0xa9, 0x0b, 0x38, 0xe5, 0x90, 0x85, 0x8e, 0x24, 0x98, 0x70, 0x07, 0xa5, 0x8e, 0x18, 0x69, 0x0c, 0x85, 0x8e, 0xa2, 0xfb, 0xb5, 0x97, 0xd0, 0x0c, 0xc6, 0x8c, 0xa5, 0x8e, 0x18, 0x69, 0x09, 0x85, 0x8e, 0xe8, 0xd0, 0xf0, 0xa5, 0x8e, 0x10, 0x31, 0xa5, 0x98, 0x29, 0x40, 0xf0, 0x0d, 0x45, 0x98, 0x85, 0x98, 0xa5, 0x8e, 0x18, 0x69, 0x0c, 0x85, 0x8e, 0x10, 0x1e, 0xa9, 0x00, 0x85, 0x8e, 0xa5, 0x98, 0x30, 0x16, 0x09, 0x80, 0x85, 0x98, 0xa4, 0x8c, 0xa5, 0x90, 0x18, 0x79, 0xf2, 0xff, 0x85, 0x90, 0x20, 0x75, 0xfe, 0xa9, 0x06, 0x20, 0x7e, 0xfe, 0xa2, 0x05, 0xa9, 0x00, 0x15, 0x92, 0xca, 0x10, 0xfb, 0x85, 0xeb, 0xa5, 0xeb, 0xf0, 0x2d, 0x4a, 0xb0, 0x18, 0x20, 0xed, 0xfb, 0xa9, 0x3a, 0x85, 0xc8, 0xa2, 0x05, 0x56, 0x92, 0xca, 0x10, 0xfb, 0xa5, 0x9a, 0x69, 0x10, 0x85, 0x9a, 0x46, 0xeb, 0xd0, 0xe1, 0xa2, 0x06, 0xca, 0xbd, 0xdc, 0xfc, 0x25, 0xeb, 0xf0, 0xf8, 0xa9, 0x82, 0x38, 0xfd, 0x39, 0xfd, 0x85, 0x8d, 0xa5, 0x90, 0x85, 0x8f, 0xa2, 0x04, 0xb5, 0x99, 0x20, 0x67, 0xfd, 0xca, 0xd0, 0xf8, 0xad, 0x82, 0x02, 0x29, 0x08, 0xa8, 0xf0, 0x02, 0xa9, 0xf7, 0x09, 0x07, 0x85, 0xee, 0xa2, 0xf8, 0xb9, 0xff, 0xfc, 0x45, 0xc7, 0x25, 0xee, 0x95, 0xe5, 0xc8, 0xe8, 0x30, 0xf3, 0x24, 0xaa, 0x30, 0x04, 0xa5, 0xc7, 0xd0, 0x12, 0xa5, 0xc8, 0x29, 0x38, 0xc9, 0x30, 0xd0, 0x0a, 0xa5, 0xdc, 0x29, 0x08, 0xf0, 0x04, 0xa5, 0xe3, 0x85, 0xe1, 0xa5, 0xde, 0x85, 0x06, 0xa5, 0xe3, 0x85, 0x09, 0xa5, 0xe2, 0x85, 0x08, 0xa5, 0xca, 0x4a, 0xa2, 0x04, 0xb0, 0x02, 0xa2, 0x00, 0x86, 0xef, 0xb5, 0xd1, 0xd5, 0xd2, 0x90, 0x2b, 0x85, 0x81, 0xb5, 0xd2, 0x95, 0xd1, 0xa5, 0x81, 0x95, 0xd2, 0xb5, 0xd3, 0x85, 0x81, 0xb5, 0xd4, 0x95, 0xd3, 0xa5, 0x81, 0x95, 0xd4, 0xa5, 0xca, 0x4a, 0x90, 0x10, 0xa5, 0x98, 0x29, 0x0c, 0x4a, 0x4a, 0xa8, 0xa5, 0x98, 0x29, 0xf3, 0x19, 0x1a, 0xfd, 0x85, 0x98, 0xb5, 0xd4, 0xa2, 0x05, 0x20, 0x67, 0xfd, 0xa6, 0xef, 0xb5, 0xd1, 0x85, 0x89, 0xb5, 0xd2, 0xc9, 0xec, 0xb0, 0x03, 0x38, 0xf5, 0xd1, 0x85, 0x8a, 0xb5, 0xd3, 0xa2, 0x00, 0x20, 0x67, 0xfd, 0xa2, 0x04, 0x20, 0x7e, 0xfd, 0x85, 0x02, 0x85, 0x2a, 0xad, 0x84, 0x02, 0xd0, 0xfb, 0x85, 0x01, 0x85, 0x2c, 0xa2, 0x00, 0xa9, 0xea, 0x85, 0x02, 0x8d, 0x96, 0x02, 0x85, 0x2b, 0x24, 0xaa, 0x30, 0x09, 0xa5, 0x9e, 0xc9, 0xb4, 0xf0, 0x03, 0x4c, 0x0d, 0xfb, 0xa2, 0x07, 0xa0, 0x03, 0xb9, 0xe6, 0x00, 0x29, 0x0f, 0x85, 0xf0, 0x0a, 0x0a, 0x65, 0xf0, 0x69, 0x54, 0x95, 0xf0, 0xca, 0xb9, 0xe6, 0x00, 0x4a, 0x4a, 0x4a, 0x4a, 0x85, 0xf0, 0x0a, 0x0a, 0x65, 0xf0, 0x69, 0x54, 0x95, 0xf0, 0xca, 0x88, 0x10, 0xdb, 0x85, 0x02, 0xa5, 0xdf, 0x85, 0x06, 0xa9, 0x02, 0x85, 0x0a, 0xa5, 0xe0, 0x85, 0x07, 0xa9, 0x04, 0x85, 0xee, 0xa9, 0xff, 0x85, 0xef, 0xea, 0xea, 0xa2, 0x05, 0xca, 0x10, 0xfd, 0xa4, 0xf0, 0xb1, 0xee, 0x85, 0x0d, 0xa9, 0x00, 0x85, 0x0e, 0xa4, 0xf5, 0xb1, 0xee, 0x4a, 0x4a, 0x4a, 0x4a, 0x85, 0x0f, 0xa4, 0xf2, 0xb1, 0xee, 0x85, 0x0d, 0xa4, 0xf7, 0xb1, 0xee, 0x4a, 0x4a, 0x4a, 0x4a, 0x85, 0x0f, 0xa4, 0xf4, 0xb1, 0xee, 0x29, 0x0f, 0x85, 0x81, 0xa4, 0xf1, 0xb1, 0xee, 0x0a, 0x0a, 0x0a, 0x0a, 0x05, 0x81, 0x85, 0x0e, 0xa9, 0x00, 0x85, 0x0d, 0x85, 0x0f, 0xa4, 0xf6, 0xb1, 0xee, 0x29, 0x0f, 0x85, 0x81, 0xa4, 0xf3, 0xb1, 0xee, 0x0a, 0x0a, 0x0a, 0x0a, 0x05, 0x81, 0x85, 0x0e, 0xc6, 0xee, 0x10, 0xaa, 0xa5, 0x89, 0x18, 0x69, 0xf9, 0x85, 0x89, 0xa9, 0x00, 0x85, 0x0e, 0xf0, 0x48, 0x20, 0x67, 0xfd, 0x20, 0x7e, 0xfd, 0x20, 0xe9, 0xfd, 0xa9, 0xa0, 0x85, 0xee, 0xa9, 0xfc, 0x85, 0xef, 0xa9, 0x00, 0x85, 0x04, 0x85, 0x02, 0x85, 0x2a, 0xa5, 0xc8, 0x29, 0x39, 0xc9, 0x39, 0xd0, 0x0e, 0xa5, 0xc8, 0x2a, 0x2a, 0x2a, 0x2a, 0x29, 0x03, 0xa8, 0xb9, 0x1e, 0xfd, 0x85, 0xee, 0x85, 0x02, 0x85, 0x2b, 0x20, 0xe9, 0xfd, 0xa0, 0x09, 0x85, 0x02, 0xb1, 0xee, 0x85, 0x1b, 0x98, 0x4a, 0xb0, 0x03, 0x20, 0xe9, 0xfd, 0x88, 0x10, 0xf0, 0xa9, 0x00, 0x85, 0x02, 0x85, 0x1b, 0xa5, 0x84, 0x85, 0x21, 0x85, 0x20, 0x29, 0x0f, 0xa8, 0x88, 0x10, 0xfd, 0x85, 0x10, 0xa9, 0x06, 0x85, 0x11, 0x85, 0x02, 0x85, 0x2a, 0x85, 0x04, 0x85, 0x05, 0xa2, 0x0a, 0xa9, 0xfc, 0x95, 0xef, 0xca, 0xca, 0x10, 0xfa, 0x20, 0xe9, 0xfd, 0xa5, 0x02, 0x29, 0x40, 0x85, 0x82, 0x85, 0x2c, 0x85, 0x2b, 0xa9, 0xf0, 0x85, 0x21, 0x85, 0x02, 0x85, 0x2a, 0xa5, 0xe1, 0x85, 0x06, 0x85, 0x07, 0xc6, 0x8f, 0x10, 0x0b, 0xa0, 0x05, 0xa9, 0x01, 0x85, 0x25, 0x85, 0x26, 0x4c, 0xa5, 0xf0, 0x20, 0xb2, 0xfd, 0x4c, 0x9a, 0xfb, 0x86, 0xf2, 0xbe, 0x38, 0xfd, 0xb5, 0xd5, 0xc9, 0x56, 0xb0, 0x04, 0xc9, 0x45, 0xb0, 0x2e, 0xa6, 0xf2, 0xa9, 0x55, 0x99, 0xd5, 0x00, 0xbd, 0xe2, 0xfc, 0x2d, 0x82, 0x02, 0x18, 0xf0, 0x02, 0xa9, 0x04, 0x69, 0x05, 0x75, 0x9c, 0x99, 0xd7, 0x00, 0xa9, 0x03, 0x20, 0x8b, 0xfe, 0xa5, 0xdb, 0x29, 0x80, 0xf0, 0x0a, 0xa5, 0xaa, 0x49, 0x40, 0x85, 0xaa, 0xa9, 0x50, 0x85, 0xd9, 0x60, 0xa5, 0xc8, 0x29, 0x39, 0xc9, 0x39, 0xd0, 0x08, 0xa9, 0xb4, 0x85, 0x9e, 0xa9, 0x00, 0x85, 0xcc, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0xfe, 0x38, 0x38, 0x7c, 0x38, 0x38, 0x10, 0xb6, 0xbe, 0x5d, 0x6b, 0x59, 0x63, 0x3c, 0x4c, 0x14, 0x28, 0xb6, 0xbe, 0x5d, 0x5b, 0x24, 0x85, 0x66, 0x64, 0x28, 0x10, 0x90, 0x88, 0x88, 0x44, 0x42, 0x42, 0xff, 0xdb, 0x5a, 0x18, 0x09, 0x11, 0x11, 0x22, 0x42, 0x42, 0xff, 0xdb, 0x7e, 0x18, 0xa5, 0xa5, 0xa5, 0x99, 0x99, 0xa5, 0xff, 0x5a, 0x7e, 0x3c, 0x42, 0x5a, 0x5a, 0x5a, 0x99, 0xa5, 0xff, 0x5a, 0x7e, 0x3c, 0xc3, 0x24, 0x18, 0x18, 0x18, 0x5a, 0xbd, 0xa5, 0x81, 0x81, 0x24, 0x42, 0x24, 0xa5, 0x99, 0x99, 0xbd, 0x5a, 0x18, 0x00, 0x81, 0x42, 0x42, 0x24, 0x24, 0x3c, 0x7e, 0xeb, 0x7e, 0x3c, 0x00, 0x24, 0x5a, 0x42, 0x24, 0x3c, 0x7e, 0xd7, 0x7e, 0x3c, 0x77, 0x44, 0x44, 0x44, 0x5c, 0xff, 0xf3, 0xf3, 0x7e, 0x3c, 0xee, 0x22, 0x22, 0x22, 0x3a, 0xff, 0xcf, 0xcf, 0x7e, 0x3c, 0xe7, 0x42, 0x7e, 0x7e, 0x6b, 0x3e, 0x98, 0xa4, 0x42, 0x01, 0xc6, 0x42, 0x7e, 0x7e, 0x56, 0x7c, 0x19, 0x25, 0x42, 0x80, 0x00, 0x38, 0x7c, 0xfe, 0xfe, 0xaa, 0xfe, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x24, 0x3c, 0x76, 0x5c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24, 0x95, 0x48, 0xc7, 0x24, 0x90, 0x20, 0x40, 0x5d, 0xbb, 0xb6, 0x77, 0xcc, 0x2d, 0x7e, 0xcd, 0xda, 0x6d, 0x77, 0x77, 0x82, 0x54, 0x25, 0x53, 0xc3, 0x54, 0x93, 0xa5, 0x99, 0x81, 0x28, 0x78, 0x64, 0x50, 0x3c, 0x8c, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x22, 0x16, 0x0c, 0x08, 0x05, 0x04, 0x03, 0x02, 0x00, 0x20, 0x20, 0x15, 0x15, 0x10, 0x0b, 0x07, 0x07, 0x04, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x05, 0x0f, 0x0e, 0x0f, 0x00, 0x02, 0x00, 0x04, 0x02, 0x34, 0x52, 0xcc, 0xf6, 0x14, 0x0f, 0x00, 0xe2, 0x05, 0x0a, 0x0f, 0x14, 0xbd, 0xb4, 0xab, 0x54, 0x59, 0x5e, 0x63, 0x00, 0x08, 0x04, 0x0c, 0xaa, 0xb6, 0xc0, 0xcc, 0x3c, 0x7e, 0x7e, 0x7e, 0x7e, 0xff, 0xff, 0xff, 0xc3, 0x05, 0x10, 0x15, 0x20, 0x25, 0x30, 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x01, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0x00, 0x10, 0x8b, 0xd1, 0xbf, 0x9d, 0xd1, 0xd1, 0x18, 0x10, 0x61, 0xd1, 0x32, 0x90, 0x14, 0x10, 0x10, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x05, 0x03, 0x17, 0x2b, 0x23, 0x75, 0xb4, 0xa0, 0xff, 0x38, 0xc8, 0xe9, 0x0f, 0xb0, 0xfb, 0x49, 0xff, 0xe9, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x94, 0x83, 0x15, 0x83, 0x95, 0x83, 0x60, 0x85, 0x02, 0xea, 0xc8, 0x95, 0x20, 0xea, 0x88, 0x10, 0xfd, 0x95, 0x10, 0x60, 0xc0, 0x09, 0xb0, 0x22, 0x86, 0xee, 0xe8, 0x20, 0xfb, 0xfd, 0x29, 0x20, 0xd0, 0x02, 0xca, 0xca, 0xe0, 0x08, 0xb0, 0x09, 0xa5, 0xea, 0xc9, 0xc0, 0x90, 0x03, 0x20, 0xaa, 0xfd, 0xa6, 0xee, 0xb1, 0xf0, 0x3d, 0x4c, 0xff, 0x91, 0xf0, 0x60, 0xc6, 0x89, 0xa5, 0x89, 0x30, 0x0f, 0xc9, 0x04, 0xa9, 0x02, 0x90, 0x01, 0x4a, 0x85, 0x1f, 0x85, 0x02, 0x85, 0x2b, 0x10, 0x1d, 0x18, 0x65, 0x8a, 0x85, 0x89, 0xa9, 0x00, 0x85, 0x02, 0x85, 0x2b, 0x85, 0x1f, 0xa5, 0x88, 0x85, 0x24, 0x29, 0x0f, 0xa8, 0x88, 0x10, 0xfd, 0x85, 0x14, 0xa9, 0x7c, 0x85, 0x8a, 0x85, 0x02, 0x85, 0x2a, 0x60, 0xc6, 0x89, 0xa5, 0x89, 0xc9, 0x04, 0x90, 0x04, 0xa9, 0x00, 0xb0, 0x03, 0xea, 0xa9, 0x02, 0x85, 0x1f, 0x60, 0xa5, 0xea, 0x0a, 0x0a, 0x18, 0x65, 0xea, 0x18, 0x69, 0x59, 0x85, 0xea, 0x60, 0xa5, 0xc7, 0xd0, 0x5c, 0xf6, 0xcd, 0xb4, 0xcb, 0xf0, 0x56, 0xc0, 0x05, 0xf0, 0x04, 0xc0, 0x02, 0xd0, 0x24, 0xb4, 0xcd, 0xc0, 0x08, 0xd0, 0x08, 0xb5, 0xcb, 0xc9, 0x05, 0xf0, 0x46, 0xd0, 0x40, 0xb9, 0xea, 0xff, 0x95, 0x17, 0xa9, 0x0c, 0x95, 0x15, 0xa9, 0xcb, 0xc9, 0x05, 0xa9, 0x04, 0x90, 0x02, 0xa9, 0x08, 0x95, 0x19, 0x60, 0xb9, 0x44, 0xfd, 0x85, 0xee, 0xa9, 0xff, 0x85, 0xef, 0xb4, 0xcf, 0xb1, 0xee, 0xd5, 0xcd, 0xd0, 0x18, 0xc8, 0xb1, 0xee, 0x30, 0x14, 0xc9, 0x3f, 0xf0, 0x14, 0x95, 0x17, 0xc8, 0xb1, 0xee, 0x95, 0x15, 0xc8, 0xb1, 0xee, 0xc8, 0x94, 0xcf, 0x95, 0x19, 0x60, 0xa9, 0x00, 0x95, 0xcb, 0xa9, 0x00, 0x95, 0x19, 0x95, 0xcd, 0x95, 0xcf, 0x60, 0xa5, 0xca, 0x29, 0x01, 0x09, 0x80, 0x85, 0xca, 0x60, 0xc5, 0xcb, 0x90, 0x08, 0x85, 0xcb, 0xa9, 0x00, 0x85, 0xcd, 0x85, 0xcf, 0x60, 0xc5, 0xcc, 0x90, 0x08, 0x85, 0xcc, 0xa9, 0x00, 0x85, 0xce, 0x85, 0xd0, 0x60, 0xd8, 0x78, 0xa2, 0x00, 0x8a, 0x95, 0x00, 0xe8, 0xd0, 0xfb, 0xca, 0x9a, 0x20, 0xb2, 0xfe, 0xa9, 0xc5, 0x85, 0xc7, 0xa9, 0x80, 0x85, 0xaa, 0x4c, 0xd4, 0xf4, 0xa9, 0x00, 0x85, 0xe6, 0x85, 0xe8, 0x85, 0xe7, 0x85, 0xe9, 0x85, 0xc7, 0xa9, 0x01, 0x85, 0xaa, 0xa9, 0x00, 0x85, 0x90, 0x85, 0x99, 0x85, 0xc6, 0x20, 0x75, 0xfe, 0xa9, 0x03, 0x85, 0xc9, 0xa9, 0xff, 0x85, 0x8b, 0xa5, 0x98, 0x29, 0x53, 0xa4, 0xec, 0x19, 0x52, 0xfd, 0x19, 0x59, 0xfd, 0x85, 0x98, 0xa5, 0xe5, 0x29, 0x7f, 0x85, 0xe5, 0x20, 0xfa, 0xfe, 0xa2, 0x0a, 0xb5, 0x90, 0x95, 0x9f, 0xca, 0x10, 0xf9, 0xa9, 0x6e, 0x85, 0xa7, 0x60, 0xa2, 0x05, 0xa9, 0x3f, 0x95, 0x92, 0xca, 0x10, 0xfb, 0x85, 0xeb, 0x85, 0xd7, 0x85, 0xd8, 0x85, 0xd3, 0x85, 0xd4, 0xa9, 0xf6, 0x85, 0xd5, 0x85, 0xd6, 0x85, 0xd1, 0x85, 0xd2, 0xa2, 0x05, 0xbd, 0x61, 0xfd, 0x95, 0x99, 0xca, 0xd0, 0xf8, 0x8a, 0x85, 0xcb, 0x85, 0xcc, 0xa9, 0x24, 0x85, 0x91, 0xa9, 0x42, 0x05, 0x98, 0x85, 0x98, 0xa9, 0x30, 0x85, 0xc8, 0xa5, 0xaa, 0x29, 0xf7, 0x85, 0xaa, 0xa2, 0x1a, 0xa0, 0x08, 0xb9, 0x22, 0xfd, 0x95, 0xab, 0x88, 0x10, 0x02, 0xa0, 0x08, 0xca, 0x10, 0xf3, 0x60, 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe, 0xe7, 0xa5, 0xa5, 0xa5, 0xe7, 0xe7, 0x42, 0x42, 0x66, 0x42, 0xe7, 0x24, 0xe7, 0x81, 0xe7, 0xe7, 0x81, 0xe7, 0x81, 0xe7, 0x81, 0x81, 0xe7, 0xa5, 0xa5, 0xe7, 0x81, 0xe7, 0x24, 0xe7, 0xe7, 0xa5, 0xe7, 0x24, 0x24, 0x81, 0x81, 0x81, 0x81, 0xe7, 0xe7, 0xa5, 0xe7, 0xa5, 0xe7, 0x81, 0x81, 0xe7, 0xa5, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x16, 0x09, 0x0a, 0x02, 0x19, 0x08, 0x0a, 0x03, 0x1f, 0x0c, 0x08, 0x04, 0x16, 0x0e, 0x07, 0x06, 0xff, 0x01, 0x18, 0x0c, 0x03, 0x03, 0x16, 0x0c, 0x03, 0x05, 0x14, 0x0c, 0x03, 0x07, 0x12, 0x0c, 0x03, 0x09, 0x10, 0x0c, 0x03, 0x0b, 0x0e, 0x0c, 0x03, 0x0d, 0x0d, 0x0c, 0x03, 0x0f, 0x10, 0x0c, 0x03, 0x11, 0x3f, 0x01, 0x18, 0x08, 0x07, 0x04, 0x19, 0x08, 0x05, 0x10, 0x1c, 0x08, 0x02, 0x30, 0x1e, 0x08, 0x01, 0x50, 0xff, 0x01, 0x18, 0x03, 0x0c, 0x09, 0x10, 0x0a, 0x08, 0x11, 0x12, 0x0e, 0x0f, 0x19, 0x16, 0x0e, 0x08, 0x29, 0x1a, 0x0e, 0x04, 0x39, 0x1d, 0x0e, 0x02, 0x49, 0xff, 0x10, 0x0d, 0x0a, 0x08, 0x07, 0x06, 0x05, 0x06, 0x07, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00, 0x98, 0xfe, 0x98, 0xfe, 0x98, 0xfe, };