Rubbermallet reads the $fffc first, and then $fffd. I'm inclined to think that's what the real deal does too. But the gianlucag emulator seems to read the vector in the opposite order. Do we know what the truth is here? Is there variation in what the real hardware does?
Synertek 6502 datasheet diagrams show a read on $FFFC first and $FFFD last.
MOS datasheets talk about fetching all the vectors in the lower address first, then higher address after.
The MCS6500 Microcomputer Family Programming Manual lists the bus cycles as reading $FFFC on 6th cycle and $FFFD on 7th cycle.
Do we know what the truth is here?
Yes, it's always low first.
While not having a manual page of it's own, the behaviour is well described in Appendix A Summary of Single Cycle Operation of the MCS6500 Family Hardware Manual. Section A.5.4 Break Operation -- (Hardware Interrupt) - BRK (Page A-11) describes the fetch for all vectors step by step:
Being set there makes it a fundamental behaviour of all 6500 hardware compatible CPU. It also explicit mentions that this sequence being the same for BRK and all hardware interrupts (*1).
Is there variation in what the real hardware does?
The addressing is entirely handled by applying constant values to the address bus. This is quite visible - as so often - when looking at Hanson's 6502 diagram:
- ADH(0..7) preset to %1111.1111 (Green)
- 0/ADH0 and 0/AHD(1-7) inactive (dashed Light Green)
- ADL(3..7) preset to %1111.1xxx (Dark Blue)
- ADL(1,2) set to vector, encoded by 0/ADL1 and 0/ADL2 (*2) (Light Blue)
- ADL(0) set according to sequence (Light Blue)
- 0/ADL0 active during the first fetch
- 0/ADL0 inactive during the second fetch
(Taken from a cleaned up version on his site)
This also shows that, other than often assumed, the sequence is not mandated due the PC being used for addressing or it needing to be loaded in that sequence. Either vector byte could have been accessed first and loaded independent from the other:
- Low half from the data bus via IDL and ADL into PCLS (Red)
- High half from the data bus via IDL and ADH into PCHS (Orange)
*1 - Which is BTW where the manuals explicit hints that any interrupt is a forced just BRK ... with different addresses.
*2 - A part that always puzzled me, as that means the hardware could have supported a 4th vector, allowing to separate between INT and BRK by vector, saving the need to look at the BRK flag when an interrupt occurs.