mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-15 14:27:29 +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:
@@ -243,6 +243,14 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
#undef CalculateD8AnXn
|
#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.
|
// If we've got to a micro-op that includes bus steps, break out of this loop.
|
||||||
|
@@ -310,11 +310,23 @@ struct ProcessorStorageConstructor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!destination_mode) {
|
switch(destination_mode) {
|
||||||
storage_.instructions[instruction].destination = &storage_.data_[destination_register];
|
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_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;
|
const int both_modes = (source_mode << 4) | destination_mode;
|
||||||
switch(both_modes) {
|
switch(both_modes) {
|
||||||
case 0x00: // MOVE Ds, Dd
|
case 0x00: // MOVE Ds, Dd
|
||||||
@@ -324,6 +336,7 @@ struct ProcessorStorageConstructor {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: // MOVEA Ds, Ad
|
case 0x01: // MOVEA Ds, Ad
|
||||||
|
case 0x11: // MOVEA As, Ad
|
||||||
if(is_byte_access) continue;
|
if(is_byte_access) continue;
|
||||||
|
|
||||||
storage_.all_micro_ops_.emplace_back(Action::PerformOperation, &arbitrary_base + assemble_program("np"));
|
storage_.all_micro_ops_.emplace_back(Action::PerformOperation, &arbitrary_base + assemble_program("np"));
|
||||||
@@ -352,7 +365,7 @@ struct ProcessorStorageConstructor {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40: // MOVE -(As), Dd
|
case 0x40: // MOVE -(As), Dd
|
||||||
if(mapping.operation == Operation::MOVEl) {
|
if(is_long_word_access) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} 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));
|
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;
|
break;
|
||||||
|
|
||||||
case 0x50: // MOVE (d16,As), Dd
|
case 0x50: // MOVE (d16,As), Dd
|
||||||
if(mapping.operation == Operation::MOVEl) {
|
if(is_long_word_access) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} 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));
|
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;
|
break;
|
||||||
|
|
||||||
case 0x60: // MOVE (d8,As,Xn), Dd
|
case 0x60: // MOVE (d8,As,Xn), Dd
|
||||||
if(mapping.operation == Operation::MOVEl) {
|
if(is_long_word_access) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} 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));
|
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;
|
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:
|
default:
|
||||||
// TODO: all other types of mode.
|
// TODO: all other types of mode.
|
||||||
continue;
|
continue;
|
||||||
|
@@ -140,6 +140,10 @@ class ProcessorStorage {
|
|||||||
|
|
||||||
/// Sets the high three bytes according to the MSB of the low byte.
|
/// Sets the high three bytes according to the MSB of the low byte.
|
||||||
SignExtendByte,
|
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 SourceMask = 1 << 30;
|
||||||
static const int DestinationMask = 1 << 29;
|
static const int DestinationMask = 1 << 29;
|
||||||
|
Reference in New Issue
Block a user