From 3ec9a1d86942fe79e949315e3676cb462deb47a2 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 24 Jun 2019 15:36:33 -0400 Subject: [PATCH] Incorporates JMP tests, fixes JSR (xxx).l timing. --- .../Mac/Clock SignalTests/68000Tests.mm | 65 +++++++++++++++++++ Processors/68000/68000.hpp | 4 ++ .../68000/Implementation/68000Storage.cpp | 6 ++ 3 files changed, 75 insertions(+) diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index f2e4b830e..17660b150 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -1393,6 +1393,71 @@ class CPU::MC68000::ProcessorStorageTests { XCTAssertEqual(6, _machine->get_cycle_count()); } +// MARK: JMP + +- (void)testJMP_A1 { + _machine->set_program({ + 0x4ed1 // JMP (A1) + }); + + auto state = _machine->get_processor_state(); + state.address[1] = 0x3000; + + _machine->set_processor_state(state); + _machine->run_for_instructions(1); + + state = _machine->get_processor_state(); + XCTAssertEqual(state.address[1], 0x3000); + XCTAssertEqual(state.program_counter, 0x3000 + 4); + XCTAssertEqual(8, _machine->get_cycle_count()); +} + +- (void)testJMP_PC { + _machine->set_program({ + 0x4efa, 0x000a // JMP PC+a (i.e. to 0x100c) + }); + + _machine->run_for_instructions(1); + + const auto state = _machine->get_processor_state(); + XCTAssertEqual(state.program_counter, 0x100c + 4); + XCTAssertEqual(10, _machine->get_cycle_count()); +} + +// MARK: JSR + +- (void)testJSR_PC { + _machine->set_program({ + 0x4eba, 0x000a // JSR (+a)PC ; JSR to $100c + }); + _machine->set_initial_stack_pointer(0x2000); + + _machine->run_for_instructions(1); + + const auto state = _machine->get_processor_state(); + XCTAssertEqual(state.stack_pointer(), 0x1ffc); + XCTAssertEqual(state.program_counter, 0x100c + 4); + XCTAssertEqual(*_machine->ram_at(0x1ffc), 0x0000); + XCTAssertEqual(*_machine->ram_at(0x1ffe), 0x1004); + XCTAssertEqual(18, _machine->get_cycle_count()); +} + +- (void)testJSR_XXXl { + _machine->set_program({ + 0x4eb9, 0x0000, 0x1008 // JSR ($1008).l + }); + _machine->set_initial_stack_pointer(0x2000); + + _machine->run_for_instructions(1); + + const auto state = _machine->get_processor_state(); + XCTAssertEqual(state.stack_pointer(), 0x1ffc); + XCTAssertEqual(state.program_counter, 0x1008 + 4); + XCTAssertEqual(*_machine->ram_at(0x1ffc), 0x0000); + XCTAssertEqual(*_machine->ram_at(0x1ffe), 0x1006); + XCTAssertEqual(20, _machine->get_cycle_count()); +} + // MARK: LEA - (void)testLEA_w { diff --git a/Processors/68000/68000.hpp b/Processors/68000/68000.hpp index 948a6b297..ea50e1ccc 100644 --- a/Processors/68000/68000.hpp +++ b/Processors/68000/68000.hpp @@ -244,6 +244,10 @@ struct ProcessorState { uint32_t program_counter; uint16_t status; + /*! + @returns the supervisor stack pointer if @c status indicates that + the processor is in supervisor mode; the user stack pointer otherwise. + */ uint32_t stack_pointer() const { return (status & Flag::Supervisor) ? supervisor_stack_pointer : user_stack_pointer; } diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 09f256231..6cb741145 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -2329,6 +2329,12 @@ struct ProcessorStorageConstructor { case XXXl: // JSR (xxx).L op(Action::None, seq("np")); + op(Action::PrepareJSR); // TODO: improve PrepareJSR to be able to compute alternative + // offsets from the current PC, and thereby move this one slot earlier. + op(address_action_for_mode(mode) | MicroOp::SourceMask); + op(Action::PerformOperation, seq("np nW+ nw np", { ea(1), ea(1) })); + break; + case XXXw: // JSR (xxx).W case d16PC: // JSR (d16, PC) case d16An: // JSR (d16, An)