is RTI used to return from BRK? wrong return address?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

is RTI used to return from BRK? wrong return address?

Post by Petruza »

is RTI used to return from BRK?

Because BRK pushes PC pointing to the 2nd byte of the instruction following the BRK.

And RTI pulls the PC without changing it.

So if RTI is used to return from a BRK call, then the immediately following byte after the BRK instruction would be ignored.

I guess I'm either wrong about what address is pushed by BRK or about RTI returning grom BRK, but which one?
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Yes, RTI can be used to return from a BRK handler, and doing so causes the byte after th BRK opcode to be skipped. I'm sure this is documented in any decent 6502 reference.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: is RTI used to return from BRK? wrong return address?

Post by tepples »

Petruza wrote:So if RTI is used to return from a BRK call, then the immediately following byte after the BRK instruction would be ignored.
Yes, which is why the Apple IIGS monitor disassembles BRK as if it took an 8-bit argument: "BRK $00" through "BRK $FF". You might think that would be useful for a syscall mechanism, but the performance isn't there.
User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

Post by Petruza »

Well yes, the docs and emu sources I read, implied this byte skipping, but none of them explicitly stated that BRK's following byte was skipped and why.
I suspected it was some kind of error or that I wasn't understanding it.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Post by koitsu »

Petruza wrote:Well yes, the docs and emu sources I read, implied this byte skipping, but none of them explicitly stated that BRK's following byte was skipped and why.
It's classified as a signature byte. This is mentioned in some 65C02 and 65816 books -- for example, Programming the 65816 Including the 6502, 65C02, and 65802 by David Eyes and Ron Lichty. I can provide an exact quote from their book if you want.

I don't understand why so many people have trouble understanding BRK and what the operand byte is for; it's probably because so much 6502 documentation states it's a 1-byte instruction and never points the reader to the fact that the PC is incremented by 2 when encountering BRK. It amuses me when I see disassemblers doing things like turning bytes $00 $C7 into "BRK" then "???", rather than "BRK $C7".
User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

Post by Petruza »

koitsu wrote:I don't understand why so many people have trouble understanding BRK and what the operand byte is for
Maybe it's because $00 is the single opcode that causes the 6502 to completely ignore a prefectly good byte of executable code, which doesn't seem logical, and the fact that, at least the documentation I read, says nothing about this, only a "pc + 2" without any explanation in an uncommented pseudocode.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Post by koitsu »

Petruza wrote:
koitsu wrote:I don't understand why so many people have trouble understanding BRK and what the operand byte is for
Maybe it's because $00 is the single opcode that causes the 6502 to completely ignore a prefectly good byte of executable code, which doesn't seem logical, and the fact that, at least the documentation I read, says nothing about this, only a "pc + 2" without any explanation in an uncommented pseudocode.
Then the documentation you've been reading is sub-par (authors didn't bother to take the time to write something that covered such), same with the source code you've been reading (lack of comments for unintuitive things == trouble).

BRK's behaviour, and signature byte (specifically PC+2), is covered in most 65xxx books I own. It's not your fault if what you've read isn't decent quality.
User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

Post by Petruza »

Well, it is my responsibillity to get good documentation, so any help would be appreciated.

So far I'm using http://www.obelisk.demon.co.uk/6502/ , "6502 Microprocessor Revision 1.02 by _Bnu." which I think I got from nesdev, but can't find the link, and the Commodore 64 Programmer's reference guide.

I've finished coding addressing modes and instruction exectuing (big switch for each) but there surely are some errors, I didn't test it yet.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Petruza wrote:Well yes, the docs and emu sources I read, implied this byte skipping, but none of them explicitly stated that BRK's following byte was skipped and why.
Technically, BRK doesn't skip anything. When the CPU executes the BRK opcode, it pushes the address of the opcode+2 on the stack, then pushes the current flags ORed with $30 on the stack, then jumps to the address contained in $FFFE-$FFFF. It's up to the IRQ/BRK handler what to do next, and how to return to the interrupted code.

For good documentation, get a book. I've been reading the 6502/65816 book koitsu just mentioned and it's the best by far of all those I've evaluated recently (I just love that the library still has these!).
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Petruza wrote:$00 is the single opcode that causes the 6502 to completely ignore a prefectly good byte of executable code
It appears you've never worked with the unofficial instructions such as the two-byte NOPs. You'll need a few unofficial instructions to get Puzznic and Lolo 3 to run.
User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

Post by Petruza »

tepples wrote:It appears you've never worked with the unofficial instructions such as the two-byte NOPs. You'll need a few unofficial instructions to get Puzznic and Lolo 3 to run.
Damn, thanks. Do you have a doc about that to point me to?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

@Petruza: This is illegal, you know. Look up "DOP". Though the document is about Atari 8-bit computers, the unofficial instructions are the same on all classic 6502 CPUs, including second-source ones that have the decimal mode circuitry dummied out.
Drag
Posts: 1350
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

Ok, color me uneducated, but why is there an extra byte after BRK? As in, why is BRK a two-byte opcode, where the parameter it takes has no apparent use?

I have no problem accepting the fact that there is an extra, seemingly unused byte after the BRK, but what was the design choice that lead to having BRK skip an extra byte?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

Ok, color me uneducated, but why is there an extra byte after BRK?
.... because the 6502 pushes return adress + 2 on the stack. There is really no other reason. I guess the byte can be used as an "argument" to the BRK opcode, to tell the IRQ handler which type of IRQ you're simluating.
The BRK opcode is completely useless IMO and I never ever used it. I don't see the point to call the IRQ routine in the middle of code.
Useless, lumbering half-wits don't scare us.
Drag
Posts: 1350
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

Bregalad wrote:
Ok, color me uneducated, but why is there an extra byte after BRK?
.... because the 6502 pushes return adress + 2 on the stack. There is really no other reason. I guess the byte can be used as an "argument" to the BRK opcode, to tell the IRQ handler which type of IRQ you're simluating.
The BRK opcode is completely useless IMO and I never ever used it. I don't see the point to call the IRQ routine in the middle of code.
I understand that PC+2 is pushed onto the stack, which causes the skipped byte, but I'm wondering if there was some kind of reasoning behind pushing PC+2 onto the stack, as opposed to PC+1.

Maybe I got confused, but it sounded like there was a use for (or otherwise, a reason to have) the argument that nobody was explaining. :P
Post Reply