From f0d5bbecf2a0d98aea9446480068e3b81ce55c18 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 4 Jan 2020 23:22:07 -0500 Subject: [PATCH] Introduces a test of stack contents after an address error. Fixes: stacked PC, address of fault. --- .../Mac/Clock SignalTests/68000Tests.mm | 33 +++++++++++++++++-- .../Implementation/68000Implementation.hpp | 1 + .../68000/Implementation/68000Storage.cpp | 4 +-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index bd069d7c7..d2d8935e4 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -223,8 +223,37 @@ class CPU::MC68000::ProcessorStorageTests { _machine->run_for_instructions(1); const auto state = _machine->processor().get_state(); - XCTAssert(state.program_counter == 0x1008); // i.e. the interrupt happened, the instruction performed was the one at 1004, and therefore - // by the wonders of prefetch the program counter is now at 1008. + XCTAssertEqual(state.program_counter, 0x1008); // i.e. the interrupt happened, the instruction performed was the one at 1004, and therefore + // by the wonders of prefetch the program counter is now at 1008. +} + +- (void)testAddressErrorStack { + // Cause an address error. + _machine->set_program({ + 0x3c7c, 0x2001, // MOVEA.w #$2001, A6 + 0x4a9e, // TST (A6)+ + }); + _machine->run_for_instructions(2); + + // Check what was left on the stack for appropriate fields. + const auto stack_frame = _machine->ram_at(0x1f8); + + // Function code et al. +// XCTAssertEqual(stack_frame[0], 0x0000); // ?? + + // Access address. + XCTAssertEqual(stack_frame[1], 0x0000); + XCTAssertEqual(stack_frame[2], 0x2001); + + // Instruction. + XCTAssertEqual(stack_frame[3], 0x4a9e); + + // Status. + XCTAssertEqual(stack_frame[4], 0x2700); + + // PC. + XCTAssertEqual(stack_frame[5], 0x0000); + XCTAssertEqual(stack_frame[6], 0x1004); } - (void)testOpcodeCoverage { diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index b287c398b..7b9211f6c 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -116,6 +116,7 @@ template void Proces active_micro_op_ = long_exception_micro_ops_; active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; populate_bus_error_steps(3, get_status(), get_bus_code(), offending_address); + program_counter_.full -= 4; } // Perform the microcycle if it is of non-zero length. If this is an operation that diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 1bbd45d7f..00532fd84 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -3262,9 +3262,9 @@ CPU::MC68000::ProcessorStorage::ProcessorStorage() { &destination_bus_data_[0].halves.low, &program_counter_.halves.high, &decoded_instruction_, - &effective_address_[0].halves.low, + &effective_address_[1].halves.low, &destination_bus_data_[0].halves.high, - &effective_address_[0].halves.high + &effective_address_[1].halves.high }); // Also relink the RTE and RTR bus steps to collect the program counter.