From 8c26d0c6e6bb14878e7874cc27df603afb321f7f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 18 Apr 2019 20:50:58 -0400 Subject: [PATCH] Makes an attempt at RTE and RTR. --- .../Implementation/68000Implementation.hpp | 19 +++++++++++++++ .../68000/Implementation/68000Storage.cpp | 23 +++++++++++++++++++ .../68000/Implementation/68000Storage.hpp | 6 +++++ 3 files changed, 48 insertions(+) diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 35b3d17ef..5d3a09ba4 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -1046,6 +1046,18 @@ template void Processor: #undef set_flags_w #undef set_flags_l #undef set_neg_zero_overflow + /* + RTE and RTR share an implementation. + */ + case Operation::RTE_RTR: + // If this is RTR, patch out the is_supervisor bit. + if(decoded_instruction_ == 0x4e77) { + source_bus_data_[0].full = + (source_bus_data_[0].full & ~(1 << 13)) | + (is_supervisor_ << 13); + } + set_status(source_bus_data_[0].full); + break; /* TSTs: compare to zero. @@ -1128,6 +1140,13 @@ template void Processor: address_[7].full += 4; break; + case int(MicroOp::Action::PrepareRTE_RTR): + precomputed_addresses_[0] = address_[7].full + 2; + precomputed_addresses_[1] = address_[7].full; + precomputed_addresses_[2] = address_[7].full + 4; + address_[7].full += 6; + break; + case int(MicroOp::Action::CopyNextWord): next_word_ = prefetch_queue_.halves.low.full; break; diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index adde06919..7df54938d 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -372,6 +372,8 @@ struct ProcessorStorageConstructor { MOVEM, // Maps a mode and register as they were a 'destination' and sets up bus steps with a suitable // hole for the runtime part to install proper MOVEM activity. + RTE_RTR, // Maps to an RTE/RTR. + Scc_DBcc, // Maps a mode and destination register to either a DBcc or Scc. TST, // Maps a mode and register to a TST. @@ -570,6 +572,9 @@ struct ProcessorStorageConstructor { {0xfff0, 0x4e60, Operation::MOVEAl, Decoder::MOVEUSP}, // 6-21 (p475) {0xfff0, 0x4e40, Operation::TRAP, Decoder::TRAP}, // 4-188 (p292) + + {0xffff, 0x4e77, Operation::RTE_RTR, Decoder::RTE_RTR}, // 4-168 (p272) [RTR] + {0xffff, 0x4e73, Operation::RTE_RTR, Decoder::RTE_RTR}, // 6-84 (p538) [RTE] }; std::vector micro_op_pointers(65536, std::numeric_limits::max()); @@ -604,6 +609,15 @@ struct ProcessorStorageConstructor { const int ea_mode = (instruction >> 3) & 7; switch(mapping.decoder) { + case Decoder::RTE_RTR: { + storage_.instructions[instruction].requires_supervisor = instruction == 0x4e73; + + // TODO: something explicit to ensure the nR nr nr is exclusively linked. + op(Action::PrepareRTE_RTR, seq("nR nr nr", { &storage_.precomputed_addresses_[0], &storage_.precomputed_addresses_[1], &storage_.precomputed_addresses_[2] } )); + op(Action::PerformOperation, seq("np np")); + op(); + } break; + case Decoder::AND_OR_EOR: { const bool to_ea = !!((instruction >> 8)&1); const bool is_eor = (instruction >> 12) == 0xb; @@ -3122,6 +3136,15 @@ CPU::MC68000::ProcessorStorage::ProcessorStorage() { trap_steps_[3].microcycle.value = trap_steps_[4].microcycle.value = &destination_bus_data_[0].halves.low; trap_steps_[5].microcycle.value = trap_steps_[6].microcycle.value = &program_counter_.halves.high; + // Also relink the RTE and RTR bus steps to collect the program counter. + // + // Assumed order of input: PC.h, SR, PC.l (i.e. the opposite of TRAP's output). + for(const int instruction: { 0x4e73, 0x4e77 }) { + auto steps = instructions[instruction].micro_operations[0].bus_program; + steps[0].microcycle.value = steps[1].microcycle.value = &program_counter_.halves.high; + steps[4].microcycle.value = steps[5].microcycle.value = &program_counter_.halves.low; + } + // Set initial state. Largely TODO. active_step_ = reset_bus_steps_; effective_address_[0] = 0; diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index 777988d4c..8174f4370 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -93,6 +93,8 @@ class ProcessorStorage { MULU, MULS, + RTE_RTR, + TRAP, }; @@ -241,6 +243,10 @@ class ProcessorStorage { // (i) copies the stack pointer to effective_address_[0]; // (ii) increments the stack pointer by four. PrepareRTS, + + // (i) fills in the proper stack addresses to the bus steps for this micro-op; and + // (ii) adjusts the stack pointer appropriately. + PrepareRTE_RTR, }; static const int SourceMask = 1 << 30; static const int DestinationMask = 1 << 29;