1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-23 03:32:32 +00:00

Ensures that page-crossing indexing no longer causes an extra read of an invalid address on the 65C02.

It rereads the last byte of the instruction stream instead.
This commit is contained in:
Thomas Harte 2018-08-15 18:47:53 -04:00
parent 901e0d65b9
commit c35dca783f
2 changed files with 23 additions and 11 deletions

View File

@ -436,32 +436,42 @@ if(number_of_cycles <= Cycles(0)) break;
// MARK: - Addressing Mode Work
#define page_crossing_stall_read() \
if(is_65c02(personality)) { \
throwaway_read(pc_.full - 1); \
} else { \
throwaway_read(address_.full); \
}
case CycleAddXToAddressLow:
nextAddress.full = address_.full + x_;
address_.bytes.low = nextAddress.bytes.low;
if(address_.bytes.high != nextAddress.bytes.high) {
throwaway_read(address_.full);
if(address_.bytes.high != nextAddress.bytes.high) {
page_crossing_stall_read();
break;
}
continue;
case CycleAddXToAddressLowRead:
nextAddress.full = address_.full + x_;
address_.bytes.low = nextAddress.bytes.low;
throwaway_read(address_.full);
page_crossing_stall_read();
break;
case CycleAddYToAddressLow:
nextAddress.full = address_.full + y_;
address_.bytes.low = nextAddress.bytes.low;
if(address_.bytes.high != nextAddress.bytes.high) {
throwaway_read(address_.full);
page_crossing_stall_read();
break;
}
continue;
case CycleAddYToAddressLowRead:
nextAddress.full = address_.full + y_;
address_.bytes.low = nextAddress.bytes.low;
throwaway_read(address_.full);
page_crossing_stall_read();
break;
#undef page_crossing_stall_read
case OperationCorrectAddressHigh:
address_.full = nextAddress.full;
continue;

View File

@ -17,10 +17,12 @@ class ProcessorStorage {
protected:
ProcessorStorage(Personality);
/*
/*!
This emulation functions by decomposing instructions into micro programs, consisting of the micro operations
as per the enum below. Each micro op takes at most one cycle. By convention, those called CycleX take a cycle
defined by MicroOp. Each micro op takes at most one cycle. By convention, those called CycleX take a cycle
to perform whereas those called OperationX occur for free (so, in effect, their cost is loaded onto the next cycle).
This micro-instruction set was put together in a fairly ad hoc fashion, I'm afraid, so is unlikely to be optimal.
*/
enum MicroOp {
CycleFetchOperation, // fetches (PC) to operation_, storing PC to last_operation_pc_ before incrementing it
@ -72,10 +74,10 @@ class ProcessorStorage {
CycleLoadAddessZeroX, // copies (operand_+x)&0xff to address_, increments the PC, and reads from operand_, throwing away the result
CycleLoadAddessZeroY, // copies (operand_+y)&0xff to address_, increments the PC, and reads from operand_, throwing away the result
CycleAddXToAddressLow, // calculates address_ + x and stores it to next_address_; copies next_address_.l back to address_.l; if address_ now does not equal next_address_, schedules a throwaway read from address_
CycleAddYToAddressLow, // calculates address_ + y and stores it to next_address_; copies next_address_.l back to address_.l; if address_ now does not equal next_address_, schedules a throwaway read from address_
CycleAddXToAddressLowRead, // calculates address_ + x and stores it to next_address; copies next_address.l back to address_.l; schedules a throwaway read from address_
CycleAddYToAddressLowRead, // calculates address_ + y and stores it to next_address; copies next_address.l back to address_.l; schedules a throwaway read from address_
CycleAddXToAddressLow, // calculates address_ + x and stores it to next_address_; copies next_address_.l back to address_.l; 6502: if address_ now does not equal next_address_, schedules a throwaway read from address_; 65C02: schedules a throaway read from PC-1
CycleAddYToAddressLow, // calculates address_ + y and stores it to next_address_; copies next_address_.l back to address_.l; 6502: if address_ now does not equal next_address_, schedules a throwaway read from address_; 65C02: schedules a throaway read from PC-1
CycleAddXToAddressLowRead, // calculates address_ + x and stores it to next_address; copies next_address.l back to address_.l; 6502: schedules a throwaway read from address_; 65C02: schedules a throaway read from PC-1
CycleAddYToAddressLowRead, // calculates address_ + y and stores it to next_address; copies next_address.l back to address_.l; 6502: schedules a throwaway read from address_; 65C02: schedules a throaway read from PC-1
OperationCorrectAddressHigh, // copies next_address_ to address_
OperationIncrementPC, // increments the PC