diff --git a/OSBindings/Mac/Clock SignalTests/68000Tests.mm b/OSBindings/Mac/Clock SignalTests/68000Tests.mm index d2d8935e4..a192a05fe 100644 --- a/OSBindings/Mac/Clock SignalTests/68000Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000Tests.mm @@ -239,7 +239,12 @@ class CPU::MC68000::ProcessorStorageTests { const auto stack_frame = _machine->ram_at(0x1f8); // Function code et al. -// XCTAssertEqual(stack_frame[0], 0x0000); // ?? + XCTAssertEqual(stack_frame[0], + (0x4a9e & 0xffe0) | // Top 11 bits: decoded instruction; + 0x10 | // Bit 4: read or write; + 0x0 | // Bit 3: 0 = in instruction, 1 = not; + 0x5 // Bits 0–2: FC0–2, i.e. bit 2 = supervisor, bit 1 = is program, bit 0 = is data. + ); // Access address. XCTAssertEqual(stack_frame[1], 0x0000); diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 7b9211f6c..e3b61d156 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -41,7 +41,8 @@ ((active_step_->microcycle.operation & Microcycle::IsProgram) ? 0x02 : 0x01) | \ (is_supervisor_ << 2) | \ (active_program_ ? 0x08 : 0) | \ - ((active_step_->microcycle.operation & Microcycle::Read) ? 0x10 : 0) \ + ((active_step_->microcycle.operation & Microcycle::Read) ? 0x10 : 0) | \ + (decoded_instruction_.full & 0xffe0) \ ) #define u_extend16(x) uint32_t(int16_t(x)) @@ -100,8 +101,9 @@ template void Proces const auto offending_address = *active_step_->microcycle.address; active_program_ = nullptr; active_micro_op_ = long_exception_micro_ops_; - active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; populate_bus_error_steps(2, get_status(), get_bus_code(), offending_address); + program_counter_.full -= 4; + active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; } } @@ -114,9 +116,16 @@ template void Proces const auto offending_address = *active_step_->microcycle.address; active_program_ = nullptr; 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; + active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; + + // TODO: the above is only correct prior to the final microcycle of an + // instruction. If an exception occurs in the final microcycle then + // the next instruction will already have moved into the current instruction + // slot (decoded_instruction_ in my terms). + + // TODO: it's also not correct for a bus error that occurs during another exception. } // Perform the microcycle if it is of non-zero length. If this is an operation that