brk flag useless?

For discussing the 65xx hardware itself or electronics projects.
Gadersd
Posts: 12
Joined: 11 May 2013

brk flag useless?

Post by Gadersd »

I just took a look at every 6502 instruction and noticed non of them used the brk flag, not even the branch and set flag instructions. Does the brk flag do anything at all?
nyef
Posts: 235
Joined: 28 Jul 2013

Re: brk flag useless?

Post by nyef »

Yes. It's used by an interrupt handler to look at the flags saved on the stack and determine if it was called because of a software interrupt (BRK instruction) or a hardware interrupt (IRQ). Note that some (all?) versions of the 6502 can combine IRQ and BRK processing if the timing comes out correctly, so one call to the interrupt handler could be from both a BRK and an IRQ.

So, it's useful, but only in the context of the flags stored on the stack when starting an interrupt handler.

-- Alastair Bridgewater
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: brk flag useless?

Post by BigEd »

Indeed, so it's (often) read by PLA in an interrupt handler. You can't read the 'break flag' because there is no flag in that sense: there's a slot in the saved P state which is stuffed as needed when an interrupt or break happens, but there's no bit to be read in P. If you PHP and PLA you'll always see 1. Even if you push 0 and PLP it'll still be 1. See http://www.visual6502.org/JSSim/expert. ... a&steps=44 for example.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: brk flag useless?

Post by BigDumbDinosaur »

Gadersd wrote:
I just took a look at every 6502 instruction and noticed non of them used the brk flag, not even the branch and set flag instructions. Does the brk flag do anything at all?

As Ed noted, the B bit in the status register (SR) is meaningful only in the copy of SR that is pushed at the time of an IRQ (hardware interrupt request) or software interrupt (BRK). The B bit is important because the 6502 and 65C02 vector both IRQ and BRK through the same address ($FFFE-$FFFF). Therefore, the IRQ/BRK handler has to determine what it is processing, usually via code similar to the following:

Code: Select all

         pha                   ;save accumulator
         txa
         pha                   ;save .X
         tya
         pha                   ;save .Y
         tsx                   ;current stack pointer
         lda $0104,x           ;get stack copy of SR
         and #%00010000        ;mask for B bit
         bne is_brk            ;is a BRK
;
         beq is_irq            ;is an IRQ
The above sequence isn't required with the 65C816 when operating in native mode, as it has separate IRQ and BRK vectors. Also, the 65C02 has instructions to push the X and Y registers to the stack without using the accumulator as an intermediary, a feature that improves performance when the system is flooded with interrupts.

For more information, may I suggest giving Garth Wilson's interrupt primer a good read? He covers most everything needed to start using interrupts in your programs, and includes code examples of common tasks that benefit from interrupt processing. You'll also get a kick out of his vintage cartoons. :lol:

Speaking of interrupt primers, I have been intermittently working on an interrupt article specific to the 65C816 in native mode. It will build on Garth's work and I'm hoping to soon have it posted for everyone's reading "pleasure."
Last edited by BigDumbDinosaur on Tue Sep 03, 2013 6:02 pm, edited 1 time in total.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: brk flag useless?

Post by BigEd »

Might be worth noting how Acorn's OS on the Beeb does this - they use a global to save A which means no need to dip into the stack:

Code: Select all

**      MAIN IRQ Entry point                                            **

;ON ENTRY STACK contains        STATUS REGISTER,PCH,PCL                 ;

DC1C  STA &FC     ;save A
DC1E  PLA         ;get back status (flags)
DC1F  PHA         ;and save again
DC20  AND #&10    ;check if BRK flag set
DC22  BNE &DC27   ;if so goto DC27
DC24  JMP (&0204) ;else JMP (IRQ1V)
See http://mdfs.net/Docs/Comp/BBC/OS1-20/DC1C

Cheers
Ed
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: brk flag useless?

Post by Arlet »

Similarly on the Atom:

Code: Select all

FFB2  85 FF     STA #FF         Save accumulator
FFB4  68        PLA             Get status
FFB5  48        PHA             Re-save status
FFB6  29 10     AND @#10        Is it IRQ or BRK ?
FFB8  D0 06     BNE #FFC0       ..it's BRK - deal with it
FFBA  A5 FF     LDA #FF         Restore accumulator
FFBC  48        PHA             Save accumulator onto stack
FFBD  6C 04 02  JMP (#204)      ..before jumping to IRQVEC
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: brk flag useless?

Post by BigDumbDinosaur »

The only problem with storing .A into RAM is the ISR is not reentrant. Otherwise, it does eliminate most of the stack acrobatics.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: brk flag useless?

Post by BigEd »

Fair point about re-entrancy!
rwiker
Posts: 294
Joined: 03 Mar 2011

Re: brk flag useless?

Post by rwiker »

BigDumbDinosaur wrote:
The only problem with storing .A into RAM is the ISR is not reentrant. Otherwise, it does eliminate most of the stack acrobatics.
I'm not sure that is much of a shortcoming... I'd expect A to be restored and if necessary pushed on the stack before interrupts are re-enabled, and that the BRK instruction would not be used in interrupt handlers.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: brk flag useless?

Post by BigDumbDinosaur »

rwiker wrote:
BigDumbDinosaur wrote:
The only problem with storing .A into RAM is the ISR is not reentrant. Otherwise, it does eliminate most of the stack acrobatics.
I'm not sure that is much of a shortcoming... I'd expect A to be restored and if necessary pushed on the stack before interrupts are re-enabled, and that the BRK instruction would not be used in interrupt handlers.

Huh? We're talking about determining if the ISR is processing a hardware or software interrupt. I didn't say anything about using BRK inside an ISR (that would be somewhat bizarre, although certainly possible). The only way to make the interrupt type distinction in the 65(c)02 is by loading .A with the SR copy that was pushed to the stack and masking for the B bit. Aside from distinguishing between IRQ and BRK, almost any non-trivial IRQ handler will end up using .A for something else (distinguishing interrupt events in a 65C22, for example), which means .A has to be preserved on the stack (not RAM) if reentrancy is desired.

Now, you may well argue that the scenario of nested interrupts won't occur in your system because you won't re-enable IRQs inside your IRQ handler, and therefore reentrancy will be unnecessary. Fine. What do you plan to do if an NMI occurs while the MPU is executing IRQ handler code? That's a nested interrupt, and as NMIs can't be masked and have priority over IRQs, execution of your IRQ handler will be suspended while the NMI is serviced. Unless your NMI handler is reentrant your system will probably go belly-up when the NMI handler exits.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: brk flag useless?

Post by BigEd »

Hi BDD surely it's a valid point that A can be restored from ZP within a few instructions, and so long as that happens before CLI, all is well.
Ed
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: brk flag useless?

Post by Arlet »

BigDumbDinosaur wrote:
Huh? We're talking about determining if the ISR is processing a hardware or software interrupt. I didn't say anything about using BRK inside an ISR (that would be somewhat bizarre, although certainly possible). The only way to make the interrupt type distinction in the 65(c)02 is by loading .A with the SR copy that was pushed to the stack and masking for the B bit. Aside from distinguishing between IRQ and BRK, almost any non-trivial IRQ handler will end up using .A for something else (distinguishing interrupt events in a 65C22, for example), which means .A has to be preserved on the stack (not RAM) if reentrancy is desired.
The Atom code does a quick check for BRK by saving A in ZP. Since IRQ is not enabled, that's perfectly safe. If the BRK code does not need to be reentrant, it's also safe to leave A in the ZP location while handling the BRK. Only when the code has decided it's dealing with an IRQ, and this particular type of IRQ is reentrant, the A is read from the ZP location, and pushed on the stack (like the Atom code does). What rwiker was referring to is the fact that this fails when you do a BRK inside the IRQ while the ZP location still holds A. But if you're careful enough not to do that, all is well.
Quote:
What do you plan to do if an NMI occurs while the MPU is executing IRQ handler code? That's a nested interrupt, and as NMIs can't be masked and have priority over IRQs, execution of your IRQ handler will be suspended while the NMI is serviced. Unless your NMI handler is reentrant your system will probably go belly-up when the NMI handler exits.
The NMI handler doesn't have to check for BRK, so it can just do PHA, and everything will work fine.
nyef
Posts: 235
Joined: 28 Jul 2013

Re: brk flag useless?

Post by nyef »

Arlet wrote:
The NMI handler doesn't have to check for BRK, so it can just do PHA, and everything will work fine.
I think that this is the bug that I'm remembering: A badly-timed coincidence of BRK and NMI can cause the NMI handler to be entered with the BRK flag stored on the stack just as would normally happen with BRK and the IRQ handler. The catch being that the NMI handler is then left "holding the bag", as it were, for dealing with the BRK as well. I'm not sure if this applies to the more recent CMOS chips, just the original NMOS chips, or maybe all chips, but it's the sort of thing that could cause once-in-a-blue-moon missed BRK processing.

Or my memory could be massively faulty right about now and I'm making the whole thing up, or it applies to an entirely separate CPU family or something.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: brk flag useless?

Post by BigEd »

It's a good point: there are some subtleties. There's a writeup at
http://visual6502.org/wiki/index.php?ti ... _and_B_bit
Cheers
Ed
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: brk flag useless?

Post by ElEctric_EyE »

Permit me to express my opinion and thereby also reveal my ignorance on interrupts: I dislike interrupts. I've never used them. They seem to have been made for slow machines.
However the level of detail being paid attention here recently in this discussion is very interesting regarding NMI and IRQ(hardware trigger or software BRK opcode). I've never wrote software to take these things into account, so some of the shared code is appreciated.
A fast enough 6502 doesn't need interrupts does it? It should have sufficient time to poll all flags/inputs within the system.
Post Reply