brk flag useless?
brk flag useless?
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?
Re: brk flag useless?
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
So, it's useful, but only in the context of the flags stored on the stack when starting an interrupt handler.
-- Alastair Bridgewater
Re: brk flag useless?
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.
- BigDumbDinosaur
- Posts: 9426
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: brk flag useless?
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
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.
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!
Re: brk flag useless?
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:
See http://mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
Cheers
Ed
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)Cheers
Ed
Re: brk flag useless?
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
- BigDumbDinosaur
- Posts: 9426
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: brk flag useless?
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!
Re: brk flag useless?
Fair point about re-entrancy!
Re: brk flag useless?
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.
- BigDumbDinosaur
- Posts: 9426
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: brk flag useless?
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.
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!
Re: brk flag useless?
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
Ed
Re: brk flag useless?
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.
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.
Re: brk flag useless?
Arlet wrote:
The NMI handler doesn't have to check for BRK, so it can just do PHA, and everything will work fine.
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.
Re: brk flag useless?
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
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?
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.
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.