diff --git a/6.out b/6.out deleted file mode 100755 index c341853..0000000 Binary files a/6.out and /dev/null differ diff --git a/scemu.c b/scemu.c deleted file mode 100644 index bd0f26f..0000000 --- a/scemu.c +++ /dev/null @@ -1,847 +0,0 @@ -#include -#include - -enum { - Negative = 1<<7, - Overflow = 1<<6, - Break = 1<<4, - Decimal = 1<<3, - Interrupt = 1<<2, - Zero = 1<<1, - Carry = 1 -}; - -int step(void); -static u16int fetch16(void); - -u8int mem[65536]; -u8int rA, rS, rX, rY, rP; -u16int pc; - -int irq, nmi; - -u8int *prog; - -void -usage(void) -{ - fprint(2, "usage: %s [ -s target speed ] [ prog ]\n", argv0); - exits("usage"); -} - -void -openprog(char *f, vlong *progsiz) -{ - int fd; - long n; - Dir *d; - - prog = nil; - if(f == nil) - f = "a.out"; - fd = open(f, OREAD); - if(fd < 0) - return; - d = dirfstat(fd); - *progsiz = d->length; - free(d); - prog = malloc(*progsiz); - if(prog == nil) - sysfatal("bad malloc"); - n = read(fd, prog, *progsiz); - if(n != *progsiz) - fprint(2, "tried to read %lld bytes, got only %ld bytes\n", *progsiz, n); - close(fd); -} - -void -main(int argc, char **argv) -{ - int c; - vlong t, t2, t3, progsiz; - vlong target; - - target = 1000; - ARGBEGIN{ - case 's': - target = atoll(EARGF(usage())); - break; - default: - usage(); - break; - }ARGEND - openprog(*argv, &progsiz); - if(prog == nil) - sysfatal("bad program: %r"); - memmove(mem+0x8000, prog, progsiz); - rP = 0x34; - pc = 0xFFFC; - pc = fetch16(); - for(;;){ - c = step(); - while(c >= 0){ - t = nsec(); - --c; - t2 = nsec(); - t3 = t2-t; - while(t3 < target){ - t2 = nsec(); - t3 = t2-t; - } - } - } -} - -static void -push8(u8int v) -{ - mem[0x100 | rS--] = v; -} - -static void -push16(u16int v) -{ - mem[0x100 | rS--] = v >> 8; - mem[0x100 | rS--] = v&0xff; -} - -static u8int -pop8(void) -{ - return mem[0x100 | ++rS]; -} - -static u16int -pop16(void) -{ - u16int v; - - v = mem[0x100 | ++rS]; - v |= mem[0x100 | ++rS] << 8; - return v; -} - -static u8int -fetch8(void) -{ - return mem[pc++]; -} - -static u16int -fetch16(void) -{ - u16int v; - - v = fetch8(); - v |= fetch8() << 8; - return v; -} - -static void -nz(u8int v) -{ - rP &= ~(Negative | Zero); - if(v & 0x80) - rP |= Negative; - if(v == 0) - rP |= Zero; -} - -static void -adc(u8int d) -{ - int r; - - r = rA + d + (rP & Carry); - rP &= ~(Negative | Zero | Overflow | Carry); - if(r > 0xFF) rP |= Carry; - if(r & 0x80) rP |= Negative; - if((~(rA ^ d) & (rA ^ r)) & 0x80) rP |= Overflow; - rA = r; - if(rA == 0) rP |= Zero; -} - -static void -sbc(u8int d) -{ - int r; - - r = rA + (u8int)~d + (rP & Carry); - rP &= ~(Negative | Zero | Overflow | Carry); - if(r > 0xFF) rP |= Carry; - if((~(rA ^ d) & (rA ^ r)) & 0x80) rP |= Overflow; - rA = r; - if(rA == 0) rP |= Zero; - if(rA & 0x80) rP |= Negative; -} - -static void -asl(u16int a) -{ - u8int v; - - rP &= ~(Negative | Zero | Carry); - v = mem[a]; - if(v & 0x80) - rP |= Carry; - v <<= 1; - if(v == 0) - rP |= Zero; - if(v & 0x80) - rP |= Negative; - mem[a] = v; -} - -static void -lsr(u16int a) -{ - u8int v; - - v = mem[a]; - rP &= ~(Negative | Zero | Carry); - rP |= v & 1; - v >>= 1; - if(v == 0) rP |= Zero; - if(v & 0x80) rP |= Negative; - mem[a] = v; -} - -static void -rol(u16int a) -{ - u8int v, b; - - v = mem[a]; - b = rP & Carry; - rP &= ~(Carry | Negative | Zero); - if(v & 0x80) rP |= Carry; - v = (v << 1) | b; - if(v & 0x80) rP |= Negative; - if(v == 0) rP |= Zero; - mem[a] = v; -} - -static void -ror(u16int a) -{ - u8int v, b; - - v = mem[a]; - b = rP & Carry; - rP &= ~(Carry | Negative | Zero); - rP |= v & 1; - v = (v >> 1) | (b << 7); - if(v & 0x80) rP |= Negative; - if(v == 0) rP |= Zero; - mem[a] = v; -} - -static void -cmp(u8int A, u8int B) -{ - rP &= ~(Negative | Zero | Carry); - if(A == B) rP |= Zero; - if(A >= B) rP |= Carry; - if((A - B) & 0x80) rP |= Negative; -} - -static void -inc(u16int a) -{ - u8int v; - - v = mem[a]; - v++; - nz(v); - mem[a] = v; -} - -static void -dec(u16int a) -{ - u8int v; - - v = mem[a]; - v--; - nz(v); - mem[a] = v; -} - -static int -branch(void) -{ - s8int t; - u16int npc; - - t = fetch8(); - npc = pc+t; - if((npc ^ pc) >> 8){ - pc = npc; - return 4; - } - pc = npc; - return 3; -} - -static u16int -aindX(void) -{ - u8int r; - u16int b; - - r = fetch8() + rX; - b = mem[r++]; - b |= mem[r] << 8; - return b; -} - -static u16int -aindY(int *p) -{ - u8int r; - u16int b; - - r = fetch8(); - b = mem[r++] + rY; - *p = b > 0xFF; - b += mem[r] << 8; - return b; -} - -static void -interrupt(int nmi, int brk) -{ - push16(pc); - push8(rP | 0x20 | (brk << 4)); - pc = mem[0xFFFA | (!nmi << 2)]; - pc |= mem[0xFFFB | (!nmi << 2)] << 8; - rP |= Interrupt; -} - -#define zp() mem[fetch8()] -#define zpX() mem[(u8int)(fetch8()+rX)] -#define zpY() mem[(u8int)(fetch8()+rY)] -#define abso() mem[fetch16()] -#define absX() mem[a = fetch16()+rX] -#define absY() mem[a = fetch16()+rY] -#define indX() mem[aindX()] -#define indY(c) mem[aindY(c)] - -int -step(void) -{ - u8int op; - u16int a, v, cpc; - int c; - - if(nmi) - if(--nmi == 0){ - interrupt(1, 0); - nmi = 0; - return 7; - } - if(irq && (rP & Interrupt) == 0){ - interrupt(0, 0); - return 7; - } - cpc = pc; - op = fetch8(); - print("%02x %08b %08b %08b %08b %04x %02x\n", - op, rA, rX, rY, rP, cpc, rS); - switch(op){ - case 0x00: - pc++; - interrupt(0, 1); - return 7; - case 0x01: - nz(rA |= indX()); - return 6; - case 0x05: - nz(rA |= zp()); - return 3; - case 0x06: - asl(fetch8()); - return 5; - case 0x08: - push8(rP | 0x30); - return 3; - case 0x09: - nz(rA |= fetch8()); - return 2; - case 0x0A: - rP &= ~(Negative | Zero | Carry); - if(rA & 0x80) rP |= Carry; - rA <<= 1; - if(rA == 0) rP |= Zero; - if(rA & 0x80) rP |= Negative; - return 2; - case 0x0D: - nz(rA |= abso()); - return 4; - case 0x0E: - asl(fetch16()); - return 6; - case 0x10: - if((rP & Negative) == 0) return branch(); - pc++; - return 2; - case 0x11: - nz(rA |= indY(&c)); - return 5+c; - case 0x15: - nz(rA |= zpX()); - return 4; - case 0x16: - asl((u8int)(fetch8() + rX)); - return 6; - case 0x18: - rP &= ~Carry; - return 2; - case 0x19: - nz(rA |= absY()); - return 4 + ((u8int)a < rY); - case 0x1D: - nz(rA |= absX()); - return 4 + ((u8int)a < rX); - case 0x1E: - asl(fetch16() + rX); - return 7; - case 0x20: - push16(pc+1); - pc = fetch16(); - return 6; - case 0x21: - nz(rA &= indX()); - return 6; - case 0x24: - a = mem[fetch8()]; - rP &= ~(Negative | Zero | Overflow); - rP |= a & 0xC0; - if((a & rA) == 0) rP |= Zero; - return 3; - case 0x25: - nz(rA &= zp()); - return 3; - case 0x26: - rol(fetch8()); - return 5; - case 0x28: - rP = pop8() & 0xcf; - return 4; - case 0x29: - nz(rA &= fetch8()); - return 2; - case 0x2A: - a = rP & Carry; - rP &= ~(Carry | Zero | Negative); - if(rA & 0x80) rP |= Carry; - rA = (rA << 1) | a; - if(rA & 0x80) rP |= Negative; - if(rA == 0) rP |= Zero; - return 2; - case 0x2C: - a = mem[fetch16()]; - rP &= ~(Negative | Zero | Overflow); - rP |= a & 0xC0; - if((a & rA) == 0) rP |= Zero; - return 4; - case 0x2D: - nz(rA &= abso()); - return 4; - case 0x2E: - rol(fetch16()); - return 6; - case 0x30: - if((rP & Negative) != 0) return branch(); - pc++; - return 3; - case 0x31: - nz(rA &= indY(&c)); - return 5+c; - case 0x35: - nz(rA &= zpX()); - return 4; - case 0x36: - rol((u8int)(fetch8() + rX)); - return 6; - case 0x38: - rP |= Carry; - return 2; - case 0x39: - nz(rA &= absY()); - return 4 + ((u8int)a < rY); - case 0x3E: - rol(fetch16() + rX); - return 7; - case 0x3D: - nz(rA &= absX()); - return 4 + ((u8int)a < rX); - case 0x40: - rP = pop8() & 0xcf; - pc = pop16(); - return 6; - case 0x41: - nz(rA ^= indX()); - return 6; - case 0x45: - nz(rA ^= zp()); - return 3; - case 0x46: - lsr(fetch8()); - return 5; - case 0x48: - push8(rA); - return 3; - case 0x49: - nz(rA ^= fetch8()); - return 2; - case 0x4A: - rP &= ~(Negative | Zero | Carry); - rP |= rA & 1; - rA >>= 1; - if(rA == 0) rP |= Zero; - if(rA & 0x80) rP |= Negative; - return 2; - case 0x4C: - pc = fetch16(); - return 3; - case 0x4D: - nz(rA ^= abso()); - return 4; - case 0x4E: - lsr(fetch16()); - return 6; - case 0x51: - nz(rA ^= indY(&c)); - return 5+c; - case 0x56: - lsr((u8int)(fetch8() + rX)); - return 6; - case 0x58: - rP &= ~Interrupt; - return 2; - case 0x50: - if((rP & Overflow) == 0) return branch(); - pc++; - return 3; - case 0x55: - nz(rA ^= zpX()); - return 4; - case 0x59: - nz(rA ^= absY()); - return 4 + ((u8int)a < rX); - case 0x5D: - nz(rA ^= absX()); - return 4 + ((u8int)a < rX); - case 0x5E: - lsr(fetch16() + rX); - return 7; - case 0x60: - pc = pop16() + 1; - return 6; - case 0x61: - adc(indX()); - return 6; - case 0x65: - adc(zp()); - return 3; - case 0x66: - ror(fetch8()); - return 5; - case 0x68: - nz(rA = pop8()); - return 4; - case 0x69: - adc(fetch8()); - return 2; - case 0x6A: - a = rP & Carry; - rP &= ~(Carry | Negative | Zero); - rP |= rA & 1; - rA = (rA >> 1) | (a << 7); - if(rA & 0x80) rP |= Negative; - if(rA == 0) rP |= Zero; - return 2; - case 0x6C: - v = fetch16(); - pc = mem[v] | (mem[(v & 0xFF00) | (u8int)(v+1)] << 8); - return 5; - case 0x6D: - adc(abso()); - return 4; - case 0x6E: - ror(fetch16()); - return 6; - case 0x70: - if((rP & Overflow) != 0) return branch(); - pc++; - return 3; - case 0x71: - adc(indY(&c)); - return 5+c; - case 0x75: - adc(zpX()); - return 4; - case 0x76: - ror((u8int)(fetch8() + rX)); - return 6; - case 0x78: - rP |= Interrupt; - return 2; - case 0x79: - adc(absY()); - return 4 + ((u8int)a < rY); - case 0x7D: - adc(absX()); - return 4 + ((u8int)a < rX); - case 0x7E: - ror(fetch16() + rX); - return 7; - case 0x81: - mem[aindX()] = rA; - return 6; - case 0x84: - mem[fetch8()] = rY; - return 3; - case 0x85: - mem[fetch8()] = rA; - return 3; - case 0x86: - mem[fetch8()] = rX; - return 3; - case 0x88: - nz(--rY); - return 2; - case 0x8A: - nz(rA = rX); - return 2; - case 0x8C: - mem[fetch16()] = rY; - return 4; - case 0x8D: - mem[fetch16()] = rA; - return 4; - case 0x8E: - mem[fetch16()] = rX; - return 4; - case 0x90: - if((rP & Carry) == 0) return branch(); - pc++; - return 3; - case 0x91: - mem[aindY(&c)] = rA; - return 6; - case 0x94: - mem[(u8int)(fetch8() + rX)] = rY; - return 4; - case 0x95: - mem[(u8int)(fetch8() + rX)] = rA; - return 4; - case 0x96: - mem[(u8int)(fetch8() + rY)] = rX; - return 4; - case 0x98: - nz(rA = rY); - return 2; - case 0x99: - mem[fetch16() + rY] = rA; - return 5; - case 0x9A: - rS = rX; - return 2; - case 0x9D: - mem[fetch16() + rX] = rA; - return 5; - case 0xA0: - nz(rY = fetch8()); - return 2; - case 0xA1: - nz(rA = indX()); - return 6; - case 0xA2: - nz(rX = fetch8()); - return 2; - case 0xA4: - nz(rY = zp()); - return 3; - case 0xA5: - nz(rA = zp()); - return 3; - case 0xA6: - nz(rX = zp()); - return 3; - case 0xA8: - nz(rY = rA); - return 2; - case 0xA9: - nz(rA = fetch8()); - return 2; - case 0xAA: - nz(rX = rA); - return 2; - case 0xAC: - nz(rY = abso()); - return 4; - case 0xAE: - nz(rX = abso()); - return 4; - case 0xAD: - nz(rA = abso()); - return 4; - case 0xB0: - if((rP & Carry) != 0) return branch(); - pc++; - return 3; - case 0xB1: - nz(rA = indY(&c)); - return 5+c; - case 0xB4: - nz(rY = zpX()); - return 4; - case 0xB5: - nz(rA = zpX()); - return 4; - case 0xB6: - nz(rX = zpY()); - return 4; - case 0xB8: - rP &= ~Overflow; - return 2; - case 0xB9: - nz(rA = absY()); - return 4 + ((u8int)a < rY); - case 0xBA: - nz(rX = rS); - return 2; - case 0xBC: - nz(rY = absX()); - return 4 + ((u8int)a < rX); - case 0xBD: - nz(rA = absX()); - return 4 + ((u8int)a < rX); - case 0xBE: - nz(rX = absY()); - return 4 + ((u8int)a < rY); - case 0xC1: - cmp(rA, indX()); - return 6; - case 0xC5: - cmp(rA, zp()); - return 3; - case 0xC9: - cmp(rA, fetch8()); - return 2; - case 0xCD: - cmp(rA, abso()); - return 4; - case 0xD0: - if((rP & Zero) == 0) return branch(); - pc++; - return 3; - case 0xD1: - cmp(rA, indY(&c)); - return 5 + c; - case 0xD5: - cmp(rA, zpX()); - return 4; - case 0xD8: - rP &= ~Decimal; - return 2; - case 0xD9: - cmp(rA, absY()); - return 4 + ((u8int)a < rY); - case 0xDD: - cmp(rA, absX()); - return 4 + ((u8int)a < rX); - case 0xC0: - cmp(rY, fetch8()); - return 2; - case 0xC4: - cmp(rY, zp()); - return 3; - case 0xC6: - dec(fetch8()); - return 5; - case 0xC8: - nz(++rY); - return 2; - case 0xCA: - nz(--rX); - return 2; - case 0xCC: - cmp(rY, abso()); - return 4; - case 0xCE: - dec(fetch16()); - return 6; - case 0xD6: - dec((u8int)(fetch8() + rX)); - return 6; - case 0xDE: - dec(fetch16() + rX); - return 7; - case 0xE0: - cmp(rX, fetch8()); - return 2; - case 0xE1: - sbc(indX()); - return 6; - case 0xE4: - cmp(rX, zp()); - return 3; - case 0xE5: - sbc(zp()); - return 3; - case 0xE6: - inc(fetch8()); - return 5; - case 0xE8: - nz(++rX); - return 2; - case 0xE9: - sbc(fetch8()); - return 2; - case 0xEA: - return 2; - case 0xEC: - cmp(rX, abso()); - return 4; - case 0xED: - sbc(abso()); - return 4; - case 0xEE: - inc(fetch16()); - return 6; - case 0xF0: - if((rP & Zero) != 0) return branch(); - pc++; - return 3; - case 0xF1: - sbc(indY(&c)); - return 5+c; - case 0xF5: - sbc(zpX()); - return 4; - case 0xF6: - inc((u8int)(fetch8() + rX)); - return 6; - case 0xF8: - rP |= Decimal; - return 2; - case 0xF9: - sbc(absY()); - return 4 + ((u8int)a < rY); - case 0xFD: - sbc(absX()); - return 4 + ((u8int)a < rX); - case 0xFE: - inc(fetch16() + rX); - return 7; - default: - print("unimplemented %#02x\n", op); - exits(nil); - case 0xFF: - print("%s\n", (s8int*)mem+0x500); - exits(nil); - } -}