summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-06-28 14:33:47 -0400
committervin <git@vineetk.net>2024-06-28 18:15:34 -0400
commit3977ab2a5d41c939f480d91265328ca62ba7be1d (patch)
treeec31f1430dc0c73e03f7e3b27e0622d95e3d0c37 /cpu.c
parentc1a42045e69797987ffa654da8dc76d577ac2629 (diff)
improve logging and JMP indirect
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c639
1 files changed, 503 insertions, 136 deletions
diff --git a/cpu.c b/cpu.c
index 4528ff5..6d8c599 100644
--- a/cpu.c
+++ b/cpu.c
@@ -50,6 +50,8 @@ struct registers regs = {0};
struct Rom rom = {0};
enum addressing_mode {
+ AM_ACC,
+ AM_IMPLICIT,
AM_IMM,
AM_ZP,
AM_ZP_X,
@@ -164,7 +166,7 @@ opcode_mem(enum addressing_mode mode)
{
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 && mode != AM_IND && mode) {
arg = peek(regs.pc++);
printf(" %02X\t", arg);
} else {
@@ -281,12 +283,14 @@ beq(uint8_t arg)
regs.pc += arg;
}
-static void
+static uint8_t
bit(uint8_t arg)
{
regs.status.zero = (regs.a & arg) == 0;
regs.status.overflow = (arg & (1 << 6)) != 0;
STATUS_UPDATE_NEGATIVE(arg);
+
+ return regs.a & arg;
}
static void
@@ -315,8 +319,7 @@ brk(void)
{
/* TODO: push regs.pc and regs.status to stack and load IRQ vector */
regs.status.brk = 1;
- putchar('\n');
- exit(0);
+ // exit(0);
}
static void
@@ -682,22 +685,31 @@ sei(void)
regs.status.interrupt_disable = 1;
}
-static void
+static uint8_t
sta(uint16_t mem)
{
+ uint8_t tmp = peek(mem);
memwrite(mem, regs.a);
+
+ return tmp;
}
-static void
+static uint8_t
stx(uint16_t mem)
{
+ uint8_t tmp = peek(mem);
memwrite(mem, regs.x);
+
+ return tmp;
}
-static void
+static uint8_t
sty(uint16_t mem)
{
+ uint8_t tmp = peek(mem);
memwrite(mem, regs.y);
+
+ return tmp;
}
static void
@@ -754,787 +766,1092 @@ tya(void)
static void
interpret(void)
{
- uint8_t opcode;
+ uint8_t opcode, did_memwrite, ret;
+ uint16_t arg, mem, deref;
uint32_t cycles_;
+ enum addressing_mode mode;
for (;;) {
opcode = peek(regs.pc++);
cycles_ = cycles;
+ did_memwrite = 0;
printf("%04X %02X", regs.pc - 1, opcode);
switch (opcode) {
case 0x69:
- adc(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 2;
printf("ADC");
break;
case 0x65:
- adc(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 3;
printf("ADC");
break;
case 0x75:
- adc(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 4;
printf("ADC");
break;
case 0x6d:
- adc(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 4;
printf("ADC");
break;
case 0x7d:
- adc(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 4;
printf("ADC");
break;
case 0x79:
- adc(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 4;
printf("ADC");
break;
case 0x61:
- adc(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 6;
printf("ADC");
break;
case 0x71:
- adc(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ adc(arg);
cycles += 5;
printf("ADC");
break;
case 0x29:
- and(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 2;
printf("AND");
break;
case 0x25:
- and(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 3;
printf("AND");
break;
case 0x35:
- and(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 4;
printf("AND");
break;
case 0x2d:
- and(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 4;
printf("AND");
break;
case 0x3d:
- and(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 4;
printf("AND");
break;
case 0x39:
- and(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 4;
printf("AND");
break;
case 0x21:
- and(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 6;
printf("AND");
break;
case 0x31:
- and(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ and(arg);
cycles += 5;
printf("AND");
break;
case 0x0a:
+ mode = AM_ACC;
asl_acc();
cycles += 2;
printf("\tASL");
break;
case 0x06:
- asl(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ asl(arg);
cycles += 5;
printf("ASL");
break;
case 0x16:
- asl(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ asl(arg);
cycles += 6;
printf("ASL");
break;
case 0x0e:
- asl(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ asl(arg);
cycles += 6;
printf("ASL");
break;
case 0x1e:
- asl(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ asl(arg);
cycles += 6;
printf("ASL");
break;
case 0x90:
- bcc(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bcc(arg);
cycles += 2;
printf("BCC");
break;
case 0xb0:
- bcs(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bcs(arg);
cycles += 2;
printf("BCS");
break;
case 0xf0:
- beq(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ beq(arg);
cycles += 2;
printf("BEQ");
break;
case 0x89:
- bit(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ did_memwrite = 1;
+ ret = bit(arg);
cycles += 2;
printf("BIT");
break;
case 0x24:
- bit(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ did_memwrite = 1;
+ ret = bit(arg);
cycles += 3;
printf("BIT");
break;
case 0x34:
- bit(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ did_memwrite = 1;
+ ret = bit(arg);
cycles += 4;
printf("BIT");
break;
case 0x2c:
- bit(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ did_memwrite = 1;
+ ret = bit(arg);
cycles += 4;
printf("BIT");
break;
case 0x3c:
- bit(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ did_memwrite = 1;
+ ret = bit(arg);
cycles += 4;
printf("BIT");
break;
case 0x30:
- bmi(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bmi(arg);
cycles += 2;
printf("BMI");
break;
case 0xd0:
- bne(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bne(arg);
cycles += 2;
printf("BNE");
break;
case 0x10:
- bpl(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bpl(arg);
cycles += 2;
printf("BPL");
break;
case 0x00:
+ mode = AM_IMPLICIT;
brk();
cycles += 7;
printf("\tBRK");
- break;
+ goto loop_exit;
case 0x50:
- bvc(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bvc(arg);
cycles += 2;
printf("BVC");
break;
case 0x70:
- bvs(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ bvs(arg);
cycles += 2;
printf("BVS");
break;
case 0x18:
+ mode = AM_IMPLICIT;
clc();
cycles += 2;
printf("\tCLC");
break;
case 0xd8:
+ mode = AM_IMPLICIT;
cld();
cycles += 2;
printf("\tCLD");
break;
case 0x58:
+ mode = AM_IMPLICIT;
cli();
cycles += 2;
printf("\tCLI");
break;
case 0xb8:
+ mode = AM_IMPLICIT;
clv();
cycles += 2;
printf("\tCLV");
break;
case 0xc9:
- cmp(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 2;
printf("CMP");
break;
case 0xc5:
- cmp(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 3;
printf("CMP");
break;
case 0xd5:
- cmp(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 4;
printf("CMP");
break;
case 0xcd:
- cmp(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 4;
printf("CMP");
break;
case 0xdd:
- cmp(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 4;
printf("CMP");
break;
case 0xd9:
- cmp(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 4;
printf("CMP");
break;
case 0xc1:
- cmp(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 6;
printf("CMP");
break;
case 0xd1:
- cmp(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ cmp(arg);
cycles += 5;
printf("CMP");
break;
case 0xe0:
- cpx(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ cpx(arg);
cycles += 2;
printf("CPX");
break;
case 0xe4:
- cpx(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ cpx(arg);
cycles += 3;
printf("CPX");
break;
case 0xec:
- cpx(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ cpx(arg);
cycles += 4;
printf("CPX");
break;
case 0xc0:
- cpy(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ cpy(arg);
cycles += 2;
printf("CPY");
break;
case 0xc4:
- cpy(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ cpy(arg);
cycles += 3;
printf("CPY");
break;
case 0xcc:
- cpy(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ cpy(arg);
cycles += 4;
printf("CPY");
break;
case 0xc6:
- dec(opcode_mem(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_mem(mode);
+ dec(arg);
cycles += 5;
printf("DEC");
break;
case 0xd6:
- dec(opcode_mem(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_mem(mode);
+ dec(arg);
cycles += 6;
printf("DEC");
break;
case 0xce:
- dec(opcode_mem(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_mem(mode);
+ dec(arg);
cycles += 6;
printf("DEC");
break;
case 0xde:
- dec(opcode_mem(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_mem(mode);
+ dec(arg);
cycles += 7;
printf("DEC");
break;
case 0xca:
+ mode = AM_IMPLICIT;
dex();
cycles += 2;
printf("\tDEX");
break;
case 0x88:
+ mode = AM_IMPLICIT;
dey();
cycles += 2;
printf("\tDEY");
break;
case 0x49:
- eor(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 2;
printf("EOR");
break;
case 0x45:
- eor(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 3;
printf("EOR");
break;
case 0x55:
- eor(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 4;
printf("EOR");
break;
case 0x4d:
- eor(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 4;
printf("EOR");
break;
case 0x5d:
- eor(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 4;
printf("EOR");
break;
case 0x59:
- eor(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 4;
printf("EOR");
break;
case 0x41:
- eor(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 6;
printf("EOR");
break;
case 0x51:
- eor(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ eor(arg);
cycles += 5;
printf("EOR");
break;
case 0xe6:
- inc(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ inc(arg);
cycles += 5;
printf("INC");
break;
case 0xf6:
- inc(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ inc(arg);
cycles += 6;
printf("INC");
break;
case 0xee:
- inc(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ inc(arg);
cycles += 6;
printf("INC");
break;
case 0xfe:
- inc(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ inc(arg);
cycles += 7;
printf("INC");
break;
case 0xe8:
+ mode = AM_IMPLICIT;
inx();
cycles += 2;
printf("\tINX");
break;
case 0xc8:
+ mode = AM_IMPLICIT;
iny();
cycles += 2;
printf("\tINY");
break;
case 0x4c:
- jmp(opcode_mem(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_mem(mode);
+ jmp(arg);
cycles += 3;
printf("JMP");
break;
case 0x6c:
- jmp(opcode_mem(AM_IND));
+ mode = AM_IND;
+ mem = peek16(regs.pc);
+ deref = peek(mem);
+ arg = opcode_mem(mode);
+ //jmp(arg);
+ jmp(deref);
cycles += 6;
printf("JMP");
break;
case 0x7c:
- jmp(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ jmp(arg);
cycles += 6;
printf("JMP");
break;
case 0x20:
- jsr(opcode_mem(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_mem(mode);
+ jsr(arg);
cycles += 6;
printf("JSR");
break;
case 0xa9:
- lda(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 2;
printf("LDA");
break;
case 0xa5:
- lda(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 3;
printf("LDA");
break;
case 0xb5:
- lda(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 4;
printf("LDA");
break;
case 0xad:
- lda(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 4;
printf("LDA");
break;
case 0xbd:
- lda(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 4;
printf("LDA");
break;
case 0xb9:
- lda(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 4;
printf("LDA");
break;
case 0xa1:
- lda(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 6;
printf("LDA");
break;
case 0xb1:
- lda(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ lda(arg);
cycles += 5;
printf("LDA");
break;
case 0xa2:
- ldx(opcode_mem(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_mem(mode);
+ ldx(arg);
cycles += 2;
printf("LDX");
break;
case 0xa6:
- ldx(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ ldx(arg);
cycles += 3;
printf("LDX");
break;
case 0xb6:
- ldx(opcode_arg(AM_ZP_Y));
+ mode = AM_ZP_Y;
+ arg = opcode_arg(mode);
+ ldx(arg);
cycles += 4;
printf("LDX");
break;
case 0xae:
- ldx(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ ldx(arg);
cycles += 4;
printf("LDX");
break;
case 0xbe:
- ldx(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ ldx(arg);
cycles += 4;
printf("LDX");
break;
case 0xa0:
- ldy(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ ldy(arg);
cycles += 2;
printf("LDY");
break;
case 0xa4:
- ldy(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ ldy(arg);
cycles += 3;
printf("LDY");
break;
case 0xb4:
- ldy(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ ldy(arg);
cycles += 4;
printf("LDY");
break;
case 0xac:
- ldy(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ ldy(arg);
cycles += 4;
printf("LDY");
break;
case 0xbc:
- ldy(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ ldy(arg);
cycles += 4;
printf("LDY");
break;
case 0x4a:
+ mode = AM_ACC;
lsr_acc();
cycles += 2;
printf("\tLSR");
break;
case 0x46:
- lsr(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ lsr(arg);
cycles += 5;
printf("LSR");
break;
case 0x56:
- lsr(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ lsr(arg);
cycles += 6;
printf("LSR");
break;
case 0x4e:
- lsr(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ lsr(arg);
cycles += 6;
printf("LSR");
break;
case 0x5e:
- lsr(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ lsr(arg);
cycles += 6;
printf("LSR");
break;
case 0xea:
+ mode = AM_IMPLICIT;
nop();
cycles += 2;
printf("\tNOP");
break;
case 0x09:
- ora(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 2;
printf("ORA");
break;
case 0x05:
- ora(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 3;
printf("ORA");
break;
case 0x15:
- ora(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 4;
printf("ORA");
break;
case 0x0d:
- ora(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 4;
printf("ORA");
break;
case 0x1d:
- ora(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 4;
printf("ORA");
break;
case 0x19:
- ora(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 4;
printf("ORA");
break;
case 0x01:
- ora(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 6;
printf("ORA");
break;
case 0x11:
- ora(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ ora(arg);
cycles += 5;
printf("ORA");
break;
case 0x48:
+ mode = AM_IMPLICIT;
pha();
cycles += 3;
printf("\tPHA");
break;
case 0x08:
+ mode = AM_IMPLICIT;
php();
cycles += 3;
printf("\tPHP");
break;
case 0x68:
+ mode = AM_IMPLICIT;
pla();
cycles += 4;
printf("\tPLA");
break;
case 0x28:
+ mode = AM_IMPLICIT;
plp();
cycles += 4;
printf("\tPLP");
break;
case 0x2a:
+ mode = AM_ACC;
rol_acc();
cycles += 2;
printf("\tROL");
break;
case 0x26:
- rol(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ rol(arg);
cycles += 5;
printf("ROL");
break;
case 0x36:
- rol(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ rol(arg);
cycles += 6;
printf("ROL");
break;
case 0x2e:
- rol(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ rol(arg);
cycles += 6;
printf("ROL");
break;
case 0x3e:
- rol(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ rol(arg);
cycles += 6;
printf("ROL");
break;
case 0x6a:
+ mode = AM_ACC;
ror_acc();
cycles += 2;
printf("\tROR");
break;
case 0x66:
- ror(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ ror(arg);
cycles += 5;
printf("ROR");
break;
case 0x76:
- ror(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ ror(arg);
cycles += 6;
printf("ROR");
break;
case 0x6e:
- ror(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ ror(arg);
cycles += 6;
printf("ROR");
break;
case 0x7e:
- ror(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ ror(arg);
cycles += 6;
printf("ROR");
break;
case 0x40:
+ mode = AM_IMPLICIT;
rti();
cycles += 6;
printf("\tRTI");
break;
case 0x60:
+ mode = AM_IMPLICIT;
rts();
cycles += 6;
printf("\tRTS");
break;
case 0xe9:
- sbc(opcode_arg(AM_IMM));
+ mode = AM_IMM;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 2;
printf("SBC");
break;
case 0xe5:
- sbc(opcode_arg(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 3;
printf("SBC");
break;
case 0xf5:
- sbc(opcode_arg(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 4;
printf("SBC");
break;
case 0xed:
- sbc(opcode_arg(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 4;
printf("SBC");
break;
case 0xfd:
- sbc(opcode_arg(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 4;
printf("SBC");
break;
case 0xf9:
- sbc(opcode_arg(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 4;
printf("SBC");
break;
case 0xe1:
- sbc(opcode_arg(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 6;
printf("SBC");
break;
case 0xf1:
- sbc(opcode_arg(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_arg(mode);
+ sbc(arg);
cycles += 5;
printf("SBC");
break;
case 0x38:
+ mode = AM_IMPLICIT;
sec();
cycles += 2;
printf("\tSEC");
break;
case 0xf8:
+ mode = AM_IMPLICIT;
sed();
cycles += 2;
printf("\tSED");
break;
case 0x78:
+ mode = AM_IMPLICIT;
sei();
cycles += 2;
printf("\tSEI");
break;
case 0x85:
- sta(opcode_mem(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 4;
printf("STA");
break;
case 0x95:
- sta(opcode_mem(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 5;
printf("STA");
break;
case 0x8d:
- sta(opcode_mem(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 5;
printf("STA");
break;
case 0x9d:
- sta(opcode_mem(AM_ABS_X));
+ mode = AM_ABS_X;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 6;
printf("STA");
break;
case 0x99:
- sta(opcode_mem(AM_ABS_Y));
+ mode = AM_ABS_Y;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 6;
printf("STA");
break;
case 0x81:
- sta(opcode_mem(AM_IND_X));
+ mode = AM_IND_X;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 7;
printf("STA");
break;
case 0x91:
- sta(opcode_mem(AM_IND_Y));
+ mode = AM_IND_Y;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sta(arg);
cycles += 7;
printf("STA");
break;
case 0x86:
- stx(opcode_mem(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = stx(arg);
cycles += 4;
printf("STX");
break;
case 0x96:
- stx(opcode_mem(AM_ZP_Y));
+ mode = AM_ZP_Y;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = stx(arg);
cycles += 5;
printf("STX");
break;
case 0x8e:
- stx(opcode_mem(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = stx(arg);
cycles += 5;
printf("STX");
break;
case 0x84:
- sty(opcode_mem(AM_ZP));
+ mode = AM_ZP;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sty(arg);
cycles += 4;
printf("STY");
break;
case 0x94:
- sty(opcode_mem(AM_ZP_X));
+ mode = AM_ZP_X;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sty(arg);
cycles += 5;
printf("STY");
break;
case 0x8c:
- sty(opcode_mem(AM_ABS));
+ mode = AM_ABS;
+ arg = opcode_mem(mode);
+ did_memwrite = 1;
+ ret = sty(arg);
cycles += 5;
printf("STY");
break;
case 0xaa:
+ mode = AM_IMPLICIT;
tax();
cycles += 2;
printf("\tTAX");
break;
case 0xa8:
+ mode = AM_IMPLICIT;
tay();
cycles += 2;
printf("\tTAY");
break;
case 0xba:
+ mode = AM_IMPLICIT;
tsx();
cycles += 2;
printf("\tTSX");
break;
case 0x8a:
+ mode = AM_IMPLICIT;
txa();
cycles += 2;
printf("\tTXA");
break;
case 0x9a:
+ mode = AM_IMPLICIT;
txs();
cycles += 2;
printf("\tTXS");
break;
case 0x98:
+ mode = AM_IMPLICIT;
tya();
cycles += 2;
printf("\tTYA");
@@ -1544,9 +1861,56 @@ interpret(void)
break;
}
- printf("%50c:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n", 'A',
+ switch (mode) {
+ case AM_IMM:
+ printf(" #$%02X", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t");
+ break;
+ case AM_ZP:
+ printf(" $%02X", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t\t");
+ break;
+ case AM_ZP_X:
+ printf(" $%02X,X", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t\t");
+ break;
+ case AM_ZP_Y:
+ printf(" $%02X,Y", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t\t");
+ break;
+ case AM_ABS:
+ printf(" $%04X", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t");
+ break;
+ case AM_ABS_X:
+ printf(" $%04X,X", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t");
+ break;
+ case AM_ABS_Y:
+ printf(" $%04X,Y", arg);
+ if (did_memwrite) printf(" = %02X\t\t\t", ret);
+ else printf("\t\t\t");
+ break;
+ case AM_IND:
+ printf(" ($%04X) = %04X\t\t", mem, deref);
+ break;
+ case AM_ACC:
+ case AM_IMPLICIT:
+ default:
+ printf("\t\t\t\t");
+ break;
+ }
+
+ printf("A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n",
regs.a, regs.x, regs.y, STATUS_TO_INT(), regs.sp, cycles_);
}
+loop_exit:
}
/* https://www.nesdev.org/wiki/CPU_power_up_state */
@@ -1604,6 +1968,9 @@ main(int argc, char *argv[])
interpret();
+ printf("\n$02 = %02X\n", memory[0x02]);
+ printf("$03 = %02X\n", memory[0x03]);
+
free_rom(&rom);
return 0;