Compare commits

...

2 commits

Author SHA1 Message Date
90cfd134ee merge 2025-09-08 21:24:16 +00:00
6fc687f433 try to make your programs read-only
this is a long time in the making. hello, memread and memwrite
byebye to mem[a] = v
2025-09-08 21:23:49 +00:00

101
scemu.c
View file

@ -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;
}