My emulator vs. Nintendulator: Gimme a BRK

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
lemmurg
Posts: 25
Joined: Fri May 07, 2021 3:22 pm

My emulator vs. Nintendulator: Gimme a BRK

Post by lemmurg »

Thanks to the help of the awesome debug logger of Nintendulator, my emulator now completes nestest.nes successfully with the same results as Nintendulator.

There is however a difference with the BRK instruction:

Code: Select all

; Nintendulator
C66E  60        RTS                             A:00 X:FF Y:15 P:27 SP:FD PPU:188,233 CYC:26554
0001  FF 00 00 *ISB $0000,X @ 00FF = 46         A:00 X:FF Y:15 P:27 SP:FF PPU:206,233 CYC:26560
0004  00 99     BRK #$99                        A:B9 X:FF Y:15 P:A4 SP:FF PPU:227,233 CYC:26567
C5F4  40        RTI                             A:B9 X:FF Y:15 P:A4 SP:FC PPU:248,233 CYC:26574
0006  00 00     BRK #$00                        A:B9 X:FF Y:15 P:A4 SP:FF PPU:266,233 CYC:26580

; my output
C66E  60        RTS                             A:00 X:FF Y:15 P:27 SP:FD PPU:188,233 CYC:26554    ..-..IZC
0001  FF 00 00  ISB                             A:00 X:FF Y:15 P:27 SP:FF PPU:206,233 CYC:26560    ..-..IZC
0004  00        BRK                             A:B9 X:FF Y:15 P:A4 SP:FF PPU:227,233 CYC:26567    N.-..I..
C5F4  40        RTI                             A:B9 X:FF Y:15 P:B4 SP:FC PPU:248,233 CYC:26574    N.-B.I..
0006  00        BRK                             A:B9 X:FF Y:15 P:B4 SP:FF PPU:266,233 CYC:26580    N.-B.I..
This is the final RTS after running nestest from $C000 and the garbage(?) that runs after that.
Theres two things here I need help with: What is this immediate BRK instruction (BRK #$99 and BRK #$00)? And why is the B flag not set after the BRK? According to my reference, it should always be set.
User avatar
Quietust
Posts: 1919
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: My emulator vs. Nintendulator: Gimme a BRK

Post by Quietust »

lemmurg wrote: Sun May 09, 2021 3:42 am This is the final RTS after running nestest from $C000 and the garbage(?) that runs after that.
When kevtris wrote nestest, he forgot to put an infinite loop at the end of the "automation" mode, so instead it hits an RTS instruction, underflows the stack, then crashes. This is why the reference log for nestest stops immediately before said crash.
lemmurg wrote: Sun May 09, 2021 3:42 am What is this immediate BRK instruction (BRK #$99 and BRK #$00)?
The 6502 treats BRK as a 2-byte instruction - the operand isn't actually used, but when you RTI you'll end up 2 bytes after the instruction rather than just 1. For this reason, many [dis]assemblers treat BRK as using the "immediate" addressing mode.
lemmurg wrote: Sun May 09, 2021 3:42 am And why is the B flag not set after the BRK? According to my reference, it should always be set.
Because the B flag doesn't actually exist within the status register.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
lemmurg
Posts: 25
Joined: Fri May 07, 2021 3:22 pm

Re: My emulator vs. Nintendulator: Gimme a BRK

Post by lemmurg »

Quietust wrote: Sun May 09, 2021 5:36 am The 6502 treats BRK as a 2-byte instruction - the operand isn't actually used, but when you RTI you'll end up 2 bytes after the instruction rather than just 1. For this reason, many [dis]assemblers treat BRK as using the "immediate" addressing mode.
Ah, right. I'm already treating it as a 2-byte instruction in my code but didn't put two and two together here, duh. I'm also not fetching the second byte, I guess I should do that.
Quietust wrote: Sun May 09, 2021 5:36 am Because the B flag doesn't actually exist within the status register.
So if I got this right then BRK and PHP push the bit, but ithe status register doesn't store it. Thus PLP and RTI will not/can not restore it. For 6502 code this would mean only PLA can be used to retrieve it, correct?

Thanks!
User avatar
Quietust
Posts: 1919
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: My emulator vs. Nintendulator: Gimme a BRK

Post by Quietust »

lemmurg wrote: Sun May 09, 2021 8:32 am
Quietust wrote: Sun May 09, 2021 5:36 am Because the B flag doesn't actually exist within the status register.
So if I got this right then BRK and PHP push the bit, but ithe status register doesn't store it. Thus PLP and RTI will not/can not restore it. For 6502 code this would mean only PLA can be used to retrieve it, correct?
That's exactly how it works, yes. You could also read it from the stack using TSX + LDA $01nn,X (with nn set appropriately to fetch the byte you want, depending on how many other bytes you've already pushed).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply