diff --git a/cpu.c b/cpu.c index 5d36d37..c7d25ef 100644 --- a/cpu.c +++ b/cpu.c @@ -326,13 +326,16 @@ brk(void) static void bvc(uint8_t arg) { - if (regs.status.overflow == 0) + //regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) == 0; + //if (regs.status.overflow == 0) + if ((STATUS_TO_INT() & (1 << 6)) == 0) regs.pc += arg; } static void bvs(uint8_t arg) { + regs.status.overflow = (STATUS_TO_INT() & (1 << 6)) != 0; if (regs.status.overflow == 1) regs.pc += arg; } @@ -559,11 +562,7 @@ pha(void) static void php(void) { - uint8_t status; - - status = STATUS_TO_INT(); - - PUSH(status); + PUSH(STATUS_TO_INT() | (1 << 4)); } static void @@ -582,14 +581,14 @@ plp(void) status = PULL(); - regs.status.carry = (status & (1 << 7)) != 0; - regs.status.zero = (status & (1 << 6)) != 0; - regs.status.interrupt_disable = (status & (1 << 5)) != 0; - regs.status.decimal_mode = (status & (1 << 4)) != 0; - regs.status.brk = (status & (1 << 3)) != 0; - regs.status.unused = (status & (1 << 2)) != 0; - regs.status.overflow = (status & (1 << 1)) != 0; - regs.status.negative = (status & 1) != 0; + regs.status.carry = (status & 1) != 0; + regs.status.zero = (status & (1 << 1)) != 0; + regs.status.interrupt_disable = (status & (1 << 2)) != 0; + regs.status.decimal_mode = (status & (1 << 3)) != 0; + regs.status.brk = 0; + regs.status.unused = 1; + regs.status.overflow = (status & (1 << 6)) != 0; + regs.status.negative = (status & (1 << 7)) != 0; } static void @@ -771,12 +770,14 @@ interpret(void) uint16_t arg, mem, deref; uint32_t cycles_; enum addressing_mode mode; + struct registers regs_; for (;;) { opcode = peek(regs.pc++); cycles_ = cycles; did_memwrite = 0; status = STATUS_TO_INT(); + regs_ = regs; printf("%04X %02X", regs.pc - 1, opcode); @@ -928,23 +929,26 @@ interpret(void) printf("ASL"); break; case 0x90: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bcc(arg); + arg += regs_.pc + 1; cycles += 2; printf("BCC"); break; case 0xb0: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bcs(arg); + arg += regs_.pc + 1; cycles += 2; printf("BCS"); break; case 0xf0: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); beq(arg); + arg += regs_.pc + 1; cycles += 2; printf("BEQ"); break; @@ -989,23 +993,26 @@ interpret(void) printf("BIT"); break; case 0x30: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bmi(arg); + arg += regs_.pc + 1; cycles += 2; printf("BMI"); break; case 0xd0: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bne(arg); + arg += regs_.pc + 1; cycles += 2; printf("BNE"); break; case 0x10: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bpl(arg); + arg += regs_.pc + 1; cycles += 2; printf("BPL"); break; @@ -1016,16 +1023,18 @@ interpret(void) printf("\tBRK"); goto loop_exit; case 0x50: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bvc(arg); + arg += regs_.pc + 1; cycles += 2; printf("BVC"); break; case 0x70: - mode = AM_IMM; + mode = AM_REL; arg = opcode_arg(mode); bvs(arg); + arg += regs_.pc + 1; cycles += 2; printf("BVS"); break; @@ -1884,6 +1893,7 @@ interpret(void) if (did_memwrite) printf(" = %02X\t\t\t", ret); else printf("\t\t\t\t"); break; + case AM_REL: case AM_ABS: printf(" $%04X", arg); if (did_memwrite) printf(" = %02X\t\t\t", ret); @@ -1910,7 +1920,7 @@ interpret(void) } printf("A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n", - regs.a, regs.x, regs.y, status, regs.sp, cycles_); + regs_.a, regs_.x, regs_.y, status, regs_.sp, cycles_); } loop_exit: }