mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
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.
This commit is contained in:
parent
412a1eb7ee
commit
21cb7307d0
@ -243,6 +243,14 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
||||
} 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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user