From 21cb7307d03abb34fd2cd4977d0e5e2aa26b68f6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 19 Mar 2019 11:53:37 -0400 Subject: [PATCH] Adds `MOVE #, Dn` and `MOVEA An, An`. As well as the scheduling for `(d16,PC), Dd` and `MOVE (d8,As,Xn), Dd` other than the .ls. --- .../Implementation/68000Implementation.hpp | 8 +++ .../68000/Implementation/68000Storage.cpp | 58 +++++++++++++++++-- .../68000/Implementation/68000Storage.hpp | 4 ++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index 9aeb4f886..a50b2d9a9 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -243,6 +243,14 @@ template void Processor: } break; #undef CalculateD8AnXn + + case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask: + bus_data_[0] = (prefetch_queue_[0] << 16) | prefetch_queue_[1]; + break; + + case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::DestinationMask: + bus_data_[1] = (prefetch_queue_[0] << 16) | prefetch_queue_[1]; + break; } // If we've got to a micro-op that includes bus steps, break out of this loop. diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp index fc1463d4a..541637660 100644 --- a/Processors/68000/Implementation/68000Storage.cpp +++ b/Processors/68000/Implementation/68000Storage.cpp @@ -310,11 +310,23 @@ struct ProcessorStorageConstructor { break; } - if(!destination_mode) { - storage_.instructions[instruction].destination = &storage_.data_[destination_register]; + switch(destination_mode) { + case 0: // Dn + storage_.instructions[instruction].destination = &storage_.data_[destination_register]; + break; + + case 1: // An + storage_.instructions[instruction].destination = &storage_.address_[destination_register]; + break; + + default: // (An), (An)+, -(An), (d16, An), (d8, An Xn), (xxx).W, (xxx).L + storage_.instructions[instruction].destination = &storage_.bus_data_[1]; + break; } const bool is_byte_access = mapping.operation == Operation::MOVEb; + const bool is_long_word_access = mapping.operation == Operation::MOVEl; + const int both_modes = (source_mode << 4) | destination_mode; switch(both_modes) { case 0x00: // MOVE Ds, Dd @@ -324,6 +336,7 @@ struct ProcessorStorageConstructor { break; case 0x01: // MOVEA Ds, Ad + case 0x11: // MOVEA As, Ad if(is_byte_access) continue; storage_.all_micro_ops_.emplace_back(Action::PerformOperation, &arbitrary_base + assemble_program("np")); @@ -352,7 +365,7 @@ struct ProcessorStorageConstructor { break; case 0x40: // MOVE -(As), Dd - if(mapping.operation == Operation::MOVEl) { + if(is_long_word_access) { continue; } else { storage_.all_micro_ops_.emplace_back(int(is_byte_access ? Action::Decrement1 : Action::Decrement2) | MicroOp::SourceMask, &arbitrary_base + assemble_program("n nr np", { &storage_.address_[source_register].full }, !is_byte_access)); @@ -361,7 +374,7 @@ struct ProcessorStorageConstructor { break; case 0x50: // MOVE (d16,As), Dd - if(mapping.operation == Operation::MOVEl) { + if(is_long_word_access) { continue; } else { storage_.all_micro_ops_.emplace_back(int(Action::CalcD16An) | MicroOp::SourceMask, &arbitrary_base + assemble_program("n np nr np", { &storage_.effective_address_[0] }, !is_byte_access)); @@ -370,7 +383,7 @@ struct ProcessorStorageConstructor { break; case 0x60: // MOVE (d8,As,Xn), Dd - if(mapping.operation == Operation::MOVEl) { + if(is_long_word_access) { continue; } else { storage_.all_micro_ops_.emplace_back(int(Action::CalcD8AnXn) | MicroOp::SourceMask, &arbitrary_base + assemble_program("n np nr np", { &storage_.effective_address_[0] }, !is_byte_access)); @@ -378,6 +391,41 @@ struct ProcessorStorageConstructor { } break; + case 0x70: // ... depends on 'register' + switch(source_register) { + case 0: // MOVE (xxx).W, Dd + break; + + case 1: // MOVE (xxx).L, Dd + break; + + case 2: // MOVE (d16,PC), Dd + if(is_long_word_access) { + continue; + } else { + storage_.all_micro_ops_.emplace_back(int(Action::CalcD16PC) | MicroOp::SourceMask, &arbitrary_base + assemble_program("n np nr np", { &storage_.effective_address_[0] }, !is_byte_access)); + storage_.all_micro_ops_.emplace_back(Action::PerformOperation); + } + break; + + case 3: // MOVE (d8,As,Xn), Dd + if(is_long_word_access) { + continue; + } else { + storage_.all_micro_ops_.emplace_back(int(Action::CalcD8PCXn) | MicroOp::SourceMask, &arbitrary_base + assemble_program("n np nr np", { &storage_.effective_address_[0] }, !is_byte_access)); + storage_.all_micro_ops_.emplace_back(Action::PerformOperation); + } + break; + + case 4: // MOVE #, Dd + storage_.all_micro_ops_.emplace_back(int(Action::AssembleWordFromPrefetch) | MicroOp::SourceMask , &arbitrary_base + assemble_program("np np")); + storage_.all_micro_ops_.emplace_back(Action::PerformOperation); + break; + + default: continue; + } + break; + default: // TODO: all other types of mode. continue; diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index bfcd0df8f..588d29a14 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -140,6 +140,10 @@ class ProcessorStorage { /// Sets the high three bytes according to the MSB of the low byte. SignExtendByte, + + /// From the next two words in the prefetch queue assembles a 32-bit long word in either or + /// both of bus_data_[0] and bus_data_[1]. + AssembleWordFromPrefetch, }; static const int SourceMask = 1 << 30; static const int DestinationMask = 1 << 29;