diff --git a/cpu.c b/cpu.c index 076e887..65e60d4 100644 --- a/cpu.c +++ b/cpu.c @@ -67,7 +67,7 @@ peek16(uint16_t addr) static void memwrite(uint16_t addr, uint8_t byte) { - memory[addr] = b; + memory[addr] = byte; } static void @@ -125,6 +125,50 @@ opcode_arg(enum addressing_mode mode) return val; } +static uint16_t +opcode_mem(enum addressing_mode mode) +{ + uint8_t arg; + uint16_t val; + + if (mode != AM_ABS && mode != AM_ABS_X && mode != AM_ABS_Y) + arg = peek(regs.pc++); + else + arg = peek16(regs.pc), regs.pc += 2; + + switch (mode) { + case AM_ZP: + val = arg % 256; + break; + case AM_ZP_X: + val = (arg + regs.x) % 256; + break; + case AM_ZP_Y: + val = (arg + regs.y) % 256; + break; + case AM_ABS: + val = arg; + break; + case AM_ABS_X: + val = arg + regs.x; + break; + case AM_ABS_Y: + val = arg + regs.y; + break; + case AM_IND_X: + val = peek((arg + regs.x) % 256) + peek((arg + regs.x + 1) % 256) * 256; + break; + case AM_IND_Y: + val = peek(arg) + peek((arg + 1) % 256) * 256 + regs.y; + break; + default: + fprintf(stderr, "INVALID ADDRESSING MODE\n"); + abort(); + } + + return val; +} + static void adc(uint8_t arg) { @@ -313,9 +357,9 @@ cpy(uint8_t arg) } static void -dec(uint8_t arg) +dec(uint16_t mem) { -/* TODO: complete this */ + memwrite(mem, peek(mem) - 1); } static void @@ -839,19 +883,19 @@ interpret(void) cycles += 2; break; case 0x18: - clc(opcode_arg(AM_ACC)); + clc(); cycles += 2; break; case 0xd8: - cld(opcode_arg(AM_ACC)); + cld(); cycles += 2; break; case 0x58: - cli(opcode_arg(AM_ACC)); + cli(); cycles += 2; break; case 0xb8: - clv(opcode_arg(AM_ACC)); + clv(); cycles += 2; break; case 0xc9: @@ -914,24 +958,20 @@ interpret(void) cpy(opcode_arg(AM_ABS)); cycles += 4; break; - case 0x3a: - dec(opcode_arg(AM_ACC)); - cycles += 2; - break; case 0xc6: - dec(opcode_arg(AM_ZP)); + dec(opcode_mem(AM_ZP)); cycles += 5; break; case 0xd6: - dec(opcode_arg(AM_ZP_X)); + dec(opcode_mem(AM_ZP_X)); cycles += 6; break; case 0xce: - dec(opcode_arg(AM_ABS)); + dec(opcode_mem(AM_ABS)); cycles += 6; break; case 0xde: - dec(opcode_arg(AM_ABS_X)); + dec(opcode_mem(AM_ABS_X)); cycles += 7; break; case 0xca: