1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-20 14:29:11 +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::MOVEb,
// InstructionSet::M68k::Operation::MOVEw, // InstructionSet::M68k::Operation::MOVEw,
// InstructionSet::M68k::Operation::MOVEl, // InstructionSet::M68k::Operation::MOVEl,
// InstructionSet::M68k::Operation::PEA,
// InstructionSet::M68k::Operation::MOVEtoSR, // Old implementation doesn't repeat a PC fetch. // 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::MOVEtoCCR, // Old implementation doesn't repeat a PC fetch.
// InstructionSet::M68k::Operation::CMPAl, // Old implementation omits an idle cycle before -(An) // 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. // InstructionSet::M68k::Operation::TAS, // Old implementation just doesn't match published cycle counts.
}; };
int testsRun = 0;
std::set<InstructionSet::M68k::Operation> failing_operations; std::set<InstructionSet::M68k::Operation> failing_operations;
for(int c = 0; c < 65536; c++) { for(int c = 0; c < 65536; c++) {
// printf("%04x\n", c); // printf("%04x\n", c);
@ -305,6 +305,8 @@ template <typename M68000> struct Tester {
// Test each 1000 times. // Test each 1000 times.
for(int test = 0; test < 100; test++) { for(int test = 0; test < 100; test++) {
++testsRun;
// Establish with certainty the initial memory state. // Establish with certainty the initial memory state.
random_store.clear(); random_store.clear();
newTester->reset_with_opcode(c); newTester->reset_with_opcode(c);
@ -408,9 +410,14 @@ template <typename M68000> struct Tester {
} }
} }
printf("\nAll failing operations:\n"); printf("%d tests run\n", testsRun);
for(const auto operation: failing_operations) { if(failing_operations.empty()) {
printf("%d,\n", int(operation)); 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. /// Perform the proper sequence to fetch a byte or word operand.
AddressingDispatch(FetchOperand_bw), AddressingDispatch(FetchOperand_bw),
/// Perform the proper sequence to fetch a long-word operand. /// Perform the proper sequence to fetch a long-word operand.
AddressingDispatch(FetchOperand_l), AddressingDispatch(FetchOperand_l),
/// Perform the sequence to calculate an effective address, but don't fetch from it. /// 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 /// There's a lack of uniformity in the bus programs used by the 68000 for relevant
/// instructions; this entry point uses: /// instructions; this entry point uses:
@ -76,6 +78,7 @@ enum ExecutionState: int {
/// (d16, PC) np (d8, PC, Xn) np n /// (d16, PC) np (d8, PC, Xn) np n
/// (xxx).w np (xxx).l np np /// (xxx).w np (xxx).l np np
AddressingDispatch(CalcEffectiveAddress), AddressingDispatch(CalcEffectiveAddress),
/// Similar to CalcEffectiveAddress, but varies slightly in the patterns: /// Similar to CalcEffectiveAddress, but varies slightly in the patterns:
/// ///
/// -(An) n /// -(An) n
@ -153,7 +156,6 @@ enum ExecutionState: int {
DIVU_DIVS, DIVU_DIVS,
Perform_idle_dyamic_Dn, Perform_idle_dyamic_Dn,
LEA, LEA,
PEA,
TAS, TAS,
MOVEtoCCRSR, MOVEtoCCRSR,
RTR, RTR,
@ -169,6 +171,10 @@ enum ExecutionState: int {
AddressRegisterIndirectWithIndex8bitDisplacement_n_np, AddressRegisterIndirectWithIndex8bitDisplacement_n_np,
ProgramCounterIndirectWithIndex8bitDisplacement_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 #undef AddressingDispatch
@ -961,10 +967,7 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
post_ea_state_ = LEA; post_ea_state_ = LEA;
MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec); MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec);
}); });
StdCASE(PEA, { SpecialCASE(PEA);
post_ea_state_ = PEA;
MoveToStateSpecific(CalcEffectiveAddressIdleFor8bitDisplacementAndPreDec);
});
StdCASE(TAS, { StdCASE(TAS, {
// TAS uses a special atomic bus cycle for memory accesses, // 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; effective_address_[next_operand_].l = registers_[8 + instruction_.reg(next_operand_)].l;
MoveToStateDynamic(post_ea_state_); 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): BeginState(JSRJMPAddressRegisterIndirect):
effective_address_[0].l = registers_[8 + instruction_.reg(next_operand_)].l; effective_address_[0].l = registers_[8 + instruction_.reg(next_operand_)].l;
temporary_address_.l = instruction_address_.l + 2; temporary_address_.l = instruction_address_.l + 2;
@ -1200,6 +1207,7 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
// //
// AddressRegisterIndirectWithDisplacement // AddressRegisterIndirectWithDisplacement
// //
BeginStateMode(FetchOperand_bw, AddressRegisterIndirectWithDisplacement): BeginStateMode(FetchOperand_bw, AddressRegisterIndirectWithDisplacement):
effective_address_[next_operand_].l = effective_address_[next_operand_].l =
registers_[8 + instruction_.reg(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 Prefetch(); // np
MoveToStateDynamic(post_ea_state_); 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): BeginState(JSRJMPAddressRegisterIndirectWithDisplacement):
effective_address_[0].l = effective_address_[0].l =
registers_[8 + instruction_.reg(next_operand_)].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 Prefetch(); // np
MoveToStateDynamic(post_ea_state_); 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): BeginState(JSRJMPProgramCounterIndirectWithDisplacement):
effective_address_[0].l = effective_address_[0].l =
program_counter_.l - 2 + program_counter_.l - 2 +
@ -1319,6 +1341,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
IdleBus(1); // n IdleBus(1); // n
MoveToStateDynamic(post_ea_state_); 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): BeginState(JSRJMPAddressRegisterIndirectWithIndex8bitDisplacement):
effective_address_[0].l = d8Xn(registers_[8 + instruction_.reg(next_operand_)].l); effective_address_[0].l = d8Xn(registers_[8 + instruction_.reg(next_operand_)].l);
IdleBus(3); // n nn IdleBus(3); // n nn
@ -1364,6 +1393,13 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
IdleBus(1); // n IdleBus(1); // n
MoveToStateDynamic(post_ea_state_); 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): BeginState(JSRJMPProgramCounterIndirectWithIndex8bitDisplacement):
effective_address_[0].l = d8Xn(program_counter_.l - 2); effective_address_[0].l = d8Xn(program_counter_.l - 2);
IdleBus(3); // n nn IdleBus(3); // n nn
@ -1405,6 +1441,10 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
Prefetch(); // np Prefetch(); // np
MoveToStateDynamic(post_ea_state_); 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): BeginState(JSRJMPAbsoluteShort):
effective_address_[0].l = uint32_t(int16_t(prefetch_.w)); effective_address_[0].l = uint32_t(int16_t(prefetch_.w));
IdleBus(1); // n IdleBus(1); // n
@ -1443,6 +1483,11 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
Prefetch(); // np Prefetch(); // np
MoveToStateDynamic(post_ea_state_); MoveToStateDynamic(post_ea_state_);
BeginStateMode(PEA, AbsoluteLong):
Prefetch(); // np
effective_address_[0].l = prefetch_.l;
MoveToStateSpecific(PEA_np_nS_ns_np);
BeginState(JSRJMPAbsoluteLong): BeginState(JSRJMPAbsoluteLong):
Prefetch(); // np Prefetch(); // np
effective_address_[0].l = prefetch_.l; effective_address_[0].l = prefetch_.l;
@ -2306,6 +2351,15 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
// PEA // PEA
// //
BeginState(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]); Push(effective_address_[0]);
Prefetch(); Prefetch();
MoveToStateSpecific(Decode); MoveToStateSpecific(Decode);