Skip to content

Comments

Add interrupt handling with vector constants and documentation#122

Merged
mre merged 1 commit intomasterfrom
add-interrupt-support
Feb 6, 2026
Merged

Add interrupt handling with vector constants and documentation#122
mre merged 1 commit intomasterfrom
add-interrupt-support

Conversation

@mre
Copy link
Owner

@mre mre commented Dec 31, 2025

This is a follow-up to #121 and implements #64.
I tried to follow the instructions from the W65C02S Datasheet, Section 3.4 (IRQB) and 3.6 (NMIB), which I referenced in a few places.

Basically:

  • Add nmi_pending() and irq_pending() to Bus trait
    • NMI: edge-triggered (falling edge detection)
    • IRQ: level-triggered, maskable by I flag
  • Add WaitState enum (Running, WaitingForInterrupt, WaitingForReset) as suggested by the awesome @omarandlorraine
  • Implement service_interrupt() - pushes PC/status, sets I flag, jumps to vector
  • Implement check_interrupts() - detects NMI edge and IRQ level
  • Update single_step() to handle wait states (STP, WAI, Running)

@mre mre requested a review from omarandlorraine December 31, 2025 01:32
@mre
Copy link
Owner Author

mre commented Dec 31, 2025

I ran into Klaus2m5/6502_65C02_functional_tests#23 while testing. Commented out that part. It seems to be an issue with the test code.

@omarandlorraine
Copy link
Collaborator

omarandlorraine commented Dec 31, 2025

Do you know what should happen when both interrupts (or one or two interrupts plus a reset) happen at once? How accurate does this emulator need to be in this area?

@mre
Copy link
Owner Author

mre commented Dec 31, 2025

Yeah, that's the tricky bit. Essentially, that's the test I commented out.

When BRK (software), IRQ, and NMI are triggered simultaneously, the behavior depends on instruction-cycle-level interrupt sampling, which according to the issue isn't even fully documented for real hardware (there's actually a hardware bug on real NMOS 6502 where concurrent BRK+NMI can corrupt the B flag).

For now we skip that specific concurrent BRK+IRQ+NMI test, but the Klaus interrupt test suite validates all other interrupt handling: individual BRK/IRQ/NMI, interrupt nesting, NMI priority, I flag masking for IRQ, edge detection, etc.

@mre mre force-pushed the add-interrupt-support branch from fe04447 to 7dbdede Compare December 31, 2025 11:57
@mre mre changed the base branch from add-cmos-instructions to master December 31, 2025 12:12
@mre mre force-pushed the add-interrupt-support branch 2 times, most recently from e695763 to 2a80766 Compare December 31, 2025 12:24
@mre
Copy link
Owner Author

mre commented Dec 31, 2025

I made a bunch of changes. Should be ready for another round of reviews. 😅

@omarandlorraine
Copy link
Collaborator

Sorry for the delay around Christmas and New Year, I'll get on it hopefully in the coming days!

@mre
Copy link
Owner Author

mre commented Jan 3, 2026

There is no rush at all. ☺️ Happy new year.

Copy link
Collaborator

@omarandlorraine omarandlorraine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job

@mre mre mentioned this pull request Jan 4, 2026
@mre mre force-pushed the add-interrupt-support branch from a1cd8cd to fdd93e1 Compare February 6, 2026 15:30
@mre
Copy link
Owner Author

mre commented Feb 6, 2026

Shouldn't affect PLP since it doesn't write the flags to the databus

removed that note, thanks @omarandlorraine.

Implements hardware interrupt support following the W65C02S datasheet:

Interrupt handling:
- Add nmi_pending() and irq_pending() to Bus trait
- NMI: edge-triggered (falling edge detection)
- IRQ: level-triggered, maskable by I flag
- service_interrupt() pushes PC/status, sets I flag, jumps to vector

Wait states:
- Replace `halted: bool` with WaitState enum (Running,
  WaitingForInterrupt, WaitingForReset)
- WAI instruction waits for interrupt, resumes on IRQ or NMI
- STP instruction waits for reset

Helper methods:
- Add push_address() for pushing 16-bit addresses to stack
- Add set_word() to Bus trait for writing 16-bit values

Testing:
- Integrate Klaus2m5 interrupt test suite
- Add unit tests for IRQ, NMI, and WAI behavior
- Concurrent BRK+IRQ+NMI test disabled (hardware timing edge case)

References:
- W65C02S Datasheet, Section 3.4 (IRQB) and 3.6 (NMIB)
- Klaus2m5/6502_65C02_functional_tests

Closes #64
@mre mre force-pushed the add-interrupt-support branch from 631ff37 to 4135b00 Compare February 6, 2026 16:11
@mre mre merged commit 9ff04c7 into master Feb 6, 2026
7 checks passed
@mre mre deleted the add-interrupt-support branch February 6, 2026 16:16
@mre mre mentioned this pull request Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants