6502 Timing States
6502 Timing States.
There are two things that are critical for correct instruction execution in the 6502 (indeed, for any CPU chip): the pattern of bits in the instruction register AND the pattern of "time code" bits from the timing control block of circuits.
Both sets of bits (IR and time code), in combination, control the output bits of the PLA block of circuits. PLA outputs, in turn, affect the RCL block of circuits, and their control outputs directly operate the connections among the registers, busses, and ALU on the other end of the chip die to actually get the instructions' work done.
The 6502's timing control has ten states (effectively) and six explicit output bits. Only the explicit output bits affect the PLA. The output bits are labelled T0, T+, T2, T3, T4, and T5. The bits are considered active when their logic states are low. There are two states where two of these explicit output bits are active at the same time. There are also two states where none of the explicit output bits are active. All other states have only one output bit active at a time.
The two states with two bits active together are T0 with T+, and T0 with T2. The two states with all explicit bits inactive are referred to as T1 and T6. Those two states can only be distinguished within the timing control block of circuits by paying attention to a logic node that is responsible for clearing (making inactive) the explicit output bits T2 through T5. The clearing node at logic high (active) corresponds to the T1 state, and low corresponds to the T6 state. For the visual6502, this is node 1357.
A notation developed for trace/debug output, and the notation presented hereafter in this document, lists the explicit output bits in numeric order followed by square brackets around the non-explicit internal state of T1 or T6. When one or more of the explicit bits is active, the square bracketed label will be blank.
Wherever one of the explicit bits is inactive, a blank placeholder of ".." is present for it. This also applies to the bracketed label.
For example, the T0 state is presented as:
T0 .. .. .. .. .. [..]
...and the T1 state is presented as:
.. .. .. .. .. .. [T1]
The low-profile "blank" notation of ".." is intended to assist visual examination of trace/debug output by keeping consistent placeholders for bits when they are inactive, and to minimize vertical visual clutter. Aligning everything in fixed positions contributes to easy recognition of changes in logged output.
Time codes seen around instruction execution
All instructions, with a few exceptions, always end with T0 in their time code for the last cycle. The presence of T0 indicates, "last cycle".
The strictly 2-cycle instructions always end with the time code:
T0 .. T2 .. .. .. [..]
All other instructions end with the time code:
T0 .. .. .. .. .. [..]
The mentioned exceptions to last-cycle T0 time codes are the conditional branch instructions. When they do not take the branch, their last cycle time code is:
.. .. T2 .. .. .. [..]
When they do take the branch, and the branch does not cross a memory page, their last cycle time code is:
.. .. .. T3 .. .. [..]
When the branch instructions take the branch, and the branch crosses a memory page, they end with a T0 last cycle just like all the other instructions do.
Instructions that vary in the number of cycles required to execute, other than the conditional branch instructions, end with a T0 cycle for both the minimum and maximum execution duration. This covers instructions that use indexed addressing modes that require one more cycle when page crossing is required to access the correct memory address. This situation is already covered by statements above ("All instructions ... always end with T0..."): it has been specifically (re)stated here for such instructions for reassurance emphasis.
For all instructions, if the previous instruction's last cycle was a cycle with T0 in it, its opcode fetch cycle will be a time code of:
.. T+ .. .. .. .. [..]
If the previous instruction's last cycle did not have T0, its opcode fetch cycle will be a time code of:
.. .. .. .. .. .. [T1]
Restated, instructions begin with T1 instead of T+ after a conditional branch instruction that did not branch, or that branched without page crossing.
Instructions appear to work equally well either way. This is because a new instruction's first actions do not begin during opcode fetch. Their earliest effect can be only in the first half of the next cycle, T2, when the IR is set from the predecode register.
This implies that an instruction's actions may extend as far as the second half of the opcode fetch of the next instruction, in concert with the T+ time code bit. Not all instructions may necessarily use this: it could be an unused constraint for some instructions.
Branch instructions definitely don't use T+ or T0 (since two cases out of three don't even cause those time codes to arise).
In sequence, all of the possible time codes during normal instruction execution are:
.. T+ .. .. .. .. [..] OR .. .. .. .. .. .. [T1] .. .. T2 .. .. .. [..] OR T0 .. T2 .. .. .. [..] .. .. .. T3 .. .. [..] .. .. .. .. T4 .. [..] .. .. .. .. .. T5 [..] .. .. .. .. .. .. [T6] T0 .. .. .. .. .. [..]
The time code:
T0 T+ .. .. .. .. [..]
arises when RES is down when a T0 phase 1 clock state is clocked in. This can be either the T0 that is usually scheduled for an instruction's last cycle, or the T0 caused by instruction abort (one of the important actions of RES is to force the clock to T0, which aborts whatever instruction is currently executing). Holding down RES long enough causes the T0 T+ state to arise.
Demonstration of all time code states
This link runs the expert version of visual6502 with a minimal 6502 program, including a RES interrupt, that causes the appearance of all the time code states documented above.
The human readable coding of the program:
02F8 CLC ; Show T0 T2 (a 2-cycle instruction) 02F9 BCS 02FB ; Show T1 for next instr. fetch, after this one's T2 (no branch) 02FB BCC 02FD ; Show T1 for next instr. fetch, after this one's T3 (branch, no page cross) 02FD BCC 0300 ; Show branch with page cross 02FF FF ; FF padding 0300 INC 0000,X ; Show all T states, including T6 Phase 33, RES0 ; RES down during T6 phase 2 Phase 34, RES1 ; RES up during T0 phase 1 ; Creates T0 T+ in cycle before next instr. fetch 0303 INC 0000,X ; Interrupted by RES ; RES starts the above code again
The twelve unsupported opcodes that run forever proceed to T6 and never leave.
- See also 6502 State Machine .