Recovered visual6502.org wiki - beta release
This page contains some as-yet unpolished extracts from postings by user Hydrophilic on commodore128.org, material used by permission.
This page contains work in progress and unanswered questions, which should be answered by reference to visual6502 simulation URLs.
Contents
The 6502 performs an interrupt as a 7-cycle instruction sequence which starts with an instruction fetch. (Is this true when the interrupted instruction is a branch?) The fetched instruction is substituted by a BRK in the IR.
This simulation shows a lost NMI. NMI is brought low when doing an IRQ acknowledge. Specifically, 1/2 cycle before fetching the IRQ vector (cycle 13 phase 2). NMI remains low for 2.5 cycles. NMI returns high on cycle 16 phase 1.
The NMI is never serviced. This might be due #NMIP being automatically cleared after fetching PC high during any interrupt response…
Instructions such as SEI and CLI affect the status register during the following instruction, due the the 6502 pipelining. Therefore the masking of the interrupt does not take place until the following instruction is already underway. However, RTI restores the status register early, and so the restored I mask bit already is in effect for the next instruction.
Perhaps this is because 'doIRQ' (line 480) is not set during the last vector fetch; that is, during cycle 15 when fetching $FFFF, 'doIRQ' is still false. I don't know why, considering both INTG and 'normal' (line 629) have 'standard' values and there is NMI pending.
After starting to work on INX, 'doIRQ' finally gets set correctly so that 'normal' and INTG get triggered at the end of its execution (cycle 18). And then finally (cycle 19) the NMI is processed
However, in the last cycle of BNE (branch taken, no page cross), although the IRQ has been asserted and ‘do IRQ’ has been set true (cycle 6), the ‘normal’ and INTG lines are not updated. So the CPU continues with the next instruction, also BNE. Again ‘do IRQ’ is examined and the ‘normal’ and INTG are updated, but not during the last cycle of the instruction (as per MOS Tech specs) but actually during the next-to-last cycle (see cycle 13). Note if the branch were not taken, it would be the last cycle of the instruction.
Perhaps the designers considered cycle 2 of any branch instruction to be the ‘natural’ end and check ‘do IRQ’ there… and only there… unless a page boundary is crossed.
Now that I think of it, the fact that INTG is set on the second cycle of any branch instruction (regardless if branch is taken or not), means this line is set 1 cycles earlier than normal if the branch does get taken, and 2 cycles earlier than normal if the branch crosses a page boundary.
(The above commentary, as a pastebomb, should be revisited and tidied up and reconciled with other sources. If we fail to explain, we can remove our explanations and leave only our evidence.)
Retrieved from “http://visual6502.org/wiki/index.php?title=6502_Timing_of_Interrupt_Handling”