BRK/IRQ/NMI

Topics pertaining to the emulation or simulation of the 65xx microprocessors and their peripheral chips.
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

BRK/IRQ/NMI

Post by cpow »

Hi, I'm looking for an answer to the following question. I *think* I know what the answer is but I haven't been able to find it anywhere conclusively.

When the 6502 is in the midst of a 7-cycle sequence for a BRK or IRQ and an NMI occurs, does the NMI 7-cycle sequence start immediately, or does the first 7-cycle sequence complete *then* the NMI 7-cycle sequence commences?

I am fairly sure they're executed one after the other, not on top of each other, as the scenario would lead to unbounded stack growth if it kept happening.

Also, at which cycle in the 7-cycle sequence is the I-flag set? I had assumed it was after (or during) the cycle where the processor status is pushed, because the processor status contains the "old" value of I so that RTI will revert it.

Thanks!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

Welcome.

I'm not sure exactly what you're asking, but any given instruction finishes before the interrupt sequence is started. The interrupt sequence is itself like an instruction. Even if IRQ hit and its interrupt sequence starts and an NMI hits during that sequence, the IRQ's sequence will complete before the NMI sequence starts.

The interrupt sequence does push the status that existed at the end of the last instruction which was just finished before the interrupt sequence started, including the I bit, then sets it, so there's no point in starting an ISR with SEI, and you wouldn't want to end an ISR with CLI. (RTI retrieves the old status.) You could have CLI inside the ISR if it's kind of a longish one and you want quick higher-priority things to be able to interrupt a lower-priority ISR.

You can find my article on interrupts here. Enjoy the outdated cartoons.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

Post by cpow »

GARTHWILSON wrote:
Welcome.
Thanks!
GARTHWILSON wrote:
I'm not sure exactly what you're asking, but any given instruction finishes before the interrupt sequence is started. The interrupt sequence is itself like an instruction. Even if IRQ hit and its interrupt sequence starts and an NMI hits during that sequence, the IRQ's sequence will complete before the NMI sequence starts.
That is what I have been assuming, that the 7-cycle sequence is an "instruction", especially when considering the reset, IRQ, NMI and BRK all use the same sequence as the BRK opcode.

Thus it would logically follow that the 7-cycle sequence is itself "uninterruptable".
GARTHWILSON wrote:
The interrupt sequence does push the status that existed at the end of the last instruction which was just finished before the interrupt sequence started, including the I bit, then sets it, so there's no point in starting an ISR with SEI, and you wouldn't want to end an ISR with CLI. (RTI retrieves the old status.) You could have CLI inside the ISR if it's kind of a longish one and you want quick higher-priority things to be able to interrupt a lower-priority ISR.

You can find my article on interrupts here. Enjoy the outdated cartoons.
Yes I had referenced that article a few times in the past. Nice job!
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

Post by cpow »

Perhaps a different way to phrase the question...

If I'm in the 7-cycle preamble for an IRQ and NMI has asserted before I get to the vector fetch cycles, which vector gets fetched in the *current 7-cycle preamble? IRQ, right? Then as soon as I'm done with the IRQ 7-cycle preamble I start the NMI 7-cycle preamble? Right?

EDIT: Addition...
From the cited webpage above:
"We should mention here that one of the NMOS 6502 bugs is that if an NMI hits during a BRK instruction, the BRK interrupt will not get executed. "

What I'm really trying to do is figure out exactly what this means.

Does "during a BRK instruction" mean all 7-cycles of it? What happens if I'm on the 7th cycle -- I've just fetched and created a PC to go to my BRK handler, so that will be where my NMI handler RTI's to, right?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

cpow wrote:
Perhaps a different way to phrase the question...

If I'm in the 7-cycle preamble for an IRQ and NMI has asserted before I get to the vector fetch cycles, which vector gets fetched in the *current 7-cycle preamble? IRQ, right? Then as soon as I'm done with the IRQ 7-cycle preamble I start the NMI 7-cycle preamble? Right?
Yes. Dr. Jefyll pointed out about 3/4 of the way down this page (on interrupts affecting timings) that they are made to be like instructions, so they will complete before getting altered by the following NMI. You will be interested in the really neat transistor-level 6502 visual simulator at http://visual6502.org/ .
Quote:
EDIT: Addition...
From the cited webpage above:
"We should mention here that one of the NMOS 6502 bugs is that if an NMI hits during a BRK instruction, the BRK interrupt will not get executed. "

What I'm really trying to do is figure out exactly what this means.

Does "during a BRK instruction" mean all 7-cycles of it? What happens if I'm on the 7th cycle -- I've just fetched and created a PC to go to my BRK handler, so that will be where my NMI handler RTI's to, right?
It's a good question if you're using NMOS which I don't recommend if you don't have to. :lol: I don't know the answer. I went to CMOS in 1986 or '87 and have never gone back. I could test it in CMOS since it allows stopping the clock at each cycle, but the CMOS one doesn't have the problem anyway. I have not used the BRK instruction since I was in school in 1982 and using the Aim-65 computer where we used BRK to end our little routines and get back to the monitor. I had thought the BRK instruction had mostly outlived its usefulness for debugging PROMs, but others here have written of its value in multitasking OSs running on 65816's with MMUs in particular. The 65816 is much better suited to multitasking than the 6502 is and has a separate BRK vector also.
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

Post by cpow »

GARTHWILSON wrote:
It's a good question if you're using NMOS which I don't recommend if you don't have to. :lol:
Well, I'm one of a multitude of NES 2A03 emulator authors, and the 2A03 I believe is NMOS, so I'm 'worried' about how properly to emulate the NMOS BRK/NMI bug. :D
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

UPDATE: BRK/IRQ/NMI -- NMI does overlap

Post by cpow »

I simulated an NMI occurring during the 7-cycle IRQ preamble...it does overlap.

http://visual6502.org/JSSim/expert.html ... re=nmi,irq
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

Uh, where did this word "preamble" come from? Does the manufacturer of another processor family use it? The data books from 6502 manufacturers Western Design Center, Rockwell, California Micro Devices, GTE, Synertek, and Commodore all call it "interrupt sequence." After the end of the interrupt sequence, execution picks up in the "interrupt service routine," or "interrupt handler."
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

Post by cpow »

GARTHWILSON wrote:
Uh, where did this word "preamble" come from? Does the manufacturer of another processor family use it? The data books from 6502 manufacturers Western Design Center, Rockwell, California Micro Devices, GTE, Synertek, and Commodore all call it "interrupt sequence." After the end of the interrupt sequence, execution picks up in the "interrupt service routine," or "interrupt handler."
Sorry, my phrasing.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

Hi cpow
That's a really interesting result: you fired an NMI in the middle of the 7-cycle interrupt sequence as it was handling an IRQ, and it fetched the NMI vectors.

Of course this is a slightly unusual situation, because you'd already brought IRQ high again (inactive) whereas IRQ normally remains low until the requesting device services it.

And indeed, if I patch in an RTI with "&a=20&d=40" the machine has no 'recollection' of the IRQ which was usurped - it continues with the main program. (You had a short handler in place too but your main program was long enough to overwrite it...)

If I instead keep IRQ active throughout by removing the '&irq1=22' we still see the IRQ being usurped by the late NMI, but when the RTI completes we start a second interrupt sequence and this time we vector through FFFE as expected. So, your interesting observation still stands, even with a normal use of IRQ. (One might have expected the first instruction of the IRQ handler to be interrupted by the NMI)

BTW, I hope you've seen the photo(*) which shows that the 2A03 contains a literal copy of an nmos 6502 in one corner - a completely different design style from the rest of the chip!

Cheers
Ed

(*)1600px chip photo here - by Christian Sattler, released into the public domain.
cpow
Posts: 7
Joined: 04 Apr 2011
Location: Minneapolis, MN, USA
Contact:

Post by cpow »

BigEd wrote:
Hi cpow
That's a really interesting result: you fired an NMI in the middle of the 7-cycle interrupt sequence as it was handling an IRQ, and it fetched the NMI vectors.
More interesting:

http://visual6502.org/JSSim/expert.html ... re=nmi,irq

This shows an NMI that fires during the fetch cycles of the IRQ sequence being completely ignored. Of course, I seem to remember reading somewhere that NMI must be low for two cycles to be recognized...this would explain why. But it also helped me to understand why the NES test ROM I was trying to emulate doesn't service an NMI right after the IRQ sequence if the NMI fires in the fetch cycles of the IRQ sequence.
BigEd wrote:
Of course this is a slightly unusual situation, because you'd already brought IRQ high again (inactive) whereas IRQ normally remains low until the requesting device services it.
And indeed, if I patch in an RTI with "&a=20&d=40" the machine has no 'recollection' of the IRQ which was usurped - it continues with the main program. (You had a short handler in place too but your main program was long enough to overwrite it...)
In the link above I think I fixed the program as you mentioned...the IRQ has an INX/RTI.
BigEd wrote:
BTW, I hope you've seen the photo(*) which shows that the 2A03 contains a literal copy of an nmos 6502 in one corner - a completely different design style from the rest of the chip!
I have indeed seen that. I'm hoping someday we'll have a Visual2A03. =]
The Visual6502 is such a fascinating useful tool...someday I'm sure we'll have Visual<YourFavoriteChip> where we can all marvel at the skills of our ancestors.
User avatar
Dr Jefyll
Posts: 3525
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Post by Dr Jefyll »

BigEd wrote:
One might have expected the first instruction of the IRQ handler to be interrupted by the NMI
Indeed, that's what I would've expected. But the observed behavior is preferable because the NMI handler is entered sooner. (Sooner, that is, than if an additional interrupt sequence were to to occur as we expected -- ie; a context save and jump via the IRQ vector followed by a context save and jump via the NMI vector). So, the observed behavior is superior in terms of speedy interrupt response. I salute the cleverness of the designers!

Although I'm surprised by this, so far I haven't noticed any contradiction of the "interrupt as an instruction" theory. Comments are welcome; here's a rehash!

The interrupt sequence (instruction) commences with either an NMI, IRQ, RST or the fetching of a BRK opcode, but its exact outcome is determined as the sequence progresses. For example, the value pushed to stack as the BRK bit in the Processor Status Register is read from the interrupt logic during T4, simultaneously as P is pushed.(see note) And now we know (thanks to cpow's experiment, April 8 post) that another decision is deferred: namely, the choice of which interrupt vector to fetch. Evidently that's determined rather late -- but still in time for T5, when the low-order byte of the vector must be fetched either from $FFFA or $FFFE.

I'm becoming more and more impressed with the nuances of the $00 instruction/circumstance -- surely one of the 65xx's most interesting (pseudo-) OpCodes. Nice work, cpow! And thanks, Big Ed, for clarifying. BTW, my hunch is that a RST partway into the sequence would usurp even the NMI, but that may not be the case. If you try it, let me know!

-- Jeff
Note: I'm not suggesting the state of this bit changes during the sequence; merely pointing out (as the schematic shows) that it is sampled later, rather than as the sequence commences.
Big Ed wrote:
Of course this is a slightly unusual situation, because you'd already brought IRQ high again (inactive) whereas IRQ normally remains low until the requesting device services it.
I think it's safe to assume the designers expect IRQ to remain low, as you say. There'd be no effort directed toward properly (?!!) handling a case like the one cpow contrived.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

Interesting indeed: playing around with the timing, we seem to need 3 cycles of NMI to be sure of catching it.

As you may have spotted, we do now have a visual6800, and we hope to have a visual4004 next. The visual2A03 may yet come, but I'm not sure how it stands in priority compared to say the z80 or the rca1802. But, capturing the polygons is the hardest part, so if you can rustle those up, we can do the rest!
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Visual2A03 by Quietust

Post by BigEd »

cpow wrote:
I'm hoping someday we'll have a Visual2A03. =]
As of very recently, "Quietust" has published just such a thing! He's still ironing out some digitisation bugs.

visual2a03thumb.jpg
visual2a03thumb.jpg (22.06 KiB) Viewed 12713 times
kakemoms
Posts: 349
Joined: 02 Mar 2016

Re: BRK/IRQ/NMI

Post by kakemoms »

Sorry about reviving an old tread, but I am trying to get my head around this interrupt. The reason is that I am implementing a MMU than needs to catch interrupt instances so that proper handling can happen.

One thing I am having a problem with is what happens when two interrupt instances happen at once. In the interrupt tutorial, it states that "you might want to re-enable interrupts (using CLI) in the ISR as soon as the most urgent part of one interrupt's servicing is finished". Apparently this is so that another interrupt can be entered before the first one is finished.

I always assumed that one interrupt had to finish with a RTI before the next could be executed. Or am I missing something? And two sequential IRQ interrupts must certainly be executed in series (with RTI between)?

Edit: I put in a sequence of $EA (NOP) in the NMI interrupt example in one of the above posts. At RTI the next (IRQ) interrupt executes, but if I put in a CLI before the RTI, the next interrupt executes two instructions (4 cycles) after the CLI but before a RTI. So it looks like two interrupts can nest and the second one executed inside the first one (e.g. when NMI and IRQ happens at the same time).
Post Reply