jc-SpaceXp / cNES

NES emulator written in C and targeted for Linux.
zlib License
6 stars 4 forks source link

Cpu interrupt handling (with branch instructions) #9

Open jc-SpaceXp opened 1 year ago

jc-SpaceXp commented 1 year ago

Branch instructions have this unique behaviour in that the T0 state (different from the T0 cycle) doesn't always happen. The T0 state only gets triggered if the branch is taken and a page cross occurs (maximum number of cycles).

This is important as the cpu will poll the edge and level detectors for the NMI and IRQ on this T0 state. Note: The NMI/IRQ are polled on phi2 and set the edge/level detectors if a NMI/IRQ is active on the next phi1 clock.

This implies a NMI/IRQ will never occur if a branch isn't taken or if it doesn't cross a page boundry. To combat this the 6502 will allow the polling of the edge/level detectors on the T2 state (which I believe is the T0/fetch cycle).

Meaning that branch instructions have two state where it polls for interrupts, T2 state and T0 state if the branch is taken and a page boundary is crossed.

jc-SpaceXp commented 1 year ago

Resources for this info above:

(see: Branch Instructions Timing States) https://www.nesdev.org/wiki/Visual6502wiki/6502_Timing_States

First discovered here I believe: http://forum.6502.org/viewtopic.php?f=4&t=1634&sid=9c96da112dbad54e6b828b3b38531cd4

jc-SpaceXp commented 1 year ago

This page also talks about the T states: (see bottom of page)

https://www.nesdev.org/wiki/Visual6502wiki/6502_State_Machine

jc-SpaceXp commented 7 months ago

New branch attempts to fix this issue: https://github.com/jc-SpaceXp/cNES/tree/cpu_interrupts_rework