From 3977ab2a5d41c939f480d91265328ca62ba7be1d Mon Sep 17 00:00:00 2001 From: vin Date: Fri, 28 Jun 2024 14:33:47 -0400 Subject: [PATCH] improve logging and JMP indirect --- cpu.c | 639 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file 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;