1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Resolve PEA timing errors.

This commit is contained in:
Thomas Harte 2022-06-13 14:08:42 -04:00
parent 7dc66128c2
commit e066546c13
2 changed files with 70 additions and 9 deletions

View File

@ -262,7 +262,6 @@ template <typename M68000> struct Tester {
// InstructionSet::M68k::Operation::MOVEb,
// InstructionSet::M68k::Operation::MOVEw,
// InstructionSet::M68k::Operation::MOVEl,
// InstructionSet::M68k::Operation::PEA,
// InstructionSet::M68k::Operation::MOVEtoSR, // Old implementation doesn't repeat a PC fetch.
// InstructionSet::M68k::Operation::MOVEtoCCR, // Old implementation doesn't repeat a PC fetch.
// InstructionSet::M68k::Operation::CMPAl, // Old implementation omits an idle cycle before -(An)
@ -285,6 +284,7 @@ template <typename M68000> struct Tester {
// InstructionSet::M68k::Operation::TAS, // Old implementation just doesn't match published cycle counts.
};
int testsRun = 0;
std::set<InstructionSet::M68k::Operation> failing_operations;
for(int c = 0; c < 65536; c++) {
// printf("%04x\n", c);
@ -305,6 +305,8 @@ template <typename M68000> struct Tester {
// Test each 1000 times.
for(int test = 0; test < 100; test++) {
++testsRun;
// Establish with certainty the initial memory state.
random_store.clear();
newTester->reset_with_opcode(c);
@ -408,9 +410,14 @@ template <typename M68000> struct Tester {
}
}
printf("\nAll failing operations:\n");
for(const auto operation: failing_operations) {
printf("%d,\n", int(operation));
printf("%d tests run\n", testsRun);
if(failing_operations.empty()) {
printf("No failures\n");
} else {
printf("\nAll failing operations:\n");
for(const auto operation: failing_operations) {
printf("%d,\n", int(operation));
}
}
}

View File

@ -64,8 +64,10 @@ enum ExecutionState: int {
/// Perform the proper sequence to fetch a byte or word operand.
AddressingDispatch(FetchOperand_bw),
/// Perform the proper sequence to fetch a long-word operand.
AddressingDispatch(FetchOperand_l),
/// Perform the sequence to calculate an effective address, but don't fetch from it.
/// There's a lack of uniformity in the bus programs used by the 68000 for relevant
/// instructions; this entry point uses:
@ -76,6 +78,7 @@ enum ExecutionState: int {
/// (d16, PC) np (d8, PC, Xn) np n
/// (xxx).w np (xxx).l np np
AddressingDispatch(CalcEffectiveAddress),
/// Similar to CalcEffectiveAddress, but varies slightly in the patterns:
///
/// -(An) n
@ -153,7 +156,6 @@ enum ExecutionState: int {
DIVU_DIVS,
Perform_idle_dyamic_Dn,
LEA,
PEA,
TAS,
MOVEtoCCRSR,
RTR,
@ -169,6 +171,10 @@ enum ExecutionState: int {
AddressRegisterIndirectWithIndex8bitDisplacement_n_np,
ProgramCounterIndirectWithIndex8bitDisplacement_n_np,
AddressingDispatch(PEA),
PEA_np_nS_ns, // Used to complete (An), (d16, [An/PC]) and (d8, [An/PC], Xn).
PEA_np_nS_ns_np, // Used to complete (xxx).w and (xxx).l
};
#undef AddressingDispatch
@ -961,10 +967,7 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
post_ea_state_ = LEA;
MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec);
});
StdCASE(PEA, {
post_ea_state_ = PEA;
MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec);
});
SpecialCASE(PEA);
StdCASE(TAS, {
// TAS uses a special atomic bus cycle for memory accesses,
@ -1130,6 +1133,10 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
effective_address_[next_operand_].l = registers_[8 + instruction_.reg(next_operand_)].l;
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, AddressRegisterIndirect):
effective_address_[0].l = registers_[8 + instruction_.reg(next_operand_)].l;
MoveToStateDynamic(PEA_np_nS_ns);
BeginState(JSRJMPAddressRegisterIndirect):
effective_address_[0].l = registers_[8 + instruction_.reg(next_operand_)].l;
temporary_address_.l = instruction_address_.l + 2;
@ -1200,6 +1207,7 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
//
// AddressRegisterIndirectWithDisplacement
//
BeginStateMode(FetchOperand_bw, AddressRegisterIndirectWithDisplacement):
effective_address_[next_operand_].l =
registers_[8 + instruction_.reg(next_operand_)].l +
@ -1230,6 +1238,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
Prefetch(); // np
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, AddressRegisterIndirectWithDisplacement):
effective_address_[0].l =
registers_[8 + instruction_.reg(next_operand_)].l +
uint32_t(int16_t(prefetch_.w));
Prefetch();
MoveToStateDynamic(PEA_np_nS_ns);
BeginState(JSRJMPAddressRegisterIndirectWithDisplacement):
effective_address_[0].l =
registers_[8 + instruction_.reg(next_operand_)].l +
@ -1271,6 +1286,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
Prefetch(); // np
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, ProgramCounterIndirectWithDisplacement):
effective_address_[0].l =
program_counter_.l - 2 +
uint32_t(int16_t(prefetch_.w));
Prefetch();
MoveToStateDynamic(PEA_np_nS_ns);
BeginState(JSRJMPProgramCounterIndirectWithDisplacement):
effective_address_[0].l =
program_counter_.l - 2 +
@ -1319,6 +1341,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
IdleBus(1); // n
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, AddressRegisterIndirectWithIndex8bitDisplacement):
effective_address_[0].l = d8Xn(registers_[8 + instruction_.reg(next_operand_)].l);
IdleBus(1); // n
Prefetch(); // np
IdleBus(1); // n
MoveToStateDynamic(PEA_np_nS_ns);
BeginState(JSRJMPAddressRegisterIndirectWithIndex8bitDisplacement):
effective_address_[0].l = d8Xn(registers_[8 + instruction_.reg(next_operand_)].l);
IdleBus(3); // n nn
@ -1364,6 +1393,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
IdleBus(1); // n
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, ProgramCounterIndirectWithIndex8bitDisplacement):
effective_address_[0].l = d8Xn(program_counter_.l - 2);
IdleBus(1); // n
Prefetch(); // np
IdleBus(1); // n
MoveToStateDynamic(PEA_np_nS_ns);
BeginState(JSRJMPProgramCounterIndirectWithIndex8bitDisplacement):
effective_address_[0].l = d8Xn(program_counter_.l - 2);
IdleBus(3); // n nn
@ -1405,6 +1441,10 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
Prefetch(); // np
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, AbsoluteShort):
effective_address_[0].l = uint32_t(int16_t(prefetch_.w));
MoveToStateSpecific(PEA_np_nS_ns_np);
BeginState(JSRJMPAbsoluteShort):
effective_address_[0].l = uint32_t(int16_t(prefetch_.w));
IdleBus(1); // n
@ -1443,6 +1483,11 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
Prefetch(); // np
MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, AbsoluteLong):
Prefetch(); // np
effective_address_[0].l = prefetch_.l;
MoveToStateSpecific(PEA_np_nS_ns_np);
BeginState(JSRJMPAbsoluteLong):
Prefetch(); // np
effective_address_[0].l = prefetch_.l;
@ -2306,6 +2351,15 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
// PEA
//
BeginState(PEA):
MoveToAddressingMode(PEA, instruction_.mode(0));
BeginState(PEA_np_nS_ns):
Prefetch();
Push(effective_address_[0]);
MoveToStateSpecific(Decode);
BeginState(PEA_np_nS_ns_np):
Prefetch();
Push(effective_address_[0]);
Prefetch();
MoveToStateSpecific(Decode);