diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index 8a9c65c9c..100991d24 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -2626,6 +2626,44 @@ class CPU::MC68000::ProcessorStorageTests { XCTAssertEqual(state.supervisor_stack_pointer, 0x200); } +// MARK: TRAPV + +- (void)testTRAPV_taken { + _machine->set_program({ + 0x4e76 // TRAPV + }); + _machine->set_initial_stack_pointer(0x206); + + auto state = _machine->get_processor_state(); + state.status = 0x702; + state.supervisor_stack_pointer = 0x206; + *_machine->ram_at(0x1e) = 0xfffe; + *_machine->ram_at(0xfffe) = 0x4e71; + + _machine->set_processor_state(state); + _machine->run_for_instructions(1); + + state = _machine->get_processor_state(); + XCTAssertEqual(state.status, 0x2702); + XCTAssertEqual(state.stack_pointer(), 0x200); + XCTAssertEqual(*_machine->ram_at(0x202), 0x0000); + XCTAssertEqual(*_machine->ram_at(0x204), 0x1002); + XCTAssertEqual(*_machine->ram_at(0x200), 0x702); + XCTAssertEqual(34, _machine->get_cycle_count()); +} + +- (void)testTRAPV_untaken { + _machine->set_program({ + 0x4e76 // TRAPV + }); + + _machine->run_for_instructions(1); + + const auto state = _machine->get_processor_state(); + XCTAssertEqual(state.program_counter, 0x1002 + 4); + XCTAssertEqual(4, _machine->get_cycle_count()); +} + // MARK: UNLINK - (void)testUNLINK_A6 { diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 0a6b59846..17c4e6b9b 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -1268,10 +1268,12 @@ template void Proces case Operation::TRAPV: { if(overflow_flag_) { - // Select the trap steps as next; the initial microcycle should be 4 cycles long. + // Select the trap steps as next; the initial microcycle should be skipped. bus_program = trap_steps_; populate_trap_steps(7, get_status()); set_next_microcycle_length(HalfCycles(0)); + + // Push the address after the TRAPV. program_counter_.full -= 4; } } break;