diff --git a/scemu.c b/scemu.c index c94a53e..8363a40 100644 --- a/scemu.c +++ b/scemu.c @@ -14,14 +14,13 @@ enum { int step(void); static u16int fetch16(void); -u8int mem[65536]; +u8int mem[32768]; +u8int prog[32768]; u8int rA, rS, rX, rY, rP; u16int pc; int irq, nmi; -u8int *prog; - void usage(void) { @@ -36,21 +35,18 @@ openprog(char *f, vlong *progsiz) long n; Dir *d; - prog = nil; + memset(prog, 0, sizeof prog); if(f == nil) f = "a.out"; fd = open(f, OREAD); if(fd < 0) - return; + sysfatal("bad program: %r\n"); d = dirfstat(fd); if(d->length > 32768) - sysfatal("bad program: bigger than 32K, please shrink it"); + sysfatal("bad program: bigger than 32K and no banking support"); *progsiz = d->length; free(d); - prog = malloc(*progsiz); - if(prog == nil) - sysfatal("bad malloc"); - n = read(fd, prog, *progsiz); + n = read(fd, prog+32768-*progsiz, *progsiz); if(n != *progsiz) fprint(2, "tried to read %lld bytes, got only %ld bytes\n", *progsiz, n); close(fd); @@ -73,9 +69,6 @@ main(int argc, char **argv) break; }ARGEND openprog(*argv, &progsiz); - if(prog == nil) - sysfatal("bad program: %r"); - memmove(mem+0x8000, prog, progsiz); rP = 0x34; pc = 0xFFFC; pc = fetch16(); @@ -94,49 +87,65 @@ main(int argc, char **argv) } } +u8int +memread(u16int a) +{ + if(a < 0x8000) + return mem[a]; + else + return prog[a-0x8000]; +} + +void +memwrite(u16int a, u8int v) +{ + if(a < 0x8000) + mem[a] = v; +} + static void push8(u8int v) { - mem[0x100 | rS--] = v; + memwrite(0x100 | rS--, v); } static void push16(u16int v) { - mem[0x100 | rS--] = v >> 8; - mem[0x100 | rS--] = v&0xff; + memwrite(0x100 | rS--, v >> 8); + memwrite(0x100 | rS--, v); } static u8int pop8(void) { - return mem[0x100 | ++rS]; + return memread(0x100 | ++rS); } static u16int pop16(void) { u16int v; - - v = mem[0x100 | ++rS]; - v |= mem[0x100 | ++rS] << 8; + + v = memread(0x100 | ++rS); + v |= memread(0x100 | ++rS) << 8; return v; } static u8int fetch8(void) { - return mem[pc++]; + return memread(pc++); } static u16int fetch16(void) { - u16int v; - - v = fetch8(); - v |= fetch8() << 8; - return v; + u16int r; + + r = memread(pc++); + r |= memread(pc++) << 8; + return r; } static void @@ -182,8 +191,8 @@ asl(u16int a) { u8int v; + v = memread(a); rP &= ~(Negative | Zero | Carry); - v = mem[a]; if(v & 0x80) rP |= Carry; v <<= 1; @@ -191,7 +200,7 @@ asl(u16int a) rP |= Zero; if(v & 0x80) rP |= Negative; - mem[a] = v; + memwrite(a, v); } static void @@ -199,13 +208,13 @@ lsr(u16int a) { u8int v; - v = mem[a]; + v = memread(a); rP &= ~(Negative | Zero | Carry); rP |= v & 1; v >>= 1; if(v == 0) rP |= Zero; if(v & 0x80) rP |= Negative; - mem[a] = v; + memwrite(a, v); } static void @@ -213,14 +222,14 @@ rol(u16int a) { u8int v, b; - v = mem[a]; + v = memread(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; + memwrite(a, v); } static void @@ -228,14 +237,14 @@ ror(u16int a) { u8int v, b; - v = mem[a]; + v = memread(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; + memwrite(a, v); } static void @@ -252,10 +261,10 @@ inc(u16int a) { u8int v; - v = mem[a]; + v = memread(a); v++; nz(v); - mem[a] = v; + memwrite(a, v); } static void @@ -263,10 +272,10 @@ dec(u16int a) { u8int v; - v = mem[a]; + v = memread(a); v--; nz(v); - mem[a] = v; + memwrite(a, v); } static int @@ -290,10 +299,10 @@ aindX(void) { u8int r; u16int b; - + r = fetch8() + rX; - b = mem[r++]; - b |= mem[r] << 8; + b = memread(r++); + b |= memread(r) << 8; return b; } @@ -302,11 +311,11 @@ aindY(int *p) { u8int r; u16int b; - + r = fetch8(); - b = mem[r++] + rY; + b = memread(r++) + rY; *p = b > 0xFF; - b += mem[r] << 8; + b += memread(r) << 8; return b; } @@ -315,8 +324,8 @@ interrupt(int nmi, int brk) { push16(pc); push8(rP | 0x20 | (brk << 4)); - pc = mem[0xFFFA | (!nmi << 2)]; - pc |= mem[0xFFFB | (!nmi << 2)] << 8; + pc = memread(0xFFFA | (!nmi << 2)); + pc |= memread(0xFFFB | (!nmi << 2)) << 8; rP |= Interrupt; }