start logging instructions as nestest.log has done

This commit is contained in:
Vineet K 2024-06-28 09:51:55 -04:00
parent 6a5b0b728e
commit 3ebdeab784
3 changed files with 201 additions and 31 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
a.out a.out
nes
*.core *.core
*~ *~

8
Makefile Normal file
View File

@ -0,0 +1,8 @@
nes:
${CC} -o nes cpu.c rom.c
test: nes
./nes ${HOME}/src/other/nes-test-roms/other/nestest.nes
clean:
rm -f *.o nes

223
cpu.c
View File

@ -12,6 +12,11 @@
(regs.status.zero = r == 0) (regs.status.zero = r == 0)
#define STATUS_UPDATE_NEGATIVE(r) \ #define STATUS_UPDATE_NEGATIVE(r) \
(regs.status.negative = ((r & (1 << 7)) != 0)) (regs.status.negative = ((r & (1 << 7)) != 0))
#define STATUS_TO_INT() \
((regs.status.carry << 7) | (regs.status.zero << 6) \
| (regs.status.interrupt_disable << 5) | (regs.status.decimal_mode << 4) \
| (regs.status.brk << 3) | (regs.status.unused << 2) \
| (regs.status.overflow << 1) | regs.status.negative)
#define MEMORY_MIRROR(addr) \ #define MEMORY_MIRROR(addr) \
if (addr < 0x2000) \ if (addr < 0x2000) \
@ -108,10 +113,14 @@ opcode_arg(enum addressing_mode mode)
{ {
uint16_t arg, val; uint16_t arg, val;
if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) {
arg = peek(regs.pc++); arg = peek(regs.pc++);
else printf(" %02X\t", arg);
arg = peek16(regs.pc), regs.pc += 2; } else {
arg = peek16(regs.pc);
printf(" %02X %02X\t", peek(regs.pc), peek(regs.pc + 1));
regs.pc += 2;
}
switch (mode) { switch (mode) {
case AM_IMM: case AM_IMM:
@ -129,12 +138,15 @@ opcode_arg(enum addressing_mode mode)
break; break;
case AM_ABS: case AM_ABS:
val = peek16(arg); val = peek16(arg);
printf("$%04X", arg);
break; break;
case AM_ABS_X: case AM_ABS_X:
val = peek16(arg + regs.x); val = peek16(arg + regs.x);
printf("$%04X", arg);
break; break;
case AM_ABS_Y: case AM_ABS_Y:
val = peek16(arg + regs.y); val = peek16(arg + regs.y);
printf("$%04X", arg);
break; break;
case AM_IND_X: case AM_IND_X:
val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256); val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256);
@ -147,8 +159,6 @@ opcode_arg(enum addressing_mode mode)
abort(); abort();
} }
printf("arg: $%04X $%04X\n", arg, val);
return val; return val;
} }
@ -157,10 +167,14 @@ opcode_mem(enum addressing_mode mode)
{ {
uint16_t arg, val; uint16_t arg, val;
if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) {
arg = peek(regs.pc++); arg = peek(regs.pc++);
else printf(" %02X\t", arg);
arg = peek16(regs.pc), regs.pc += 2; } else {
arg = peek16(regs.pc);
printf(" %02X %02X\t", peek(regs.pc), peek(regs.pc + 1));
regs.pc += 2;
}
switch (mode) { switch (mode) {
case AM_ZP: case AM_ZP:
@ -301,6 +315,7 @@ brk(void)
{ {
/* TODO: push regs.pc and regs.status to stack and load IRQ vector */ /* TODO: push regs.pc and regs.status to stack and load IRQ vector */
regs.status.brk = 1; regs.status.brk = 1;
putchar('\n');
exit(0); exit(0);
} }
@ -542,10 +557,7 @@ php(void)
{ {
uint8_t status; uint8_t status;
status = (regs.status.carry << 7) | (regs.status.zero << 6) status = STATUS_TO_INT();
| (regs.status.interrupt_disable << 5) | (regs.status.decimal_mode << 4)
| (regs.status.brk << 3) | (regs.status.unused << 2)
| (regs.status.overflow << 1) | regs.status.negative;
PUSH(status); PUSH(status);
} }
@ -742,678 +754,837 @@ tya(void)
static void static void
interpret(void) interpret(void)
{ {
uint8_t opcode; uint8_t opcode, cycles_;
for (;;) { for (;;) {
opcode = peek(regs.pc++); opcode = peek(regs.pc++);
cycles_ = cycles;
printf("opcode: $%02X @ $%04X\n", opcode, regs.pc - 1); printf("%04X %02X", regs.pc - 1, opcode);
switch (opcode) { switch (opcode) {
case 0x69: case 0x69:
adc(opcode_arg(AM_IMM)); adc(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("ADC");
break; break;
case 0x65: case 0x65:
adc(opcode_arg(AM_ZP)); adc(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("ADC");
break; break;
case 0x75: case 0x75:
adc(opcode_arg(AM_ZP_X)); adc(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("ADC");
break; break;
case 0x6d: case 0x6d:
adc(opcode_arg(AM_ABS)); adc(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("ADC");
break; break;
case 0x7d: case 0x7d:
adc(opcode_arg(AM_ABS_X)); adc(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("ADC");
break; break;
case 0x79: case 0x79:
adc(opcode_arg(AM_ABS_Y)); adc(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("ADC");
break; break;
case 0x72: case 0x72:
adc(opcode_arg(AM_IND)); adc(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("ADC");
break; break;
case 0x61: case 0x61:
adc(opcode_arg(AM_IND_X)); adc(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("ADC");
break; break;
case 0x71: case 0x71:
adc(opcode_arg(AM_IND_Y)); adc(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("ADC");
break; break;
case 0x29: case 0x29:
and(opcode_arg(AM_IMM)); and(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("AND");
break; break;
case 0x25: case 0x25:
and(opcode_arg(AM_ZP)); and(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("AND");
break; break;
case 0x35: case 0x35:
and(opcode_arg(AM_ZP_X)); and(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("AND");
break; break;
case 0x2d: case 0x2d:
and(opcode_arg(AM_ABS)); and(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("AND");
break; break;
case 0x3d: case 0x3d:
and(opcode_arg(AM_ABS_X)); and(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("AND");
break; break;
case 0x39: case 0x39:
and(opcode_arg(AM_ABS_Y)); and(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("AND");
break; break;
case 0x32: case 0x32:
and(opcode_arg(AM_IND)); and(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("AND");
break; break;
case 0x21: case 0x21:
and(opcode_arg(AM_IND_X)); and(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("AND");
break; break;
case 0x31: case 0x31:
and(opcode_arg(AM_IND_Y)); and(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("AND");
break; break;
case 0x0a: case 0x0a:
asl_acc(); asl_acc();
cycles += 2; cycles += 2;
printf("\tASL");
break; break;
case 0x06: case 0x06:
asl(opcode_arg(AM_ZP)); asl(opcode_arg(AM_ZP));
cycles += 5; cycles += 5;
printf("ASL");
break; break;
case 0x16: case 0x16:
asl(opcode_arg(AM_ZP_X)); asl(opcode_arg(AM_ZP_X));
cycles += 6; cycles += 6;
printf("ASL");
break; break;
case 0x0e: case 0x0e:
asl(opcode_arg(AM_ABS)); asl(opcode_arg(AM_ABS));
cycles += 6; cycles += 6;
printf("ASL");
break; break;
case 0x1e: case 0x1e:
asl(opcode_arg(AM_ABS_X)); asl(opcode_arg(AM_ABS_X));
cycles += 6; cycles += 6;
printf("ASL");
break; break;
case 0x90: case 0x90:
bcc(opcode_arg(AM_IMM)); bcc(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BCC");
break; break;
case 0xb0: case 0xb0:
bcs(opcode_arg(AM_IMM)); bcs(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BCS");
break; break;
case 0xf0: case 0xf0:
beq(opcode_arg(AM_IMM)); beq(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BEQ");
break; break;
case 0x89: case 0x89:
bit(opcode_arg(AM_IMM)); bit(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BIT");
break; break;
case 0x24: case 0x24:
bit(opcode_arg(AM_ZP)); bit(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("BIT");
break; break;
case 0x34: case 0x34:
bit(opcode_arg(AM_ZP_X)); bit(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("BIT");
break; break;
case 0x2c: case 0x2c:
bit(opcode_arg(AM_ABS)); bit(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("BIT");
break; break;
case 0x3c: case 0x3c:
bit(opcode_arg(AM_ABS_X)); bit(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("BIT");
break; break;
case 0x30: case 0x30:
bmi(opcode_arg(AM_IMM)); bmi(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BMI");
break; break;
case 0xd0: case 0xd0:
bne(opcode_arg(AM_IMM)); bne(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BNE");
break; break;
case 0x10: case 0x10:
bpl(opcode_arg(AM_IMM)); bpl(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BPL");
break; break;
case 0x00: case 0x00:
brk(); brk();
cycles += 7; cycles += 7;
printf("\tBRK");
break; break;
case 0x50: case 0x50:
bvc(opcode_arg(AM_IMM)); bvc(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BVC");
break; break;
case 0x70: case 0x70:
bvs(opcode_arg(AM_IMM)); bvs(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("BVS");
break; break;
case 0x18: case 0x18:
clc(); clc();
cycles += 2; cycles += 2;
printf("\tCLC");
break; break;
case 0xd8: case 0xd8:
cld(); cld();
cycles += 2; cycles += 2;
printf("\tCLD");
break; break;
case 0x58: case 0x58:
cli(); cli();
cycles += 2; cycles += 2;
printf("\tCLI");
break; break;
case 0xb8: case 0xb8:
clv(); clv();
cycles += 2; cycles += 2;
printf("\tCLV");
break; break;
case 0xc9: case 0xc9:
cmp(opcode_arg(AM_IMM)); cmp(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("CMP");
break; break;
case 0xc5: case 0xc5:
cmp(opcode_arg(AM_ZP)); cmp(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("CMP");
break; break;
case 0xd5: case 0xd5:
cmp(opcode_arg(AM_ZP_X)); cmp(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("CMP");
break; break;
case 0xcd: case 0xcd:
cmp(opcode_arg(AM_ABS)); cmp(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("CMP");
break; break;
case 0xdd: case 0xdd:
cmp(opcode_arg(AM_ABS_X)); cmp(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("CMP");
break; break;
case 0xd9: case 0xd9:
cmp(opcode_arg(AM_ABS_Y)); cmp(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("CMP");
break; break;
case 0xd2: case 0xd2:
cmp(opcode_arg(AM_IND)); cmp(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("CMP");
break; break;
case 0xc1: case 0xc1:
cmp(opcode_arg(AM_IND_X)); cmp(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("CMP");
break; break;
case 0xd1: case 0xd1:
cmp(opcode_arg(AM_IND_Y)); cmp(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("CMP");
break; break;
case 0xe0: case 0xe0:
cpx(opcode_arg(AM_IMM)); cpx(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("CPX");
break; break;
case 0xe4: case 0xe4:
cpx(opcode_arg(AM_ZP)); cpx(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("CPX");
break; break;
case 0xec: case 0xec:
cpx(opcode_arg(AM_ABS)); cpx(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("CPX");
break; break;
case 0xc0: case 0xc0:
cpy(opcode_arg(AM_IMM)); cpy(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("CPY");
break; break;
case 0xc4: case 0xc4:
cpy(opcode_arg(AM_ZP)); cpy(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("CPY");
break; break;
case 0xcc: case 0xcc:
cpy(opcode_arg(AM_ABS)); cpy(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("CPY");
break; break;
case 0xc6: case 0xc6:
dec(opcode_mem(AM_ZP)); dec(opcode_mem(AM_ZP));
cycles += 5; cycles += 5;
printf("DEC");
break; break;
case 0xd6: case 0xd6:
dec(opcode_mem(AM_ZP_X)); dec(opcode_mem(AM_ZP_X));
cycles += 6; cycles += 6;
printf("DEC");
break; break;
case 0xce: case 0xce:
dec(opcode_mem(AM_ABS)); dec(opcode_mem(AM_ABS));
cycles += 6; cycles += 6;
printf("DEC");
break; break;
case 0xde: case 0xde:
dec(opcode_mem(AM_ABS_X)); dec(opcode_mem(AM_ABS_X));
cycles += 7; cycles += 7;
printf("DEC");
break; break;
case 0xca: case 0xca:
dex(); dex();
cycles += 2; cycles += 2;
printf("\tDEX");
break; break;
case 0x88: case 0x88:
dey(); dey();
cycles += 2; cycles += 2;
printf("\tDEY");
break; break;
case 0x49: case 0x49:
eor(opcode_arg(AM_IMM)); eor(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("EOR");
break; break;
case 0x45: case 0x45:
eor(opcode_arg(AM_ZP)); eor(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("EOR");
break; break;
case 0x55: case 0x55:
eor(opcode_arg(AM_ZP_X)); eor(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("EOR");
break; break;
case 0x4d: case 0x4d:
eor(opcode_arg(AM_ABS)); eor(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("EOR");
break; break;
case 0x5d: case 0x5d:
eor(opcode_arg(AM_ABS_X)); eor(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("EOR");
break; break;
case 0x59: case 0x59:
eor(opcode_arg(AM_ABS_Y)); eor(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("EOR");
break; break;
case 0x52: case 0x52:
eor(opcode_arg(AM_IND)); eor(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("EOR");
break; break;
case 0x41: case 0x41:
eor(opcode_arg(AM_IND_X)); eor(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("EOR");
break; break;
case 0x51: case 0x51:
eor(opcode_arg(AM_IND_Y)); eor(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("EOR");
break; break;
case 0xe6: case 0xe6:
inc(opcode_arg(AM_ZP)); inc(opcode_arg(AM_ZP));
cycles += 5; cycles += 5;
printf("INC");
break; break;
case 0xf6: case 0xf6:
inc(opcode_arg(AM_ZP_X)); inc(opcode_arg(AM_ZP_X));
cycles += 6; cycles += 6;
printf("INC");
break; break;
case 0xee: case 0xee:
inc(opcode_arg(AM_ABS)); inc(opcode_arg(AM_ABS));
cycles += 6; cycles += 6;
printf("INC");
break; break;
case 0xfe: case 0xfe:
inc(opcode_arg(AM_ABS_X)); inc(opcode_arg(AM_ABS_X));
cycles += 7; cycles += 7;
printf("INC");
break; break;
case 0xe8: case 0xe8:
inx(); inx();
cycles += 2; cycles += 2;
printf("\tINX");
break; break;
case 0xc8: case 0xc8:
iny(); iny();
cycles += 2; cycles += 2;
printf("\tINY");
break; break;
case 0x4c: case 0x4c:
jmp(opcode_mem(AM_ABS)); jmp(opcode_mem(AM_ABS));
cycles += 3; cycles += 3;
printf("JMP");
break; break;
case 0x6c: case 0x6c:
jmp(opcode_arg(AM_IND)); jmp(opcode_arg(AM_IND));
cycles += 6; cycles += 6;
printf("JMP");
break; break;
case 0x7c: case 0x7c:
jmp(opcode_arg(AM_ABS_X)); jmp(opcode_arg(AM_ABS_X));
cycles += 6; cycles += 6;
printf("JMP");
break; break;
case 0x20: case 0x20:
jsr(opcode_arg(AM_ABS)); jsr(opcode_arg(AM_ABS));
cycles += 6; cycles += 6;
printf("JSR");
break; break;
case 0xa9: case 0xa9:
lda(opcode_arg(AM_IMM)); lda(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("LDA");
break; break;
case 0xa5: case 0xa5:
lda(opcode_arg(AM_ZP)); lda(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("LDA");
break; break;
case 0xb5: case 0xb5:
lda(opcode_arg(AM_ZP_X)); lda(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("LDA");
break; break;
case 0xad: case 0xad:
lda(opcode_arg(AM_ABS)); lda(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("LDA");
break; break;
case 0xbd: case 0xbd:
lda(opcode_arg(AM_ABS_X)); lda(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("LDA");
break; break;
case 0xb9: case 0xb9:
lda(opcode_arg(AM_ABS_Y)); lda(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("LDA");
break; break;
case 0xb2: case 0xb2:
lda(opcode_arg(AM_IND)); lda(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("LDA");
break; break;
case 0xa1: case 0xa1:
lda(opcode_arg(AM_IND_X)); lda(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("LDA");
break; break;
case 0xb1: case 0xb1:
lda(opcode_arg(AM_IND_Y)); lda(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("LDA");
break; break;
case 0xa2: case 0xa2:
ldx(opcode_mem(AM_IMM)); ldx(opcode_mem(AM_IMM));
cycles += 2; cycles += 2;
printf("LDX");
break; break;
case 0xa6: case 0xa6:
ldx(opcode_arg(AM_ZP)); ldx(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("LDX");
break; break;
case 0xb6: case 0xb6:
ldx(opcode_arg(AM_ZP_Y)); ldx(opcode_arg(AM_ZP_Y));
cycles += 4; cycles += 4;
printf("LDX");
break; break;
case 0xae: case 0xae:
ldx(opcode_arg(AM_ABS)); ldx(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("LDX");
break; break;
case 0xbe: case 0xbe:
ldx(opcode_arg(AM_ABS_Y)); ldx(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("LDX");
break; break;
case 0xa0: case 0xa0:
ldy(opcode_arg(AM_IMM)); ldy(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("LDY");
break; break;
case 0xa4: case 0xa4:
ldy(opcode_arg(AM_ZP)); ldy(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("LDY");
break; break;
case 0xb4: case 0xb4:
ldy(opcode_arg(AM_ZP_X)); ldy(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("LDY");
break; break;
case 0xac: case 0xac:
ldy(opcode_arg(AM_ABS)); ldy(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("LDY");
break; break;
case 0xbc: case 0xbc:
ldy(opcode_arg(AM_ABS_X)); ldy(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("LDY");
break; break;
case 0x4a: case 0x4a:
lsr_acc(); lsr_acc();
cycles += 2; cycles += 2;
printf("\tLSR");
break; break;
case 0x46: case 0x46:
lsr(opcode_arg(AM_ZP)); lsr(opcode_arg(AM_ZP));
cycles += 5; cycles += 5;
printf("LSR");
break; break;
case 0x56: case 0x56:
lsr(opcode_arg(AM_ZP_X)); lsr(opcode_arg(AM_ZP_X));
cycles += 6; cycles += 6;
printf("LSR");
break; break;
case 0x4e: case 0x4e:
lsr(opcode_arg(AM_ABS)); lsr(opcode_arg(AM_ABS));
cycles += 6; cycles += 6;
printf("LSR");
break; break;
case 0x5e: case 0x5e:
lsr(opcode_arg(AM_ABS_X)); lsr(opcode_arg(AM_ABS_X));
cycles += 6; cycles += 6;
printf("LSR");
break; break;
case 0xea: case 0xea:
nop(); nop();
cycles += 2; cycles += 2;
printf("\tNOP");
break; break;
case 0x09: case 0x09:
ora(opcode_arg(AM_IMM)); ora(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("ORA");
break; break;
case 0x05: case 0x05:
ora(opcode_arg(AM_ZP)); ora(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("ORA");
break; break;
case 0x15: case 0x15:
ora(opcode_arg(AM_ZP_X)); ora(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("ORA");
break; break;
case 0x0d: case 0x0d:
ora(opcode_arg(AM_ABS)); ora(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("ORA");
break; break;
case 0x1d: case 0x1d:
ora(opcode_arg(AM_ABS_X)); ora(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("ORA");
break; break;
case 0x19: case 0x19:
ora(opcode_arg(AM_ABS_Y)); ora(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("ORA");
break; break;
case 0x12: case 0x12:
ora(opcode_arg(AM_IND)); ora(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("ORA");
break; break;
case 0x01: case 0x01:
ora(opcode_arg(AM_IND_X)); ora(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("ORA");
break; break;
case 0x11: case 0x11:
ora(opcode_arg(AM_IND_Y)); ora(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("ORA");
break; break;
case 0x48: case 0x48:
pha(); pha();
cycles += 3; cycles += 3;
printf("\tPHA");
break; break;
case 0x08: case 0x08:
php(); php();
cycles += 3; cycles += 3;
printf("\tPHP");
break; break;
case 0x68: case 0x68:
pla(); pla();
cycles += 4; cycles += 4;
printf("\tPLA");
break; break;
case 0x28: case 0x28:
plp(); plp();
cycles += 4; cycles += 4;
printf("\tPLP");
break; break;
case 0x2a: case 0x2a:
rol_acc(); rol_acc();
cycles += 2; cycles += 2;
printf("\tROL");
break; break;
case 0x26: case 0x26:
rol(opcode_arg(AM_ZP)); rol(opcode_arg(AM_ZP));
cycles += 5; cycles += 5;
printf("ROL");
break; break;
case 0x36: case 0x36:
rol(opcode_arg(AM_ZP_X)); rol(opcode_arg(AM_ZP_X));
cycles += 6; cycles += 6;
printf("ROL");
break; break;
case 0x2e: case 0x2e:
rol(opcode_arg(AM_ABS)); rol(opcode_arg(AM_ABS));
cycles += 6; cycles += 6;
printf("ROL");
break; break;
case 0x3e: case 0x3e:
rol(opcode_arg(AM_ABS_X)); rol(opcode_arg(AM_ABS_X));
cycles += 6; cycles += 6;
printf("ROL");
break; break;
case 0x6a: case 0x6a:
ror_acc(); ror_acc();
cycles += 2; cycles += 2;
printf("\tROR");
break; break;
case 0x66: case 0x66:
ror(opcode_arg(AM_ZP)); ror(opcode_arg(AM_ZP));
cycles += 5; cycles += 5;
printf("ROR");
break; break;
case 0x76: case 0x76:
ror(opcode_arg(AM_ZP_X)); ror(opcode_arg(AM_ZP_X));
cycles += 6; cycles += 6;
printf("ROR");
break; break;
case 0x6e: case 0x6e:
ror(opcode_arg(AM_ABS)); ror(opcode_arg(AM_ABS));
cycles += 6; cycles += 6;
printf("ROR");
break; break;
case 0x7e: case 0x7e:
ror(opcode_arg(AM_ABS_X)); ror(opcode_arg(AM_ABS_X));
cycles += 6; cycles += 6;
printf("ROR");
break; break;
case 0x40: case 0x40:
rti(); rti();
cycles += 6; cycles += 6;
printf("\tRTI");
break; break;
case 0x60: case 0x60:
rts(); rts();
cycles += 6; cycles += 6;
printf("\tRTS");
break; break;
case 0xe9: case 0xe9:
sbc(opcode_arg(AM_IMM)); sbc(opcode_arg(AM_IMM));
cycles += 2; cycles += 2;
printf("SBC");
break; break;
case 0xe5: case 0xe5:
sbc(opcode_arg(AM_ZP)); sbc(opcode_arg(AM_ZP));
cycles += 3; cycles += 3;
printf("SBC");
break; break;
case 0xf5: case 0xf5:
sbc(opcode_arg(AM_ZP_X)); sbc(opcode_arg(AM_ZP_X));
cycles += 4; cycles += 4;
printf("SBC");
break; break;
case 0xed: case 0xed:
sbc(opcode_arg(AM_ABS)); sbc(opcode_arg(AM_ABS));
cycles += 4; cycles += 4;
printf("SBC");
break; break;
case 0xfd: case 0xfd:
sbc(opcode_arg(AM_ABS_X)); sbc(opcode_arg(AM_ABS_X));
cycles += 4; cycles += 4;
printf("SBC");
break; break;
case 0xf9: case 0xf9:
sbc(opcode_arg(AM_ABS_Y)); sbc(opcode_arg(AM_ABS_Y));
cycles += 4; cycles += 4;
printf("SBC");
break; break;
case 0xf2: case 0xf2:
sbc(opcode_arg(AM_IND)); sbc(opcode_arg(AM_IND));
cycles += 5; cycles += 5;
printf("SBC");
break; break;
case 0xe1: case 0xe1:
sbc(opcode_arg(AM_IND_X)); sbc(opcode_arg(AM_IND_X));
cycles += 6; cycles += 6;
printf("SBC");
break; break;
case 0xf1: case 0xf1:
sbc(opcode_arg(AM_IND_Y)); sbc(opcode_arg(AM_IND_Y));
cycles += 5; cycles += 5;
printf("SBC");
break; break;
case 0x38: case 0x38:
sec(); sec();
cycles += 2; cycles += 2;
printf("\tSEC");
break; break;
case 0xf8: case 0xf8:
sed(); sed();
cycles += 2; cycles += 2;
printf("\tSED");
break; break;
case 0x78: case 0x78:
sei(); sei();
cycles += 2; cycles += 2;
printf("\tSEI");
break; break;
case 0x85: case 0x85:
sta(opcode_mem(AM_ZP)); sta(opcode_mem(AM_ZP));
cycles += 4; cycles += 4;
printf("STA");
break; break;
case 0x95: case 0x95:
sta(opcode_mem(AM_ZP_X)); sta(opcode_mem(AM_ZP_X));
cycles += 5; cycles += 5;
printf("STA");
break; break;
case 0x8d: case 0x8d:
sta(opcode_mem(AM_ABS)); sta(opcode_mem(AM_ABS));
cycles += 5; cycles += 5;
printf("STA");
break; break;
case 0x9d: case 0x9d:
sta(opcode_mem(AM_ABS_X)); sta(opcode_mem(AM_ABS_X));
cycles += 6; cycles += 6;
printf("STA");
break; break;
case 0x99: case 0x99:
sta(opcode_mem(AM_ABS_Y)); sta(opcode_mem(AM_ABS_Y));
cycles += 6; cycles += 6;
printf("STA");
break; break;
case 0x92: case 0x92:
sta(opcode_mem(AM_IND)); sta(opcode_mem(AM_IND));
cycles += 6; cycles += 6;
printf("STA");
break; break;
case 0x81: case 0x81:
sta(opcode_mem(AM_IND_X)); sta(opcode_mem(AM_IND_X));
cycles += 7; cycles += 7;
printf("STA");
break; break;
case 0x91: case 0x91:
sta(opcode_mem(AM_IND_Y)); sta(opcode_mem(AM_IND_Y));
cycles += 7; cycles += 7;
printf("STA");
break; break;
case 0x86: case 0x86:
stx(opcode_mem(AM_ZP)); stx(opcode_mem(AM_ZP));
cycles += 4; cycles += 4;
printf("STX");
break; break;
case 0x96: case 0x96:
stx(opcode_mem(AM_ZP_Y)); stx(opcode_mem(AM_ZP_Y));
cycles += 5; cycles += 5;
printf("STX");
break; break;
case 0x8e: case 0x8e:
stx(opcode_mem(AM_ABS)); stx(opcode_mem(AM_ABS));
cycles += 5; cycles += 5;
printf("STX");
break; break;
case 0x84: case 0x84:
sty(opcode_mem(AM_ZP)); sty(opcode_mem(AM_ZP));
cycles += 4; cycles += 4;
printf("STY");
break; break;
case 0x94: case 0x94:
sty(opcode_mem(AM_ZP_X)); sty(opcode_mem(AM_ZP_X));
cycles += 5; cycles += 5;
printf("STY");
break; break;
case 0x8c: case 0x8c:
sty(opcode_mem(AM_ABS)); sty(opcode_mem(AM_ABS));
cycles += 5; cycles += 5;
printf("STY");
break; break;
case 0xaa: case 0xaa:
tax(); tax();
cycles += 2; cycles += 2;
printf("\tTAX");
break; break;
case 0xa8: case 0xa8:
tay(); tay();
cycles += 2; cycles += 2;
printf("\tTAY");
break; break;
case 0xba: case 0xba:
tsx(); tsx();
cycles += 2; cycles += 2;
printf("\tTSX");
break; break;
case 0x8a: case 0x8a:
txa(); txa();
cycles += 2; cycles += 2;
printf("\tTXA");
break; break;
case 0x9a: case 0x9a:
txs(); txs();
cycles += 2; cycles += 2;
printf("\tTXS");
break; break;
case 0x98: case 0x98:
tya(); tya();
cycles += 2; cycles += 2;
printf("\tTYA");
break; break;
default: default:
printf("opcode $%02X not implemented\n", opcode); printf("opcode $%02X not implemented\n", opcode);
break; break;
} }
printf("status: %i%i%i%i%i%i%i%i\n", regs.status.carry, printf("%50c:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n", 'A',
regs.status.zero, regs.status.interrupt_disable, regs.a, regs.x, regs.y, STATUS_TO_INT(), regs.sp, cycles_);
regs.status.decimal_mode, regs.status.brk,
regs.status.unused, regs.status.overflow,
regs.status.negative);
printf("A: $%02X, X: $%02X, Y: $%02X, SP: $%02X, PC: $%04X\n",
regs.a, regs.x, regs.y, regs.sp, regs.pc);
} }
} }
@ -1470,16 +1641,6 @@ main(int argc, char *argv[])
memwrite16(0xFFFC, 0xC000); memwrite16(0xFFFC, 0xC000);
regs.pc = 0xC000; regs.pc = 0xC000;
printf("status: %i%i%i%i%i%i%i%i\n", regs.status.carry,
regs.status.zero, regs.status.interrupt_disable,
regs.status.decimal_mode, regs.status.brk,
regs.status.unused, regs.status.overflow,
regs.status.negative);
printf("A: $%02X, X: $%02X, Y: $%02X, SP: $%02X, PC: $%02X\n",
regs.a, regs.x, regs.y, regs.sp, regs.pc);
putchar('\n');
interpret(); interpret();
free_rom(&rom); free_rom(&rom);