From 943c92438263cdf40cf02ccce475d39f66fbb780 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 11 May 2022 07:52:23 -0400 Subject: [PATCH] Add missing: MOVE to/from USP, RESET. --- InstructionSets/M68k/Executor.hpp | 7 +++++- .../Implementation/ExecutorImplementation.hpp | 23 ++++++++++++++++--- .../Implementation/PerformImplementation.hpp | 12 ++++++++++ InstructionSets/M68k/Perform.hpp | 11 +++++++++ .../68000ComparativeTests.mm | 2 ++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/InstructionSets/M68k/Executor.hpp b/InstructionSets/M68k/Executor.hpp index fc409ebf7..133343eaf 100644 --- a/InstructionSets/M68k/Executor.hpp +++ b/InstructionSets/M68k/Executor.hpp @@ -31,6 +31,7 @@ enum class FunctionCode { struct BusHandler { template void write(uint32_t address, IntT value, FunctionCode function); template IntT read(uint32_t address, FunctionCode function); + void reset(); }; /// Ties together the decoder, sequencer and performer to provide an executor for 680x0 instruction streams. @@ -64,11 +65,15 @@ template class Executor: public NullFlowContr void rts(); void rte(); void stop(); + void reset(); void link(Preinstruction instruction, uint32_t offset); void unlink(uint32_t &address); void pea(uint32_t address); + void move_to_usp(uint32_t address); + void move_from_usp(uint32_t &address); + template void movep(Preinstruction instruction, uint32_t source, uint32_t dest); template void movem_toM(Preinstruction instruction, uint32_t source, uint32_t dest); template void movem_toR(Preinstruction instruction, uint32_t source, uint32_t dest); @@ -92,7 +97,7 @@ template class Executor: public NullFlowContr BusHandler &bus_handler_; Predecoder decoder_; - void reset(); + void reset_processor(); struct EffectiveAddress { CPU::SlicedInt32 value; bool requires_fetch; diff --git a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp index 56759d738..fc9f83f6b 100644 --- a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp +++ b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp @@ -26,11 +26,11 @@ namespace M68k { template Executor::Executor(BusHandler &handler) : bus_handler_(handler) { - reset(); + reset_processor(); } template -void Executor::reset() { +void Executor::reset_processor() { // Establish: supervisor state, all interrupts blocked. status_.set_status(0b0010'0011'1000'0000); did_update_status(); @@ -255,7 +255,9 @@ void Executor::run_for_instructions(int count) { try { program_counter_.l = read(vector_address); } catch (uint64_t) { - reset(); + // TODO: I think this is incorrect, but need to verify consistency + // across different 680x0s. + reset_processor(); } } } @@ -412,6 +414,11 @@ void Executor::did_update_status() { template void Executor::stop() {} +template +void Executor::reset() { + bus_handler_.reset(); +} + template void Executor::jmp(uint32_t address) { program_counter_.l = address; @@ -504,6 +511,16 @@ void Executor::tas(Preinstruction instruction, uint32_t addre status_.negative_flag_ = value & 0x80; } +template +void Executor::move_to_usp(uint32_t address) { + stack_pointers_[0].l = address; +} + +template +void Executor::move_from_usp(uint32_t &address) { + address = stack_pointers_[0].l; +} + template template void Executor::movep(Preinstruction instruction, uint32_t source, uint32_t dest) { diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index 42b6b2ea2..2e3c34fdb 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -427,6 +427,14 @@ template < status.set_ccr(src.w); break; + case Operation::MOVEtoUSP: + flow_controller.move_to_usp(src.l); + break; + + case Operation::MOVEfromUSP: + flow_controller.move_from_usp(src.l); + break; + case Operation::EXTbtow: src.w = uint16_t(int8_t(src.b)); status.overflow_flag_ = status.carry_flag_ = 0; @@ -1162,6 +1170,10 @@ template < flow_controller.stop(); break; + case Operation::RESET: + flow_controller.reset(); + break; + /* Development period debugging. */ diff --git a/InstructionSets/M68k/Perform.hpp b/InstructionSets/M68k/Perform.hpp index deecbf6a7..6351b1448 100644 --- a/InstructionSets/M68k/Perform.hpp +++ b/InstructionSets/M68k/Perform.hpp @@ -84,6 +84,9 @@ struct NullFlowController { /// Put the processor into the stopped state, waiting for interrupts. void stop(); + /// Assert the reset output. + void reset(); + /// Perform LINK using the address register identified by @c instruction and the specified @c offset. void link(Preinstruction instruction, uint32_t offset); @@ -93,6 +96,14 @@ struct NullFlowController { /// Push @c address to the stack. void pea(uint32_t address); + /// Replace the current user stack pointer with @c address. + /// The processor is guranteed to be in supervisor mode. + void move_to_usp(uint32_t address); + + /// Put the value of the user stack pointer into @c address. + /// The processor is guranteed to be in supervisor mode. + void move_from_usp(uint32_t &address); + /// Perform an atomic TAS cycle; if @c instruction indicates that this is a TAS Dn then /// perform the TAS directly upon that register; otherwise perform it on the memory at /// @c address. If this is a TAS Dn then @c address will contain the initial value of diff --git a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm index 7cb2f342f..375ad96ac 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm @@ -267,6 +267,8 @@ ram[(address+3) & 0xffffff] = uint8_t(value); } } + + void reset() {} }; auto uniqueTest68000 = std::make_unique(); auto test68000 = uniqueTest68000.get();