1
0
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:
Thomas Harte 2019-12-16 22:38:54 -05:00
parent 0d23f141d6
commit 096b447b4b

View File

@ -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(""));