From b8a0f4e831cee8da272506eea115d6cd0270a12f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 17 Apr 2019 16:58:59 -0400 Subject: [PATCH] Implements MOVE to/from USP. --- .../Implementation/68000Implementation.hpp | 4 ++++ .../68000/Implementation/68000Storage.cpp | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 4c647cf0e..66df4e4cb 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -478,6 +478,10 @@ template void Processor: set_ccr(active_program_->source->full); break; + /* + Multiplications. + */ + case Operation::MULU: { active_program_->destination->full = active_program_->destination->halves.low.full * active_program_->source->halves.low.full; diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index 3e5f20fea..b294190ba 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -375,6 +375,8 @@ struct ProcessorStorageConstructor { TST, // Maps a mode and register to a TST. RTS, // Maps to an RST. + + MOVEUSP, // Maps a direction and register to a MOVE [to/from] USP. }; using Operation = ProcessorStorage::Operation; @@ -553,6 +555,8 @@ struct ProcessorStorageConstructor { {0xf1c0, 0xc0c0, Operation::MULU, Decoder::MULU_MULS}, // 4-139 (p243) {0xf1c0, 0xc1c0, Operation::MULS, Decoder::MULU_MULS}, // 4-136 (p240) + {0xfff0, 0x4e60, Operation::MOVEAl, Decoder::MOVEUSP}, // 6-21 (p475) + }; #ifndef NDEBUG @@ -2027,6 +2031,24 @@ struct ProcessorStorageConstructor { op(is_to_m ? Action::MOVEMtoMComplete : Action::MOVEMtoRComplete, seq("np")); } break; + case Decoder::MOVEUSP: { + storage_.instructions[instruction].requires_supervisor = true; + + // Observation here: because this is a privileged instruction, the user stack pointer + // definitely isn't currently A7. + if(instruction & 0x8) { + // Transfer FROM the USP. + storage_.instructions[instruction].destination = &storage_.stack_pointers_[0]; + storage_.instructions[instruction].set_source(storage_, An, ea_register); + } else { + // Transfer TO the USP. + storage_.instructions[instruction].source = &storage_.stack_pointers_[0]; + storage_.instructions[instruction].set_destination(storage_, An, ea_register); + } + + op(Action::PerformOperation, seq("np")); + } break; + // Decodes the format used by most MOVEs and all MOVEAs. case Decoder::MOVE: { const int destination_mode = (instruction >> 6) & 7;