1
0
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:
Thomas Harte 2019-03-19 11:53:37 -04:00
parent 412a1eb7ee
commit 21cb7307d0
3 changed files with 65 additions and 5 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;