diff --git a/cpu.c b/cpu.c index 08c6119..86fbcb0 100644 --- a/cpu.c +++ b/cpu.c @@ -62,49 +62,58 @@ peek16(uint16_t addr) return (uint16_t)memory[addr] | ((uint16_t)memory[addr + 1] << 8); } -void -adc(enum addressing_mode mode) +uint8_t +opmode_arg(enum addressing_mode mode) { uint8_t arg, val; - uint16_t sum; // 16-bit sum makes it easier to determine carry flag if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) arg = peek(regs.pc++); else - arg = peek16(regs.pc++); + arg = peek16(regs.pc), regs.pc += 2; switch (mode) { - case AM_IMM: /* $69 */ + case AM_IMM: val = arg; break; - case AM_ZP: /* $65 */ + case AM_ZP: val = peek(arg % 256); break; - case AM_ABS: /* $6D */ - val = peek16(arg); - break; - case AM_ZP_X: /* $75 */ + case AM_ZP_X: val = peek((arg + regs.x) % 256); break; - case AM_ABS_X: /* $7D */ + case AM_ZP_Y: + val = peek((arg + regs.y) % 256); + break; + case AM_ABS: + val = peek16(arg); + break; + case AM_ABS_X: val = peek16(arg + regs.x); break; - case AM_ABS_Y: /* $79 */ + case AM_ABS_Y: val = peek16(arg + regs.y); break; - case AM_IND_X: /* $61 */ + case AM_IND_X: val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256); break; - case AM_IND_Y: /* $71 */ + case AM_IND_Y: val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y); break; default: - fprintf(stderr, "INVALID ADC ADDRESSING MODE\n"); + fprintf(stderr, "INVALID ADDRESSING MODE\n"); abort(); - return; } - sum = regs.a + val + regs.status.carry; + return val; +} + +void +adc(uint8_t arg) +{ + uint16_t sum; // 16-bit sum makes it easier to determine carry flag + + sum = regs.a + arg + regs.status.carry; regs.a = sum & 0xFF; regs.status.carry = sum > 0xFF; @@ -144,48 +153,10 @@ inx(void) } void -lda(enum addressing_mode mode) +lda(uint8_t arg) { - uint8_t arg, val; - - if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) - arg = peek(regs.pc++); - else - arg = peek16(regs.pc++); - - switch (mode) { - case AM_IMM: /* $A9 */ - val = arg; - break; - case AM_ZP: /* $A5 */ - val = peek(arg % 256); - break; - case AM_ABS: /* $AD */ - val = peek16(arg); - break; - case AM_ZP_X: /* $B5 */ - val = peek((arg + regs.x) % 256); - break; - case AM_ABS_X: /* $BD */ - val = peek16(arg + regs.x); - break; - case AM_ABS_Y: /* $B9 */ - val = peek16(arg + regs.y); - break; - case AM_IND_X: /* $A1 */ - val = peek(peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256); - break; - case AM_IND_Y: /* $B1 */ - val = peek(peek(arg) + peek((arg + 1) % 256) * 256 + regs.y); - break; - default: - fprintf(stderr, "INVALID LDA ADDRESSING MODE\n"); - abort(); - return; - } - printf("arg1 $%02X\n", arg); - regs.a = val; + regs.a = arg; STATUS_UPDATE_ZERO(regs.a); STATUS_UPDATE_NEGATIVE(regs.a); @@ -206,55 +177,55 @@ interpret(void) brk(); return; case 0x61: - adc(AM_IND_X); + adc(opmode_arg(AM_IND_X)); break; case 0x65: - adc(AM_ZP); + adc(opmode_arg(AM_ZP)); break; case 0x69: - adc(AM_IMM); + adc(opmode_arg(AM_IMM)); break; case 0x6D: - adc(AM_ABS); + adc(opmode_arg(AM_ABS)); break; case 0x71: - adc(AM_IND_Y); + adc(opmode_arg(AM_IND_Y)); break; case 0x75: - adc(AM_ZP_X); + adc(opmode_arg(AM_ZP_X)); break; case 0x79: - adc(AM_ABS_Y); + adc(opmode_arg(AM_ABS_Y)); break; case 0x7D: - adc(AM_ABS_X); + adc(opmode_arg(AM_ABS_X)); break; case 0xa1: - lda(AM_IND_X); + lda(opmode_arg(AM_IND_X)); break; case 0xa5: - lda(AM_ZP); + lda(opmode_arg(AM_ZP)); break; case 0xa9: - lda(AM_IMM); + lda(opmode_arg(AM_IMM)); break; case 0xaa: tax(); break; case 0xad: - lda(AM_ABS); + lda(opmode_arg(AM_ABS)); break; case 0xb1: - lda(AM_IND_Y); + lda(opmode_arg(AM_IND_Y)); break; case 0xb5: - lda(AM_ZP_X); + lda(opmode_arg(AM_ZP_X)); break; case 0xb9: - lda(AM_ABS_Y); + lda(opmode_arg(AM_ABS_Y)); break; case 0xbd: - lda(AM_ABS_X); + lda(opmode_arg(AM_ABS_X)); break; case 0xe8: inx();