1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Made an initial stab at completing MOVEA.w.

I think I'm probably peeking into the prefetch queue incorrectly.
This commit is contained in:
Thomas Harte 2019-03-22 21:43:51 -04:00
parent db0da4b741
commit ed7060a105
3 changed files with 41 additions and 14 deletions

View File

@ -199,11 +199,11 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
break;
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask:
effective_address_[0] = int16_t(prefetch_queue_.halves.high.full) + active_program_->source->full;
effective_address_[0] = int16_t(prefetch_queue_.halves.low.full) + active_program_->source->full;
break;
case int(MicroOp::Action::CalcD16An) | MicroOp::DestinationMask:
effective_address_[1] = int16_t(prefetch_queue_.halves.high.full) + active_program_->destination->full;
effective_address_[1] = int16_t(prefetch_queue_.halves.low.full) + active_program_->destination->full;
break;
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask | MicroOp::DestinationMask:
@ -224,11 +224,11 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
} \
}
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask: {
CalculateD8AnXn(prefetch_queue_.halves.high, active_program_->source, effective_address_[0]);
CalculateD8AnXn(prefetch_queue_.halves.low, active_program_->source, effective_address_[0]);
} break;
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::DestinationMask: {
CalculateD8AnXn(prefetch_queue_.halves.high, active_program_->destination, effective_address_[1]);
CalculateD8AnXn(prefetch_queue_.halves.low, active_program_->destination, effective_address_[1]);
} break;
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask | MicroOp::DestinationMask: {
@ -239,11 +239,19 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
#undef CalculateD8AnXn
case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask:
bus_data_[0] = prefetch_queue_.full;
effective_address_[0] = prefetch_queue_.halves.high.full;
break;
case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::DestinationMask:
bus_data_[1] = prefetch_queue_.full;
effective_address_[1] = prefetch_queue_.halves.high.full;
break;
case int(MicroOp::Action::AssembleLongWordFromPrefetch) | MicroOp::SourceMask:
effective_address_[0] = prefetch_queue_.full;
break;
case int(MicroOp::Action::AssembleLongWordFromPrefetch) | MicroOp::DestinationMask:
effective_address_[1] = prefetch_queue_.full;
break;
}
@ -321,7 +329,7 @@ template <class T, bool dtack_is_implicit> ProcessorState Processor<T, dtack_is_
(negative_flag_ ? 0x0008 : 0x0000) |
(extend_flag_ ? 0x0010 : 0x0000) |
(is_supervisor_ ? 0x2000 : 0x0000);
(is_supervisor_ << 13);
return state;
}

View File

@ -420,6 +420,9 @@ struct ProcessorStorageConstructor {
// Source = (An) or (An)+
//
case 0x0201: // MOVEA (An), An
case 0x0301: // MOVEA (An)+, An
operation = Operation::MOVEAw; // Substitute MOVEA for MOVE.
case 0x0200: // MOVE (An), Dn
case 0x0300: // MOVE (An)+, Dn
op(Action::None, seq("nr np", { &storage_.address_[source_register].full }, !is_byte_access));
@ -465,6 +468,8 @@ struct ProcessorStorageConstructor {
// Source = -(An)
//
case 0x0401: // MOVEA -(An), An
operation = Operation::MOVEAw; // Substitute MOVEA for MOVE.
case 0x0400: // MOVE -(An), Dn
op( int(is_byte_access ? Action::Decrement1 : Action::Decrement2) | MicroOp::SourceMask,
seq("n nr np", { &storage_.address_[source_register].full }, !is_byte_access));
@ -503,6 +508,9 @@ struct ProcessorStorageConstructor {
#define action_calc() int(source_mode == 0x05 ? Action::CalcD16An : Action::CalcD8AnXn)
#define pseq(x) (source_mode == 0x06 ? "n" x : x)
case 0x0501: // MOVE (d16, An), An
case 0x0601: // MOVE (d8, An, Xn), An
operation = Operation::MOVEAw;
case 0x0500: // MOVE (d16, An), Dn
case 0x0600: // MOVE (d8, An, Xn), Dn
op(action_calc() | MicroOp::SourceMask, seq(pseq("np nr np"), { &storage_.effective_address_[0] }, !is_byte_access));
@ -554,8 +562,11 @@ struct ProcessorStorageConstructor {
// Source = (xxx).W
//
case 0x1001: // MOVEA (xxx).W, Dn
operation = Operation::MOVEAw;
case 0x1000: // MOVE (xxx).W, Dn
// np nr np
op(int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask, seq("np"));
op(Action::PerformOperation, seq("nr np", { &storage_.effective_address_[0] }, !is_byte_access));
continue;
case 0x1002: // MOVE (xxx).W, (An)
@ -587,8 +598,11 @@ struct ProcessorStorageConstructor {
// Source = (xxx).L
//
case 0x1100: // MOVE (xxx).L, Dn
// np np nr np
case 0x1101: // MOVEA (xxx).W, Dn
operation = Operation::MOVEAw;
case 0x1100: // MOVE (xxx).W, Dn
op(int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask, seq("np np"));
op(Action::PerformOperation, seq("nr np", { &storage_.effective_address_[0] }, !is_byte_access));
continue;
//
@ -613,6 +627,8 @@ struct ProcessorStorageConstructor {
// Source = #
//
case 0x1401: // MOVE #, Dn
operation = Operation::MOVEAw;
case 0x1400: // MOVE #, Dn
storage_.instructions[instruction].source = &storage_.prefetch_queue_;
op(int(Action::PerformOperation), seq("np np"));

View File

@ -129,10 +129,10 @@ class ProcessorStorage {
/// Adds 4.
Increment4,
/// Peeking into the prefetch queue, calculates the proper target of (d16,An) addressing.
/// Peeking into the end of the prefetch queue, calculates the proper target of (d16,An) addressing.
CalcD16An,
/// Peeking into the prefetch queue, calculates the proper target of (d8,An,Xn) addressing.
/// Peeking into the end of the prefetch queue, calculates the proper target of (d8,An,Xn) addressing.
CalcD8AnXn,
/// Peeking into the prefetch queue, calculates the proper target of (d16,PC) addressing,
@ -151,9 +151,12 @@ 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].
/// From the next word in the prefetch queue assembles a 0-padded 32-bit long word in either or
/// both of effective_address_[0] and effective_address_[1].
AssembleWordFromPrefetch,
/// Copies the next two prefetch words into one of the effective_address_.
AssembleLongWordFromPrefetch
};
static const int SourceMask = 1 << 30;
static const int DestinationMask = 1 << 29;