this is a long time in the making. hello, memread and memwrite byebye to mem[a] = v
858 lines
13 KiB
C
858 lines
13 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
|
|
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[32768];
|
|
u8int prog[32768];
|
|
u8int rA, rS, rX, rY, rP;
|
|
u16int pc;
|
|
|
|
int irq, nmi;
|
|
|
|
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;
|
|
|
|
memset(prog, 0, sizeof prog);
|
|
if(f == nil)
|
|
f = "a.out";
|
|
fd = open(f, OREAD);
|
|
if(fd < 0)
|
|
sysfatal("bad program: %r\n");
|
|
d = dirfstat(fd);
|
|
if(d->length > 32768)
|
|
sysfatal("bad program: bigger than 32K and no banking support");
|
|
*progsiz = d->length;
|
|
free(d);
|
|
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);
|
|
}
|
|
|
|
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);
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
static u8int
|
|
fetch8(void)
|
|
{
|
|
return memread(pc++);
|
|
}
|
|
|
|
static u16int
|
|
fetch16(void)
|
|
{
|
|
u16int r;
|
|
|
|
r = memread(pc++);
|
|
r |= memread(pc++) << 8;
|
|
return r;
|
|
}
|
|
|
|
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;
|
|
|
|
v = memread(a);
|
|
rP &= ~(Negative | Zero | Carry);
|
|
if(v & 0x80)
|
|
rP |= Carry;
|
|
v <<= 1;
|
|
if(v == 0)
|
|
rP |= Zero;
|
|
if(v & 0x80)
|
|
rP |= Negative;
|
|
memwrite(a, v);
|
|
}
|
|
|
|
static void
|
|
lsr(u16int a)
|
|
{
|
|
u8int v;
|
|
|
|
v = memread(a);
|
|
rP &= ~(Negative | Zero | Carry);
|
|
rP |= v & 1;
|
|
v >>= 1;
|
|
if(v == 0) rP |= Zero;
|
|
if(v & 0x80) rP |= Negative;
|
|
memwrite(a, v);
|
|
}
|
|
|
|
static void
|
|
rol(u16int a)
|
|
{
|
|
u8int v, b;
|
|
|
|
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;
|
|
memwrite(a, v);
|
|
}
|
|
|
|
static void
|
|
ror(u16int a)
|
|
{
|
|
u8int v, b;
|
|
|
|
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;
|
|
memwrite(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 = memread(a);
|
|
v++;
|
|
nz(v);
|
|
memwrite(a, v);
|
|
}
|
|
|
|
static void
|
|
dec(u16int a)
|
|
{
|
|
u8int v;
|
|
|
|
v = memread(a);
|
|
v--;
|
|
nz(v);
|
|
memwrite(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 = memread(r++);
|
|
b |= memread(r) << 8;
|
|
return b;
|
|
}
|
|
|
|
static u16int
|
|
aindY(int *p)
|
|
{
|
|
u8int r;
|
|
u16int b;
|
|
|
|
r = fetch8();
|
|
b = memread(r++) + rY;
|
|
*p = b > 0xFF;
|
|
b += memread(r) << 8;
|
|
return b;
|
|
}
|
|
|
|
static void
|
|
interrupt(int nmi, int brk)
|
|
{
|
|
push16(pc);
|
|
push8(rP | 0x20 | (brk << 4));
|
|
pc = memread(0xFFFA | (!nmi << 2));
|
|
pc |= memread(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);
|
|
}
|
|
}
|