Hi Dave,
I know exactly what you mean...
Yes, the MCL65 is CPU cycle exact as well as bus-cycle exact. It performs the exact same bus fetches, over-fetches, interrupts, and other sequences to match the original 6502. This was necessary to be able to use the core inside of an actual Apple II, Atari 2600, and Commodore computer. All signals/pins going to the 6502 are supported by the MCL65.
I also think that the true test of the "correctness" of a CPU core is to run it on actual vintage hardware where it can execute all of the programs used at the time. It it can run operating systems, games, and utilities on multiple systems, some of which are very cycle/bus timing dependent, then you can be sure the core is an accurate clone of the original CPU.
This was on my mind when designing the MCL65 and as far as I know it is the only 6502 core that can run timing/bus exact on vintage hardware.
Thanks,
-Ted
In fact, here is my JSR microcode routine which matches the cycles you described:
// -------------------------------------------------
// -------------------------------------------------
// 0x20 - JSR - Jump to Subroutine
// -------------------------------------------------
@470 277F_0001 // PC = PC + 1
@471 4A7F_0000 // ADDRESS_OUT = PC
@472 4DFF_0001 // SYNC=0, RD_WR_n=1
@473 1033_0000 // Wait for CLK to be high
@474 1034_0000 // Wait for CLK to be low
@475 32BF_00FF // r2 <= data_in AND 0x00FF -- Fetch ADL
@476 4A8F_0000 // ADDRESS_OUT = SP OR 0x0000
@477 4DFF_0001 // SYNC=0, RD_WR_n=1
@478 1033_0000 // Wait for CLK to be high
@479 277F_0001 // PC = PC + 1
@47A 1034_0000 // Wait for CLK to be low
@47B 3FBF_00FF // Dummy <= data_in AND 0x00FF -- discard data
@47C 4DFF_0000 // SYNC=0, RD_WR_n=0
@47D 4BF7_0000 // Data_Out <= 0x0000 OR PC_Byte_Swapped
@47E 288F_FFFF // SP <= SP - 1
@47F 1033_0000 // Wait for CLK to be high
@480 4DFF_0004 // Dataout_Enable=1, SYNC=0, RD_WR_n=0
@481 1034_0000 // Wait for CLK to be low
@482 4DFF_0000 // Dataout_Enable=0, SYNC=0, RD_WR_n=1 -- Push PCH
@483 4A8F_0000 // ADDRESS_OUT = SP OR 0x0000
@484 4B7F_0000 // Data_Out <= 0x0000 OR PC
@485 1033_0000 // Wait for CLK to be high
@486 4DFF_0004 // Dataout_Enable=1, SYNC=0, RD_WR_n=0
@487 1034_0000 // Wait for CLK to be low
@488 4DFF_0000 // Dataout_Enable=0, SYNC=0, RD_WR_n=1 -- Push PCL
@489 4A7F_0000 // ADDRESS_OUT = PC
@48A 4DFF_0001 // SYNC=0, RD_WR_n=1
@48B 1033_0000 // Wait for CLK to be high
@48C 288F_FFFF // SP <= SP - 1
@48D 1034_0000 // Wait for CLK to be low
@48E 31BF_FF00 // r1 <= data_in AND 0xFF00 -- Fetch ADH
@48F 4712_0000 // PC = r1 OR r2
@490 4A7F_0000 // ADDRESS_OUT = PC
@491 4DFF_0003 // SYNC=1, RD_WR_n=1
@492 1000_0102 // Jump to main loop