mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-13 00:25:26 +00:00
Fix MOVEM timing.
This commit is contained in:
@@ -272,10 +272,6 @@ template <typename M68000> struct Tester {
|
|||||||
// InstructionSet::M68k::Operation::NEGXw, // Old implementation omits an idle cycle before -(An)
|
// InstructionSet::M68k::Operation::NEGXw, // Old implementation omits an idle cycle before -(An)
|
||||||
// InstructionSet::M68k::Operation::NEGb, // Old implementation omits an idle cycle before -(An)
|
// InstructionSet::M68k::Operation::NEGb, // Old implementation omits an idle cycle before -(An)
|
||||||
// InstructionSet::M68k::Operation::NEGw, // Old implementation omits an idle cycle before -(An)
|
// InstructionSet::M68k::Operation::NEGw, // Old implementation omits an idle cycle before -(An)
|
||||||
InstructionSet::M68k::Operation::MOVEMtoRl,
|
|
||||||
InstructionSet::M68k::Operation::MOVEMtoRw,
|
|
||||||
InstructionSet::M68k::Operation::MOVEMtoMl,
|
|
||||||
InstructionSet::M68k::Operation::MOVEMtoMw,
|
|
||||||
// InstructionSet::M68k::Operation::NOTb, // Old implementation omits an idle cycle before -(An)
|
// InstructionSet::M68k::Operation::NOTb, // Old implementation omits an idle cycle before -(An)
|
||||||
// InstructionSet::M68k::Operation::NOTw, // Old implementation omits an idle cycle before -(An)
|
// InstructionSet::M68k::Operation::NOTw, // Old implementation omits an idle cycle before -(An)
|
||||||
// InstructionSet::M68k::Operation::MULU,
|
// InstructionSet::M68k::Operation::MULU,
|
||||||
|
@@ -173,7 +173,6 @@ enum ExecutionState: int {
|
|||||||
LEA,
|
LEA,
|
||||||
PEA,
|
PEA,
|
||||||
TAS,
|
TAS,
|
||||||
TASAddressRegisterIndirectWithIndex8bitDisplacement,
|
|
||||||
MOVEtoCCRSR,
|
MOVEtoCCRSR,
|
||||||
RTR,
|
RTR,
|
||||||
RTE,
|
RTE,
|
||||||
@@ -185,6 +184,9 @@ enum ExecutionState: int {
|
|||||||
STOP,
|
STOP,
|
||||||
TRAP,
|
TRAP,
|
||||||
TRAPV,
|
TRAPV,
|
||||||
|
|
||||||
|
AddressRegisterIndirectWithIndex8bitDisplacement_n_np,
|
||||||
|
ProgramCounterIndirectWithIndex8bitDisplacement_n_np,
|
||||||
};
|
};
|
||||||
|
|
||||||
// MARK: - The state machine.
|
// MARK: - The state machine.
|
||||||
@@ -983,15 +985,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Mode::AddressRegisterIndirectWithIndex8bitDisplacement:
|
case Mode::AddressRegisterIndirectWithIndex8bitDisplacement:
|
||||||
MoveToStateSpecific(TASAddressRegisterIndirectWithIndex8bitDisplacement);
|
post_ea_state_ = TAS;
|
||||||
|
MoveToStateSpecific(AddressRegisterIndirectWithIndex8bitDisplacement_n_np);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
post_ea_state_ = TAS;
|
post_ea_state_ = TAS;
|
||||||
MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec);
|
MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec);
|
||||||
}
|
}
|
||||||
if(instruction_.mode(0) != Mode::DataRegisterDirect) {
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
StdCASE(MOVEtoCCR, perform_state_ = MOVEtoCCRSR);
|
StdCASE(MOVEtoCCR, perform_state_ = MOVEtoCCRSR);
|
||||||
@@ -1398,11 +1398,11 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
temporary_address_.l = instruction_address_.l + 4;
|
temporary_address_.l = instruction_address_.l + 4;
|
||||||
MoveToStateDynamic(post_ea_state_);
|
MoveToStateDynamic(post_ea_state_);
|
||||||
|
|
||||||
BeginState(TASAddressRegisterIndirectWithIndex8bitDisplacement):
|
BeginState(AddressRegisterIndirectWithIndex8bitDisplacement_n_np):
|
||||||
effective_address_[0].l = d8Xn(registers_[8 + instruction_.reg(next_operand_)].l);
|
effective_address_[next_operand_].l = d8Xn(registers_[8 + instruction_.reg(next_operand_)].l);
|
||||||
IdleBus(1); // n
|
IdleBus(1); // n
|
||||||
Prefetch(); // np
|
Prefetch(); // np
|
||||||
MoveToStateSpecific(TAS);
|
MoveToStateDynamic(post_ea_state_);
|
||||||
|
|
||||||
//
|
//
|
||||||
// ProgramCounterIndirectWithIndex8bitDisplacement
|
// ProgramCounterIndirectWithIndex8bitDisplacement
|
||||||
@@ -1439,6 +1439,12 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
temporary_address_.l = instruction_address_.l + 4;
|
temporary_address_.l = instruction_address_.l + 4;
|
||||||
MoveToStateDynamic(post_ea_state_);
|
MoveToStateDynamic(post_ea_state_);
|
||||||
|
|
||||||
|
BeginState(ProgramCounterIndirectWithIndex8bitDisplacement_n_np):
|
||||||
|
effective_address_[next_operand_].l = d8Xn(program_counter_.l - 2);
|
||||||
|
IdleBus(1); // n
|
||||||
|
Prefetch(); // np
|
||||||
|
MoveToStateDynamic(post_ea_state_);
|
||||||
|
|
||||||
#undef d8Xn
|
#undef d8Xn
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -2114,7 +2120,17 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
|
|
||||||
SetDataAddress(effective_address_[1].l);
|
SetDataAddress(effective_address_[1].l);
|
||||||
SetupDataAccess(Microcycle::Read, Microcycle::SelectWord);
|
SetupDataAccess(Microcycle::Read, Microcycle::SelectWord);
|
||||||
MoveToStateSpecific(CalcEffectiveAddress);
|
|
||||||
|
switch(instruction_.mode(1)) {
|
||||||
|
case Mode::AddressRegisterIndirectWithIndex8bitDisplacement:
|
||||||
|
MoveToStateSpecific(AddressRegisterIndirectWithIndex8bitDisplacement_n_np);
|
||||||
|
|
||||||
|
case Mode::ProgramCounterIndirectWithIndex8bitDisplacement:
|
||||||
|
MoveToStateSpecific(ProgramCounterIndirectWithIndex8bitDisplacement_n_np);
|
||||||
|
|
||||||
|
default:
|
||||||
|
MoveToStateSpecific(CalcEffectiveAddress);
|
||||||
|
}
|
||||||
|
|
||||||
BeginState(MOVEMtoR_w_read):
|
BeginState(MOVEMtoR_w_read):
|
||||||
// If there's nothing left to read, move on.
|
// If there's nothing left to read, move on.
|
||||||
@@ -2178,27 +2194,37 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
|
|||||||
SetDataAddress(effective_address_[1].l);
|
SetDataAddress(effective_address_[1].l);
|
||||||
SetupDataAccess(0, Microcycle::SelectWord);
|
SetupDataAccess(0, Microcycle::SelectWord);
|
||||||
|
|
||||||
// Predecrement writes registers the other way around, but still reads the
|
|
||||||
// mask from LSB.
|
|
||||||
if(instruction_.mode(1) == Mode::AddressRegisterIndirectWithPredecrement) {
|
|
||||||
register_index_ = 15;
|
|
||||||
effective_address_[1].l = registers_[8 + instruction_.reg(1)].l;
|
|
||||||
|
|
||||||
// Don't go through the usual calculate EA path because: (i) the test above
|
|
||||||
// has already told us the addressing mode, and it's trivial; and (ii) the
|
|
||||||
// predecrement isn't actually wanted.
|
|
||||||
if(instruction_.operation == InstructionSet::M68k::Operation::MOVEMtoMl) {
|
|
||||||
MoveToStateSpecific(MOVEMtoM_l_write_predec);
|
|
||||||
} else {
|
|
||||||
MoveToStateSpecific(MOVEMtoM_w_write_predec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_index_ = 0;
|
register_index_ = 0;
|
||||||
post_ea_state_ =
|
post_ea_state_ =
|
||||||
(instruction_.operation == InstructionSet::M68k::Operation::MOVEMtoMl) ?
|
(instruction_.operation == InstructionSet::M68k::Operation::MOVEMtoMl) ?
|
||||||
MOVEMtoM_l_write : MOVEMtoM_w_write;
|
MOVEMtoM_l_write : MOVEMtoM_w_write;
|
||||||
MoveToStateSpecific(CalcEffectiveAddress);
|
|
||||||
|
// Predecrement writes registers the other way around, but still reads the
|
||||||
|
// mask from LSB.
|
||||||
|
switch(instruction_.mode(1)) {
|
||||||
|
case Mode::AddressRegisterIndirectWithPredecrement:
|
||||||
|
register_index_ = 15;
|
||||||
|
effective_address_[1].l = registers_[8 + instruction_.reg(1)].l;
|
||||||
|
|
||||||
|
// Don't go through the usual calculate EA path because: (i) the test above
|
||||||
|
// has already told us the addressing mode, and it's trivial; and (ii) the
|
||||||
|
// predecrement isn't actually wanted.
|
||||||
|
if(instruction_.operation == InstructionSet::M68k::Operation::MOVEMtoMl) {
|
||||||
|
MoveToStateSpecific(MOVEMtoM_l_write_predec);
|
||||||
|
} else {
|
||||||
|
MoveToStateSpecific(MOVEMtoM_w_write_predec);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mode::AddressRegisterIndirectWithIndex8bitDisplacement:
|
||||||
|
MoveToStateSpecific(AddressRegisterIndirectWithIndex8bitDisplacement_n_np);
|
||||||
|
|
||||||
|
case Mode::ProgramCounterIndirectWithIndex8bitDisplacement:
|
||||||
|
MoveToStateSpecific(ProgramCounterIndirectWithIndex8bitDisplacement_n_np);
|
||||||
|
|
||||||
|
default:
|
||||||
|
MoveToStateSpecific(CalcEffectiveAddress);
|
||||||
|
}
|
||||||
|
|
||||||
BeginState(MOVEMtoM_w_write):
|
BeginState(MOVEMtoM_w_write):
|
||||||
// If there's nothing left to read, move on.
|
// If there's nothing left to read, move on.
|
||||||
|
Reference in New Issue
Block a user