File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -59,6 +59,7 @@ class MOS6502
5959 bool running = false ;
6060
6161 std::array<bool , INTERRUPT ::COUNT > signals = {};
62+ std::array<bool , INTERRUPT ::COUNT > pending = {};
6263
6364 WORD PC = { .w = 0x0000 };
6465 WORD AB = { .w = 0x0000 };
@@ -84,10 +85,20 @@ class MOS6502
8485 const int8_t offset = static_cast <int8_t >(Fetch ());
8586
8687 if (test) {
87- Idle ();
8888 const uint16_t target = static_cast <uint16_t >(PC .w + offset);
89- if ((PC .w ^ target) & 0xFF00 ) { Load ((PC .h << 8 ) | (target & 0xFF )); }
89+ if ((PC .w ^ target) & 0xFF00 ) {
90+ Idle ();
91+ PollInterrupts ();
92+ Load ((PC .h << 8 ) | (target & 0xFF ));
93+ } else {
94+ // Branch-taken quirk:
95+ // A non-page-crossing taken branch suppresses the interrupt poll entirely.
96+ // Any pending IRQ/NMI is therefore delayed by one additional instruction.
97+ Idle ();
98+ }
9099 PC .w = target;
100+ } else {
101+ PollInterrupts ();
91102 }
92103 }
93104
@@ -127,9 +138,23 @@ class MOS6502
127138 Push (PC .h );
128139 Push (PC .l );
129140 Push (P.value | 0x20 );
141+
142+ // NMI hijack
143+ if (signals[INTERRUPT ::NMI ]) {
144+ signals[INTERRUPT ::NMI ] = false ;
145+ pending[INTERRUPT ::NMI ] = false ;
146+ vector = 0xFFFA ;
147+ }
148+
149+ P.I = 1 ;
130150 PC .l = Load (vector);
151+ PollInterrupts ();
131152 PC .h = Load (vector + 1 );
132- P.I = 1 ;
153+ }
154+
155+ inline void PollInterrupts () {
156+ if (signals[INTERRUPT ::NMI ]) { pending[INTERRUPT ::NMI ] = true ; }
157+ pending[INTERRUPT ::IRQ ] = !P.I && signals[INTERRUPT ::IRQ ];
133158 }
134159
135160 [[nodiscard]] inline uint8_t Pull () {
You can’t perform that action at this time.
0 commit comments