brk instructions

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
dougeff
Posts: 2875
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

brk instructions

Post by dougeff »

I was just thinking about BRK (00) instructions today. When the 6502 encounters a BRK, it jumps to the address written at fffe-ffff. I always assumed that this would happen by accident (if the blank portion of the rom was filled with 0's).

But, could you do this on purpose? Let's say, as a way to save bytes, since BRK takes fewer bytes than jsr someaddress.

Has any game ever used BRK as a special subroutine?
nesdoug.com -- blog/tutorial on programming for the NES
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: brk instructions

Post by tepples »

If you're using BRK $nn as a syscall, it takes a long time to safely distinguish it from an IRQ. We discussed this possibility before and concluded that it'd be impractical. The only game I'm aware of that had any sort of special handling for BRK was Galaxian, and that might just have been a generic 6502 support library that its programmer used.
User avatar
dougeff
Posts: 2875
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: brk instructions

Post by dougeff »

I mean, the fffe-ffff could point to a code that does something like this...(For example)

Asl a
Asl a
Asl a
Asl a
Rti

Therefore, anytime you need to do that, you just insert BRK, and it will perform this for you, saving 3 bytes each time. (Or some other more frequently used bit of code).
nesdoug.com -- blog/tutorial on programming for the NES
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: brk instructions

Post by lidnariq »

tepples wrote:The only game I'm aware of that had any sort of special handling for BRK was Galaxian, and that might just have been a generic 6502 support library that its programmer used.
The only thing Galaxian does with the B flag is trigger a cold boot.
User avatar
dougeff
Posts: 2875
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: brk instructions

Post by dougeff »

Or, perhaps this would be a more frequently used bit of code the BRK could point to...
WaitForVBlank:
BIT $2002
BPL WaitForVBlank
RTI

That's 5 bytes that can be replaced by 1 (BRK). If used 10 times in a game, that could give you an extra...maybe 35 bytes. And it wouldn't slow down the game since this bit takes a bunch of time anyway, looping around.

(I'm expecting someone to chime in any minute now and explain why this is a terrible idea) ;)
nesdoug.com -- blog/tutorial on programming for the NES
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: brk instructions

Post by tepples »

BRK advances PC by two bytes. Therefore it'd save only one byte over a JSR.
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: brk instructions

Post by thefox »

You could adjust the return address.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: brk instructions

Post by tepples »

Which means you're giving up a buttload of cycles to save a few bytes over JSR.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: brk instructions

Post by rainwarrior »

In my project I used BRK as a crash diagnostic, since I wasn't using IRQ for anything. Comes in handy sometimes.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: brk instructions

Post by AWJ »

Hiryu no Ken Special uses BRK for inter-bank function calls. The two bytes after the BRK are a bank index and a vector index (multiply by 2, add #$8000 and jump to that indirect address). This makes disassembling a bit tricky since not many 6502 disassemblers know how to disassemble BRK as a three-byte instruction.

As far-call methods go, using BRK this way is pretty much the extreme of compactness at the expense of cycle overhead (it also largely precludes using hardware IRQs, but Hiryu no Ken Special is an MMC1 cartridge and doesn't use them) You could squeeze out one more byte per call at the expense of space in your fixed bank by putting the banks and offsets of all functions that are ever called from another bank into a big lookup table. This is what Final Fantasy Legend 3 on the GB does (using RST $18 as the BRK analogue)
isosceles
Posts: 17
Joined: Sat Mar 08, 2014 12:59 pm

Re: brk instructions

Post by isosceles »

Bionic Commando uses the BRK instruction - this happens after destroying the "Main System" at the end of the first level.
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: brk instructions

Post by Dwedit »

According to certain stories, people used to use BRK as a way of patching code on PROMs. Bits could be set to 0, but not set back to 1, so you could replace an instruction with BRK, then add some new code to your BRK handler.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Re: brk instructions

Post by Bisqwit »

BRK can also be recognized in an underhanded way by setting a global variable right before the BRK is issued.

Alternatively if you know exactly your possible sources of IRQs (there aren't that many), you can manage with IRQ and BRK.
Post Reply