I can't answer the question "why doesn't the 6502/65C02 use the PC to do the indirection to execute
JMP (abs)", but I can answer some of the other points.
Visual6502 is the best site to find out about the inner workings of the 6502.
I'll be using the "Random Control Logic" signal names as used in the simulator, which are the same names used in Hanson's block diagram. If you rotate the diagram by 90 degrees, it roughly corresponds to the silicon (actual size used on silicon is different, so take it with a grain of salt). The block diagram is sufficient to understand what is going on, and easier to read than the silicon.
For the ROM decoder, I'll use the simulator names, which are different from the 6507 mnemonics.
You can follow both types of signals by adding a
loglevel of at least 6 to the simulator URL, or by pressing
Trace more often enough in the expert simulator mode. Decoding has "don't care" values, so some of the signals may be accidental.
JMP abs and
JMP (abs) work internally?
(What circuitry is used? Is the implementation cheap?)
In general, instructions are executed through several states (numbered
T6). The 6502 has a kind of two-stage pipeline, where the next instruction is already fetched and decoded while the last stage(s) of the previous instruction still executes. In
T0, the next opcoded is prepared to be fetched, and in
T1, the opcode is decoded, and the next byte after the opcode is prepared to be fetched. This is why every instruction execution ends with
T1, and starts with
T2 if more than two cycles are needed. (I'd assume
T0 is also the phase where the 6502 checks for interrupts, and replaces the opcode with a
BRK if it finds one, but I didn't verify this).
So beginning in the
T2 cycle of
JMP abs, the low byte of the destination address is fetched. It is output on the DB bus (
DL/DB), then stored in the the B input register of the ALU (
DB/ADD), added to a zero (
0ADD) from the A input, and finally temporarily stored in the adder hold register. This is necessary because the
T0 cycle already loads the high byte of the destination address onto the ADH bus, and both must be stored in PCL and PCH at the same time (
JMP (abs), the first cycles are very similar (the only different ROM signal is the absence of
T2‑jmp‑abs), but in
T3, the operand address is only output onto the address bus and not stored in the PC. The low byte of the final destination address that is fetched this way is eventually again stored in the B input register. But before that, the old value of the B input register is incremented by 1 using the carry, and this is used as the address of the high byte of the final destination address. Overflow for that is not handled, which explains the "infamous wrapping effect". The final transfer to the PC works similarly as for
So both jumps use the datapath circuitry just like every other instruction, it's neither particularly cheap nor expensive.
How could one test a
JMP (abs) implementation using the PC?
(Is there anything that would prevent it from working?)
You could modify the decode ROM and decode logic in the simulator. The simulator uses three files to store the silicon data in a simple format, which are available on github. There are already special signals
T4-jmp for the "indirect" phase, and you may need an additional signal (or re-use one of those two) to ensure loading of the PC in the
T2 phase in absence of
T2-jmp-abs. And of course you need to rewire the
You'll likely need some more space for transistors, so a tool to create horizontal or vertical space (increment all coordinates greater than some threshold) in the data files would be helpful.