mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-03 11:30:02 +00:00
Corrects MOVE -(An), SR/CCR, which was not previously decrementing.
Also adds a safety check against other instances of the same error. There seem to be none.
This commit is contained in:
parent
0d23f141d6
commit
096b447b4b
|
@ -2549,42 +2549,45 @@ struct ProcessorStorageConstructor {
|
||||||
program.set_source(storage_, ea_mode, ea_register);
|
program.set_source(storage_, ea_mode, ea_register);
|
||||||
program.set_requires_supervisor(operation == Operation::MOVEtoSR);
|
program.set_requires_supervisor(operation == Operation::MOVEtoSR);
|
||||||
|
|
||||||
|
is_long_word_access = false;
|
||||||
|
is_byte_access = false; // Even MOVE, CCR is a .w.
|
||||||
|
|
||||||
/* DEVIATION FROM YACHT.TXT: it has all of these reading an extra word from the PC;
|
/* DEVIATION FROM YACHT.TXT: it has all of these reading an extra word from the PC;
|
||||||
this looks like a mistake so I've padded with nil cycles in the middle. */
|
this looks like a mistake so I've padded with nil cycles in the middle. */
|
||||||
const int mode = combined_mode(ea_mode, ea_register);
|
const int mode = combined_mode(ea_mode, ea_register);
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
default: continue;
|
default: continue;
|
||||||
|
|
||||||
case Dn: // MOVE Dn, SR
|
case Dn: // MOVE Dn, SR/CCR
|
||||||
op(Action::PerformOperation, seq("nn np"));
|
op(Action::PerformOperation, seq("nn np"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Ind: // MOVE (An), SR
|
case Ind: // MOVE (An), SR/CCR
|
||||||
case PostInc: // MOVE (An)+, SR
|
case PostInc: // MOVE (An)+, SR/CCR
|
||||||
op(Action::None, seq("nr nn nn np", { a(ea_register) }));
|
op(Action::None, seq("nr nn nn np", { a(ea_register) }, !is_byte_access));
|
||||||
if(mode == PostInc) {
|
if(mode == PostInc) {
|
||||||
op(int(Action::Increment2) | MicroOp::SourceMask);
|
op(inc(ea_register) | MicroOp::SourceMask);
|
||||||
}
|
}
|
||||||
op(Action::PerformOperation);
|
op(Action::PerformOperation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PreDec: // MOVE -(An), SR
|
case PreDec: // MOVE -(An), SR/CCR
|
||||||
op(Action::Decrement2, seq("n nr nn nn np", { a(ea_register) }));
|
op(dec(ea_register) | MicroOp::SourceMask, seq("n nr nn nn np", { a(ea_register) }, !is_byte_access));
|
||||||
op(Action::PerformOperation);
|
op(Action::PerformOperation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XXXl: // MOVE (xxx).L, SR
|
case XXXl: // MOVE (xxx).L, SR/CCR
|
||||||
op(Action::None, seq("np"));
|
op(Action::None, seq("np"));
|
||||||
case XXXw: // MOVE (xxx).W, SR
|
case XXXw: // MOVE (xxx).W, SR/CCR
|
||||||
case d16PC: // MOVE (d16, PC), SR
|
case d16PC: // MOVE (d16, PC), SR/CCR
|
||||||
case d8PCXn: // MOVE (d8, PC, Xn), SR
|
case d8PCXn: // MOVE (d8, PC, Xn), SR/CCR
|
||||||
case d16An: // MOVE (d16, An), SR
|
case d16An: // MOVE (d16, An), SR/CCR
|
||||||
case d8AnXn: // MOVE (d8, An, Xn), SR
|
case d8AnXn: // MOVE (d8, An, Xn), SR/CCR
|
||||||
op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr nn nn np", mode), { ea(0) }));
|
op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr nn nn np", mode), { ea(0) }, !is_byte_access));
|
||||||
op(Action::PerformOperation);
|
op(Action::PerformOperation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Imm: // MOVE #, SR
|
case Imm: // MOVE #, SR/CCR
|
||||||
program.set_source(storage_, &storage_.prefetch_queue_);
|
program.set_source(storage_, &storage_.prefetch_queue_);
|
||||||
op(int(Action::PerformOperation), seq("np nn nn np"));
|
op(int(Action::PerformOperation), seq("np nn nn np"));
|
||||||
break;
|
break;
|
||||||
|
@ -3002,6 +3005,7 @@ struct ProcessorStorageConstructor {
|
||||||
// for improperly encoded address calculation-type actions.
|
// for improperly encoded address calculation-type actions.
|
||||||
for(auto index = micro_op_start; index < storage_.all_micro_ops_.size() - 1; ++index) {
|
for(auto index = micro_op_start; index < storage_.all_micro_ops_.size() - 1; ++index) {
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
// All of the actions below must also nominate a source and/or destination.
|
// All of the actions below must also nominate a source and/or destination.
|
||||||
switch(storage_.all_micro_ops_[index].action) {
|
switch(storage_.all_micro_ops_[index].action) {
|
||||||
default: break;
|
default: break;
|
||||||
|
@ -3012,8 +3016,15 @@ struct ProcessorStorageConstructor {
|
||||||
case int(Action::AssembleWordAddressFromPrefetch):
|
case int(Action::AssembleWordAddressFromPrefetch):
|
||||||
case int(Action::AssembleLongWordAddressFromPrefetch):
|
case int(Action::AssembleLongWordAddressFromPrefetch):
|
||||||
case int(Action::CopyToEffectiveAddress):
|
case int(Action::CopyToEffectiveAddress):
|
||||||
|
case int(Action::Increment1):
|
||||||
|
case int(Action::Increment2):
|
||||||
|
case int(Action::Increment4):
|
||||||
|
case int(Action::Decrement1):
|
||||||
|
case int(Action::Decrement2):
|
||||||
|
case int(Action::Decrement4):
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(storage_.all_micro_ops_[index].is_terminal()) {
|
if(storage_.all_micro_ops_[index].is_terminal()) {
|
||||||
storage_.all_micro_ops_[index].bus_program = uint16_t(seq(""));
|
storage_.all_micro_ops_[index].bus_program = uint16_t(seq(""));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user