Thanks Ed.
Knowing that the opcode fetch happens in T1 gives me a new perspective, and I can kind of see how the state machine works with respect to 2 cycle instructions like LDA #imm which have this peculiar T0+T2 state.
In the following sequence:
We end up with the following operations:
Code: Select all
T1 Fetch LDX #
T0+T2 Fetch #1
T1 Store 1 in X Fetch LDA #
T0+T2 Fetch #2
T1 Store 2 in A Fetch ADC #
T0+T2 Fetch #3
T1 Perform A+3 Fetch STA zp
T2 Store 5 in A Fetch 41
T0 Store A in 41
T1 --
I think the key is to realise that the opcode fetch doesn't count as part of that instruction - in T1, the IR still contains the previous opcode and so should be treated as part of the previous instruction. T2 is the start of a new instruction, as already stated in the document on the Visual6502 wiki.
Why do we need the T0+T2 state? My guess is that there are PLA lines which always fire for T0 and T2 to perform standard operations, e.g. poll IRQs for T0, and fetch the following byte for T2, both of which need to be done simultaneously in a 2 cycle op. How does it know that we need to go into this superposition of states? No idea.
In the case of LDA #imm, the only additional operation to be done is in T1, to load the accumulator with the value on the data bus.
The thing I can't figure out now is how, in the case of ADC, it gets its fourth operation decoded (to transfer the ALU result to A). By the time it gets there, the IR already contains the following instruction and is back on T2 again. Any ideas?
Edit to add: Looking at the PLA lines, it looks as if the operations which don't tie up the databus are triggered a cycle earlier than I expected, e.g. the transfer from DB to A in LDA #imm seems to happen in T0 rather than T1. Not sure how this is working if the value isn't actually there yet, but I guess it's relying on some kind of propagation delay or something. But at least that explains how ADC #imm is able to perform its final two steps in T0 and T1.