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

Merge pull request #1226 from TomHarte/65c02STAAbsX

Adjust 65c02 STA abs,x behaviour.
This commit is contained in:
Thomas Harte 2023-12-21 12:31:39 -05:00 committed by GitHub
commit dc03b2c03b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 14 deletions

View File

@ -544,11 +544,6 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
break; break;
} }
continue; continue;
case CycleAddXToAddressLowRead:
next_address_.full = address_.full + x_;
address_.halves.low = next_address_.halves.low;
page_crossing_stall_read();
break;
case CycleAddYToAddressLow: case CycleAddYToAddressLow:
next_address_.full = address_.full + y_; next_address_.full = address_.full + y_;
address_.halves.low = next_address_.halves.low; address_.halves.low = next_address_.halves.low;
@ -557,13 +552,36 @@ template <Personality personality, typename T, bool uses_ready_line> void Proces
break; break;
} }
continue; continue;
#undef page_crossing_stall_read
case CycleAddXToAddressLowRead:
next_address_.full = address_.full + x_;
address_.halves.low = next_address_.halves.low;
// Cf. https://groups.google.com/g/comp.sys.apple2/c/RuTGaRxu5Iw/m/uyFLEsF8ceIJ
//
// STA abs,X has been fixed for the PX (page-crossing) case by adding a dummy read of the
// program counter, so the change was rW -> W. In the non-PX case it still reads the destination
// address, so there is no change: RW -> RW.
if(!is_65c02(personality) || next_address_.full == address_.full) {
throwaway_read(address_.full);
} else {
throwaway_read(pc_.full - 1);
}
break;
case CycleAddYToAddressLowRead: case CycleAddYToAddressLowRead:
next_address_.full = address_.full + y_; next_address_.full = address_.full + y_;
address_.halves.low = next_address_.halves.low; address_.halves.low = next_address_.halves.low;
page_crossing_stall_read();
break;
#undef page_crossing_stall_read // A similar rule as for above applies; this one adjusts (abs, y) addressing.
if(!is_65c02(personality) || next_address_.full == address_.full) {
throwaway_read(address_.full);
} else {
throwaway_read(pc_.full - 1);
}
break;
case OperationCorrectAddressHigh: case OperationCorrectAddressHigh:
// Preserve the uncorrected address in next_address_ (albeit that it's // Preserve the uncorrected address in next_address_ (albeit that it's

View File

@ -346,11 +346,14 @@ ProcessorStorage::ProcessorStorage(Personality personality) {
} }
// Correct JMP (abs) and install JMP (abs, x). // Correct JMP (abs) and install JMP (abs, x).
//
// Guess: JMP (abs, x), being listed at a fixed 6 cycles, uses the slower abs,x of INC and DEC.
Install(0x6c, Program(CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddressLowInc, CycleReadPCHFromAddressFixed)); Install(0x6c, Program(CycleReadAddressHLoadAddressL, CycleReadPCLFromAddress, CycleReadPCHFromAddressLowInc, CycleReadPCHFromAddressFixed));
Install(0x7c, Program( Install(0x7c, Program(
CycleReadAddressHLoadAddressL, // (3) read second byte of (addr) CycleReadAddressHLoadAddressL, // (3) read second byte of (addr)
CycleAddXToAddressLowRead, // (4) calculate addr+x, read from (addr+x) with high byte not yet calculated CycleAddXToAddressLowRead,
OperationCorrectAddressHigh, CycleReadPCLFromAddress, // (5) read from real (addr+x) OperationCorrectAddressHigh, // (4) read from incorrectly-calculated address
CycleReadPCLFromAddress, // (5) read from real (addr+x)
CycleReadPCHFromAddressInc // (6) read from addr+x+1 CycleReadPCHFromAddressInc // (6) read from addr+x+1
)); ));

View File

@ -71,12 +71,19 @@ class ProcessorStorage {
CycleLoadAddessZeroX, // copies (operand_+x)&0xff to address_, increments the PC, and reads from operand_, throwing away the result 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 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; 6502: if address_ now does not equal next_address_, schedules a throwaway read from address_; 65C02: schedules a throaway read from PC-1 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 throwaway 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 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 throwaway 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_ OperationCorrectAddressHigh, // copies next_address_ to address_
// 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 throwaway read from PC-1 if a page boundary was crossed;
// otherwise does as per the 6502.
//
CycleAddXToAddressLowRead,
CycleAddYToAddressLowRead, // As per CycleAddXToAddressLowRead, but uses Y rather than X.
OperationIncrementPC, // increments the PC OperationIncrementPC, // increments the PC
CycleFetchOperandFromAddress, // fetches operand_ from address_ CycleFetchOperandFromAddress, // fetches operand_ from address_
CycleWriteOperandToAddress, // writes operand_ to address_ CycleWriteOperandToAddress, // writes operand_ to address_