mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-08 14:25:05 +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:
@@ -199,11 +199,11 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask:
|
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;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD16An) | MicroOp::DestinationMask:
|
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;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask | MicroOp::DestinationMask:
|
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: {
|
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;
|
} break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::DestinationMask: {
|
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;
|
} break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask | MicroOp::DestinationMask: {
|
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
|
#undef CalculateD8AnXn
|
||||||
|
|
||||||
case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask:
|
case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask:
|
||||||
bus_data_[0] = prefetch_queue_.full;
|
effective_address_[0] = prefetch_queue_.halves.high.full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::DestinationMask:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +329,7 @@ template <class T, bool dtack_is_implicit> ProcessorState Processor<T, dtack_is_
|
|||||||
(negative_flag_ ? 0x0008 : 0x0000) |
|
(negative_flag_ ? 0x0008 : 0x0000) |
|
||||||
(extend_flag_ ? 0x0010 : 0x0000) |
|
(extend_flag_ ? 0x0010 : 0x0000) |
|
||||||
|
|
||||||
(is_supervisor_ ? 0x2000 : 0x0000);
|
(is_supervisor_ << 13);
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@@ -420,6 +420,9 @@ struct ProcessorStorageConstructor {
|
|||||||
// Source = (An) or (An)+
|
// 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 0x0200: // MOVE (An), Dn
|
||||||
case 0x0300: // MOVE (An)+, Dn
|
case 0x0300: // MOVE (An)+, Dn
|
||||||
op(Action::None, seq("nr np", { &storage_.address_[source_register].full }, !is_byte_access));
|
op(Action::None, seq("nr np", { &storage_.address_[source_register].full }, !is_byte_access));
|
||||||
@@ -465,6 +468,8 @@ struct ProcessorStorageConstructor {
|
|||||||
// Source = -(An)
|
// Source = -(An)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
case 0x0401: // MOVEA -(An), An
|
||||||
|
operation = Operation::MOVEAw; // Substitute MOVEA for MOVE.
|
||||||
case 0x0400: // MOVE -(An), Dn
|
case 0x0400: // MOVE -(An), Dn
|
||||||
op( int(is_byte_access ? Action::Decrement1 : Action::Decrement2) | MicroOp::SourceMask,
|
op( int(is_byte_access ? Action::Decrement1 : Action::Decrement2) | MicroOp::SourceMask,
|
||||||
seq("n nr np", { &storage_.address_[source_register].full }, !is_byte_access));
|
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 action_calc() int(source_mode == 0x05 ? Action::CalcD16An : Action::CalcD8AnXn)
|
||||||
#define pseq(x) (source_mode == 0x06 ? "n" x : x)
|
#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 0x0500: // MOVE (d16, An), Dn
|
||||||
case 0x0600: // MOVE (d8, An, Xn), 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));
|
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
|
// Source = (xxx).W
|
||||||
//
|
//
|
||||||
|
|
||||||
|
case 0x1001: // MOVEA (xxx).W, Dn
|
||||||
|
operation = Operation::MOVEAw;
|
||||||
case 0x1000: // MOVE (xxx).W, Dn
|
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;
|
continue;
|
||||||
|
|
||||||
case 0x1002: // MOVE (xxx).W, (An)
|
case 0x1002: // MOVE (xxx).W, (An)
|
||||||
@@ -587,8 +598,11 @@ struct ProcessorStorageConstructor {
|
|||||||
// Source = (xxx).L
|
// Source = (xxx).L
|
||||||
//
|
//
|
||||||
|
|
||||||
case 0x1100: // MOVE (xxx).L, Dn
|
case 0x1101: // MOVEA (xxx).W, Dn
|
||||||
// np np nr np
|
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;
|
continue;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -613,6 +627,8 @@ struct ProcessorStorageConstructor {
|
|||||||
// Source = #
|
// Source = #
|
||||||
//
|
//
|
||||||
|
|
||||||
|
case 0x1401: // MOVE #, Dn
|
||||||
|
operation = Operation::MOVEAw;
|
||||||
case 0x1400: // MOVE #, Dn
|
case 0x1400: // MOVE #, Dn
|
||||||
storage_.instructions[instruction].source = &storage_.prefetch_queue_;
|
storage_.instructions[instruction].source = &storage_.prefetch_queue_;
|
||||||
op(int(Action::PerformOperation), seq("np np"));
|
op(int(Action::PerformOperation), seq("np np"));
|
||||||
|
@@ -129,10 +129,10 @@ class ProcessorStorage {
|
|||||||
/// Adds 4.
|
/// Adds 4.
|
||||||
Increment4,
|
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,
|
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,
|
CalcD8AnXn,
|
||||||
|
|
||||||
/// Peeking into the prefetch queue, calculates the proper target of (d16,PC) addressing,
|
/// 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.
|
/// 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
|
/// From the next word in the prefetch queue assembles a 0-padded 32-bit long word in either or
|
||||||
/// both of bus_data_[0] and bus_data_[1].
|
/// both of effective_address_[0] and effective_address_[1].
|
||||||
AssembleWordFromPrefetch,
|
AssembleWordFromPrefetch,
|
||||||
|
|
||||||
|
/// Copies the next two prefetch words into one of the effective_address_.
|
||||||
|
AssembleLongWordFromPrefetch
|
||||||
};
|
};
|
||||||
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