Re: [stella] BRK instruction: Request for clarification!

Subject: Re: [stella] BRK instruction: Request for clarification!
From: "B. Watson" <atari@xxxxxxxxxxxxxx>
Date: Mon, 25 Jul 2005 17:57:13 -0400
> 1) When a BRK instruction is executed, is the existing
> status register altered?

Yes: the B flag is set.

Here's one way of describing what happens (taken from the Stella emu
source):

case 0x00: 
{
   peek(PC++);

   B = true;

   poke(0x0100 + SP--, PC >> 8);
   poke(0x0100 + SP--, PC & 0x00ff);
   poke(0x0100 + SP--, PS());

   I = true;

   PC = peek(0xfffe);
   PC |= ((uInt16)peek(0xffff) << 8);
} 
break;


> 2) Where and how should the BRK flag be cleared? Or is this
> done automatically?

In your interrupt handler. As you said, you have to clear it by masking
the bit manually.

> 3) What happens to the IRQ flag during execution of the BRK?
> is it ever changed? (It should normally be inactive when a
> BRK occurs, but since it is ignored by BRK it could be in
> any state.)

According to the Stella code above (and according to "cpu.asm" in the
z26 source), the I flag gets set *after* the PC and status are pushed,
so an RTI restores its original state. I didn't know/remember that until
I looked at the code just now (it's been a long time since I used a 6502
system that actually has interrupts: on the 2600, I just SEI at startup
and ignore the I flag thereafter).

I doubt both Stella and z26 are wrong though, not when they're doing
exactly the same thing.

I *think* the idea behind this behaviour of the B and I flags is that
the same interrupt handler can handle both hardware and software (BRK)
interrupts, and can tell the difference between the two by inspecting
the B flag.

The 6502's I flag is actually the Interrupt *disable*: While set,
it prevents further IRQs from being received. As you mention, the BRK
flag ignores the state of the I flag, but it does set it, for the same
reason: to prevent an external IRQ from interrupting the interrupt handler
(the one triggered by the BRK). On a 6507 (with no external IRQ line),
you really can just ignore the I flag (or use it as an extra bit of
storage that takes a long time to access :)

I'm not sure why the B flag gets set *before* pushing the processor
status: it seems like it'd be better to do it afterward, so the
interrupt service routine wouldn't have to change the saved value on
the stack. Perhaps it was due to a hardware limitation? Perhaps someone
who's actually a hardware person can jump in? I'd just make a fool of
myself guessing :)

Hmm, 6502.org has a tutorial that looks like it might do a better job
than me of explaining things:

http://www.6502.org/tutorials/interrupts.html

The BRK is mentioned in section 2.2. Anywhere the tutorial contradicts
what I just wrote, the tutorial is probably right: Mine is from memory,
and I'm known to remember things wrong...

--
B.
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://stella.biglist.com

Current Thread