The mental model · and where it stops
An opcode does not
drive anything.
The usual picture of a processor is a clock that ticks, an instruction that is read, and a machine that steps forward. It is close enough to write software against and it is not what the silicon does. This page is the difference, one correction at a time. Every number on it is read out of the same measurements the rest of this site is built from, rather than typed into a sentence and left to rot.
Loading the measurements…
Question one
Is there a fixed set of inputs and outputs?
There is, and the die names all of it. Everything the chip can be told and everything it can say goes through these wires; the other … nodes are internal and cannot be observed from outside at all.
| Pin | Direction | What it is |
|---|
Starting the chip…
Two things in that table are worth stopping on.
clk0 is an input. The 6502 has no oscillator. You feed it a square wave, and it hands back the two phases it derived from it (clk1out and clk2out) so the rest of the board can stay in step with the chip rather than the other way round.
The data pins point both ways, and a pin is not a wire. A pad is an output driver: every one of the data pin's terminals goes to a power rail, so nothing enters this chip from a pin through a pass transistor. The way in is the input receiver, which is a gate. A trace that follows only switches can never leave the pad ring, which is exactly what happened the first time one was written here, and is why the wire watch list on the Trace page starts at idl/idb rather than at db.
Correction one
Two edges, not one blip
The chip does work on both clock edges. One phase precharges, the other evaluates, and the state is held in between as charge on a wire. So a cycle is two events, not one, and counting whole cycles throws away half of what happened.
That is why the fundamental unit everywhere on this site is the half-cycle. It is not a simulation convenience; it is the grain the chip actually works at. Bus reads are serviced as the clock falls, writes as it rises.
It also explains a property that surprises people: the 6502 has a minimum clock speed as well as a maximum. Stop it too long and the charge, which is the state, leaks away. There is no static storage holding your registers between phases.
Starting the chip…
See it: Trace lists every half-cycle of an instruction and marks which fields changed on each.
Correction two
The opcode selects switches; it drives nothing
The fetched byte lands in the instruction register, ir0…ir7. Those eight wires are inputs to a PLA: … product terms, combinational, no microcode ROM anywhere on this chip. Each term is a NOR that matches some pattern of IR bits and a timing state.
Fire a term and it asserts control lines. A control line's entire job is to hold open a pass transistor between two wires. So dpc23_SBAC does not mean "load the accumulator". It is a wire that, while it is high, shorts the special bus to the accumulator's storage nodes. The value moves because a switch is open, and for no other reason.
The die names … of the … terms, after the T-state and the instructions they serve. Of … control lines, … have been traced back to the terms that assert them; … have not, and ship as unresolved rather than as guesses.
Starting the chip…
See it: Decode has every product term and the opcodes that fire it. Schematic shows the gate behind any one of them.
Correction three
Nothing counts the cycles
There is no state counter being incremented. There is a timing chain, a shift register of clocked latches, active low, and an instruction ends when a product term resets it. A cycle count is stored nowhere. It is however many cycles went by before something fired.
Which means the counts are free to be wrong, and that is what makes them evidence rather than a tautology. Measured over all … opcodes: … terminate, taking between … and … cycles.
And … never terminate at all …, the JAM opcodes. The chain stops advancing and no further fetch ever happens. Nobody designed that behaviour; it is what the wiring does when no term arrives to reset it. They are recorded as unterminated rather than timed out, because a timeout reported as a cycle count would put a plausible number beside twelve opcodes that do not have one.
Which term ends an instruction is reported as arriving: high in the final cycle and not high in any earlier one. … of the terminating opcodes end on their own op-T0-… term. … have nothing arriving at all. Both numbers are on the page, because two thirds is the honest figure.
Starting the chip…
See it: Timing has every instruction's length and what ended it.
Where the model breaks
There is no state separate from the wires
Register contents mostly do not steer the sequence. The decode sees the opcode and the T-state, plus a handful of condition inputs: a branch being taken, a page being crossed. This is why one product term, op-branch-done, needs a branch that is taken and crosses a page before it will fire at all: it took three separate program runs before it was ever observed.
The deeper correction is this. A register is a set of nodes holding charge. A level is not even a property of a node. It belongs to the group of nodes shorted together at that instant, and the group changes every time a switch opens. Ask what idb0 is, and the honest answer is a list of the other wires it is currently joined to.
The sharpest demonstration is an addition. Trace ADC and at the end of the instruction the accumulator still holds its old value. The sum exists, sitting in the adder's hold register, and arrives in the accumulator during the next instruction's opcode fetch. For most of a cycle the answer is in no register at all.
A behavioural emulator has to hide that, because it has nowhere to put a value that is not in a register. Here it falls out of simulating … switches, and so does every cycle count on this site.
Starting the chip…
See it: Trace, with the wire panel open. The "shorted together right now" list has no equivalent in any software model of a 6502. Or the Lab at ADC step 4, which is the exact half-cycle where the adder holds the answer and the accumulator does not.