mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-23 11:30:24 +00:00
Implements MOVEP.
371 is now the alleged number of missing opcodes. But I'd dare imagine it's more like three or four.
This commit is contained in:
parent
0298b1b3b7
commit
ca1f669e64
@ -794,6 +794,38 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
||||
active_step_->microcycle.length = HalfCycles(cycles_expended * 2);
|
||||
} break;
|
||||
|
||||
/*
|
||||
MOVEP: move words and long-words a byte at a time.
|
||||
*/
|
||||
|
||||
case Operation::MOVEPtoMw:
|
||||
// Write pattern is nW+ nw, which should write the low word of the source in big-endian form.
|
||||
destination_bus_data_[0].halves.high.full = active_program_->source->halves.low.halves.high;
|
||||
destination_bus_data_[0].halves.low.full = active_program_->source->halves.low.halves.low;
|
||||
break;
|
||||
|
||||
case Operation::MOVEPtoMl:
|
||||
// Write pattern is nW+ nWr+ nw+ nwr, which should write the source in big-endian form.
|
||||
destination_bus_data_[0].halves.high.full = active_program_->source->halves.high.halves.high;
|
||||
source_bus_data_[0].halves.high.full = active_program_->source->halves.high.halves.low;
|
||||
destination_bus_data_[0].halves.low.full = active_program_->source->halves.low.halves.high;
|
||||
source_bus_data_[0].halves.low.full = active_program_->source->halves.low.halves.low;
|
||||
break;
|
||||
|
||||
case Operation::MOVEPtoRw:
|
||||
// Read pattern is nRd+ nrd.
|
||||
active_program_->source->halves.low.halves.high = destination_bus_data_[0].halves.high.full;
|
||||
active_program_->source->halves.low.halves.low = destination_bus_data_[0].halves.low.full;
|
||||
break;
|
||||
|
||||
case Operation::MOVEPtoRl:
|
||||
// Read pattern is nRd+ nR+ nrd+ nr.
|
||||
active_program_->source->halves.high.halves.high = destination_bus_data_[0].halves.high.full;
|
||||
active_program_->source->halves.high.halves.low = source_bus_data_[0].halves.high.full;
|
||||
active_program_->source->halves.low.halves.high = destination_bus_data_[0].halves.low.full;
|
||||
active_program_->source->halves.low.halves.low = source_bus_data_[0].halves.low.full;
|
||||
break;
|
||||
|
||||
/*
|
||||
MOVEM: multi-word moves.
|
||||
*/
|
||||
|
@ -264,9 +264,9 @@ struct ProcessorStorageConstructor {
|
||||
}
|
||||
|
||||
// A standard read or write.
|
||||
if(token == "nR" || token == "nr" || token == "nW" || token == "nw" || token == "nRd" || token == "nrd") {
|
||||
if(token == "nR" || token == "nr" || token == "nW" || token == "nw" || token == "nRd" || token == "nrd" || token == "nWr" || token == "nwr") {
|
||||
const bool is_read = tolower(token[1]) == 'r';
|
||||
const bool use_source_storage = is_read && token.size() != 3;
|
||||
const bool use_source_storage = (token == "nR" || token == "nr" || token == "nWr" || token == "nwr");
|
||||
RegisterPair32 *const scratch_data = use_source_storage ? &storage_.source_bus_data_[0] : &storage_.destination_bus_data_[0];
|
||||
|
||||
assert(address_iterator != addresses.end());
|
||||
@ -431,8 +431,9 @@ struct ProcessorStorageConstructor {
|
||||
// decoded at runtime.
|
||||
ASLR_LSLR_ROLR_ROXLRm, // Maps a destination mode and register to a memory-based AS[L/R], LS[L/R], RO[L/R], ROX[L/R].
|
||||
|
||||
MOVEM, // Maps a mode and register as they were a 'destination' and sets up bus steps with a suitable
|
||||
MOVEM, // Maps a mode and register as if they were a 'destination' and sets up bus steps with a suitable
|
||||
// hole for the runtime part to install proper MOVEM activity.
|
||||
MOVEP, // Maps a data register, address register and operation mode to a MOVEP.
|
||||
|
||||
RTE_RTR, // Maps to an RTE/RTR.
|
||||
|
||||
@ -654,6 +655,11 @@ struct ProcessorStorageConstructor {
|
||||
{0xffc0, 0x4cc0, Operation::MOVEMtoRl, Decoder::MOVEM}, // 4-128 (p232)
|
||||
{0xffc0, 0x4c80, Operation::MOVEMtoRw, Decoder::MOVEM}, // 4-128 (p232)
|
||||
|
||||
{0xf1f8, 0x0108, Operation::MOVEPtoRw, Decoder::MOVEP}, // 4-133 (p237)
|
||||
{0xf1f8, 0x0148, Operation::MOVEPtoRl, Decoder::MOVEP}, // 4-133 (p237)
|
||||
{0xf1f8, 0x0188, Operation::MOVEPtoMw, Decoder::MOVEP}, // 4-133 (p237)
|
||||
{0xf1f8, 0x01c8, Operation::MOVEPtoMl, Decoder::MOVEP}, // 4-133 (p237)
|
||||
|
||||
{0xffc0, 0x4a00, Operation::TSTb, Decoder::TST}, // 4-192 (p296)
|
||||
{0xffc0, 0x4a40, Operation::TSTw, Decoder::TST}, // 4-192 (p296)
|
||||
{0xffc0, 0x4a80, Operation::TSTl, Decoder::TST}, // 4-192 (p296)
|
||||
@ -2604,6 +2610,37 @@ struct ProcessorStorageConstructor {
|
||||
op(Action::PerformOperation, seq("np"));
|
||||
} break;
|
||||
|
||||
case Decoder::MOVEP: {
|
||||
storage_.instructions[instruction].set_destination(storage_, An, ea_register);
|
||||
storage_.instructions[instruction].set_source(storage_, Dn, data_register);
|
||||
|
||||
switch(operation) {
|
||||
default: continue;
|
||||
|
||||
// Both of the MOVEP to memory instructions perform their operation first — it will
|
||||
// break up the source value into 8-bit chunks for the write section.
|
||||
case Operation::MOVEPtoMw:
|
||||
op(Action::PerformOperation);
|
||||
op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nW+ nw np", { ea(1), ea(1) }, false));
|
||||
break;
|
||||
|
||||
case Operation::MOVEPtoMl:
|
||||
op(Action::PerformOperation);
|
||||
op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nW+ nWr+ nw+ nwr np", { ea(1), ea(1), ea(1), ea(1) }, false));
|
||||
break;
|
||||
|
||||
case Operation::MOVEPtoRw:
|
||||
op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nRd+ nrd np", { ea(1), ea(1) }, false));
|
||||
op(Action::PerformOperation);
|
||||
break;
|
||||
|
||||
case Operation::MOVEPtoRl:
|
||||
op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nRd+ nR+ nrd+ nr np", { ea(1), ea(1), ea(1), ea(1) }, false));
|
||||
op(Action::PerformOperation);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Decoder::MOVEM: {
|
||||
// For the sake of commonality, both to R and to M will evaluate their addresses
|
||||
// as if they were destinations.
|
||||
@ -3424,7 +3461,7 @@ struct ProcessorStorageConstructor {
|
||||
}
|
||||
}
|
||||
|
||||
CPU::MC68000::ProcessorStorage::ProcessorStorage() {
|
||||
CPU::MC68000::ProcessorStorage::ProcessorStorage() {
|
||||
ProcessorStorageConstructor constructor(*this);
|
||||
|
||||
// Create the special programs.
|
||||
|
@ -94,6 +94,9 @@ class ProcessorStorage {
|
||||
MOVEMtoRl, MOVEMtoRw,
|
||||
MOVEMtoMl, MOVEMtoMw,
|
||||
|
||||
MOVEPtoRl, MOVEPtoRw,
|
||||
MOVEPtoMl, MOVEPtoMw,
|
||||
|
||||
ANDb, ANDw, ANDl,
|
||||
EORb, EORw, EORl,
|
||||
NOTb, NOTw, NOTl,
|
||||
|
Loading…
x
Reference in New Issue
Block a user