Where's fault? ROM? Emulator?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Yave Yu
Posts: 66
Joined: Sun Jan 19, 2014 6:15 pm

Where's fault? ROM? Emulator?

Post by Yave Yu »

Run Shinsenden (J) [!].nes in GoodNES on Mesen or BizHawk.
If you try to "search", after two lines sentence it will crash. In Mesen told you an error message then reset, in BizHawk just freeze. So is this emulator's fault, or ROM dump issue?
Image
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Where's fault? ROM? Emulator?

Post by Fiskbit »

That's an interesting question. I'm able to reproduce the crash. Using Mesen's trace logger, things look like they start going off the rails here:

Code: Select all

A3EB  $A5 $18      LDA $18        A:11 X:19 Y:68 P:05 SP:EE CYC:186 SL:25
A3ED  $AE $DB $67  LDX $67DB      A:1A X:19 Y:68 P:05 SP:EE CYC:195 SL:25
A3F0  $DD $FD $A3  CMP $A3FD,X @ $A3FD A:1A X:00 Y:68 P:07 SP:EE CYC:207 SL:25
A3F3  $D0 $C9      BNE $A3BE      A:1A X:00 Y:68 P:07 SP:EE CYC:219 SL:25
A3F5  $60          RTS            A:1A X:00 Y:68 P:07 SP:EE CYC:225 SL:25
87C7  $4C $5E $E8  JMP $E85E        A:1A X:00 Y:68 P:07 SP:F0 CYC:243 SL:25
E85E  $7F $96 $98  RRA* $9896,X @ $9896 A:1A X:00 Y:68 P:07 SP:F0 CYC:252 SL:25
E861  $AD $00 $70  LDA $7000        A:A2 X:00 Y:68 P:84 SP:F0 CYC:273 SL:25
E864  $10 $06      BPL $E86C        A:FF X:00 Y:68 P:84 SP:F0 CYC:285 SL:25
E866  $C9 $FF      CMP #$FF         A:FF X:00 Y:68 P:84 SP:F0 CYC:291 SL:25
E868  $F0 $6C      BEQ $E8D6        A:FF X:00 Y:68 P:07 SP:F0 CYC:297 SL:25
E8D6  $A9 $C3      LDA #$C3         A:FF X:00 Y:68 P:07 SP:F0 CYC:306 SL:25
E8D8  $8D $FA $03  STA $03FA        A:C3 X:00 Y:68 P:85 SP:F0 CYC:312 SL:25
E8DB  $60          RTS              A:C3 X:00 Y:68 P:85 SP:F0 CYC:324 SL:25
C085  $68          PLA                A:C3 X:00 Y:68 P:85 SP:F2 CYC:1   SL:26
C086  $4C $C8 $C0  JMP $C0C8           A:0D X:00 Y:68 P:05 SP:F3 CYC:13  SL:26
C0C8  $85 $46      STA $46             A:0D X:00 Y:68 P:05 SP:F3 CYC:22  SL:26
C0CA  $85 $4D      STA $4D             A:0D X:00 Y:68 P:05 SP:F3 CYC:31  SL:26
C0CC  $A5 $04      LDA $04             A:0D X:00 Y:68 P:05 SP:F3 CYC:40  SL:26
C0CE  $09 $20      ORA #$20            A:80 X:00 Y:68 P:85 SP:F3 CYC:49  SL:26
C0D0  $85 $04      STA $04             A:A0 X:00 Y:68 P:85 SP:F3 CYC:55  SL:26
C0D2  $A5 $4D      LDA $4D             A:A0 X:00 Y:68 P:85 SP:F3 CYC:64  SL:26
C0D4  $8D $FF $FF  STA $FFFF           A:0D X:00 Y:68 P:05 SP:F3 CYC:73  SL:26
C0D7  $4A          LSR A               A:0D X:00 Y:68 P:05 SP:F3 CYC:85  SL:26
C0D8  $8D $FF $FF  STA $FFFF           A:06 X:00 Y:68 P:05 SP:F3 CYC:91  SL:26
C0DB  $4A          LSR A               A:06 X:00 Y:68 P:05 SP:F3 CYC:103 SL:26
C0DC  $8D $FF $FF  STA $FFFF           A:03 X:00 Y:68 P:04 SP:F3 CYC:109 SL:26
C0DF  $4A          LSR A               A:03 X:00 Y:68 P:04 SP:F3 CYC:121 SL:26
C0E0  $8D $FF $FF  STA $FFFF           A:01 X:00 Y:68 P:05 SP:F3 CYC:127 SL:26
C0E3  $4A          LSR A               A:01 X:00 Y:68 P:05 SP:F3 CYC:139 SL:26
C0E4  $8D $FF $FF  STA $FFFF           A:00 X:00 Y:68 P:07 SP:F3 CYC:145 SL:26
C0E7  $A5 $04      LDA $04             A:00 X:00 Y:68 P:07 SP:F3 CYC:157 SL:26
C0E9  $29 $DF      AND #$DF            A:A0 X:00 Y:68 P:85 SP:F3 CYC:166 SL:26
C0EB  $85 $04      STA $04             A:80 X:00 Y:68 P:85 SP:F3 CYC:172 SL:26
C0ED  $60          RTS                 A:80 X:00 Y:68 P:85 SP:F3 CYC:181 SL:26
997F  $53 $53      SRE* ($53),Y @ $0068  A:80 X:00 Y:68 P:85 SP:F5 CYC:199 SL:26
9981  $50 $50      BVC $99D3             A:8F X:00 Y:68 P:84 SP:F5 CYC:223 SL:26
99D3  $3B $3B $3F  RLA* $3F3B,Y @ $3FA3  A:8F X:00 Y:68 P:84 SP:F5 CYC:232 SL:26
99D6  $3F $3F $3F  RLA* $3F3F,X @ $3F3F  A:06 X:00 Y:68 P:05 SP:F5 CYC:253 SL:26
99D9  $3F $3F $3F  RLA* $3F3F,X @ $3F3F  A:04 X:00 Y:68 P:04 SP:F5 CYC:274 SL:26
99DC  $3F $3F $3C  RLA* $3C3F,X @ $3C3F  A:00 X:00 Y:68 P:06 SP:F5 CYC:295 SL:26
99DF  $3B $3B $3B  RLA* $3B3B,Y @ $3BA3  A:00 X:00 Y:68 P:07 SP:F5 CYC:316 SL:26
99E2  $3B $3B $3B  RLA* $3B3B,Y @ $3BA3  A:00 X:00 Y:68 P:07 SP:F5 CYC:337 SL:26
99E5  $3B $3B $3B  RLA* $3B3B,Y @ $3BA3  A:00 X:00 Y:68 P:07 SP:F5 CYC:17  SL:27
99E8  $3B $3B $3B  RLA* $3B3B,Y @ $3BA3  A:00 X:00 Y:68 P:07 SP:F5 CYC:38  SL:27
99EB  $3B $3B $53  RLA* $533B,Y @ $53A3  A:00 X:00 Y:68 P:06 SP:F5 CYC:59  SL:27
99EE  $53 $53      SRE* ($53),Y @ $0068  A:00 X:00 Y:68 P:06 SP:F5 CYC:80  SL:27
99F0  $53 $0A      SRE* ($0A),Y @ $BC46  A:07 X:00 Y:68 P:05 SP:F5 CYC:104 SL:27
99F2  $44 $44      NOP* $44              A:78 X:00 Y:68 P:05 SP:F5 CYC:128 SL:27
99F4  $44 $15      NOP* $15              A:78 X:00 Y:68 P:05 SP:F5 CYC:137 SL:27
99F6  $16 $15      ASL $15,X @ $15       A:78 X:00 Y:68 P:05 SP:F5 CYC:146 SL:27
99F8  $15 $17      ORA $17,X @ $17       A:78 X:00 Y:68 P:07 SP:F5 CYC:164 SL:27
99FA  $12          STP*                  A:78 X:00 Y:68 P:05 SP:F5 CYC:176 SL:27
; We're in the wrong place now! Should be bank $D, but in bank $A, instead.
Near the start, we have this weird RRA abs,X instruction, which is an RMW instruction that is doing 2 consecutive writes to the mapper, which MMC1 will see as 1 write. This will break future sets-of-5 writes because they'll be aligned wrong. And indeed, we try to swap in bank D, but get bank A.

So first, I have to wonder if the game has gone off the rails, and I don't think it has. We got here directly by what looks like a legitimate JMP, and this target is in the fixed bank, so it's not a matter of having the wrong bank loaded. This RRA instruction is the first thing after a JMP that I believe is the end of the previous function, so it's plausible RRA is indeed the start of this function. I see at $E805, though, that these 3 bytes are being used as data, so it looks like the game has a bug where it's jumping to the data between 2 functions instead of the start of the 2nd function, and thus erroneously executing this data as code. Whoops. Indeed, changing $307D8 in the ROM file from $5E to $61 to skip that RRA does indeed fix the crash.

RRA is an illegal instruction. It does ROR and ADC. The ROR is the part we care about here. It writes back the unmodified value first, which is going to depend on the value of X. I'm not sure yet what the limits are on X, but it gets the value of $67DB in the loop that terminates at 0C:A3F0. In my test, X is 0, so it operates on $9896 of the current bank (currently $0C), which is $10. So, it'll first write $10, which doesn't perform a reset and misaligns the shift register. If the value were >= $80, then a reset would be performed and we would be OK.

Since we're shifting, the second write will bring carry into bit 7. Carry at this point will be 1, because the comparison to exit the loop before this will always set carry. We know that MMC1 will ignore the 2nd write in a set of 2, but this leaves me wondering if maybe it doesn't ignore it if the 2nd write performs a reset. This could be tested on a real MMC1 by incrementing a value such as $7F. 2nd-write resets are my best guess right now as to how this could work on real hardware, but not emulator.
NewRisingSun
Posts: 1510
Joined: Thu May 19, 2005 11:30 am

Re: Where's fault? ROM? Emulator?

Post by NewRisingSun »

I can confirm that "神仙伝 (Shinsen-den)" can be made to work without breaking "Bill & Ted's Excellent Video Game Adventure" by only enforcing the consecutive write filter during writes that do not have D7 set. "Bill & Ted's Excellent Video Game Adventure" is the sole known game that relies on that consecutive write filter due to a faulty initialization routine that performs INC on a memory location that contains $FF.

This behavior by "神仙伝 (Shinsen-den)" could be an original game error, or it could be a clever attempt to break bootleg MMC1 implementations, assuming that they work differently in this regard. I suggest performing Fiskbit's test not only on all Nintendo MMC1 revisions, but also on the AX5904 and KS5361 clones.

For what it's worth, the hashes of the ROM file are validated both by NesCartDB and Nintendo's own spreadsheet. So it is definitely not a problem of a bad ROM image file.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Where's fault? ROM? Emulator?

Post by Dwedit »

Wasn't there a decapping of the MMC1 that was done recently?
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Where's fault? ROM? Emulator?

Post by unregistered »

Fiskbit wrote: Tue Mar 01, 2022 10:04 pm Indeed, changing $307D8 in the ROM file from $5E to $61 to skip that RRA does indeed fix the crash.
General note: According to Mesen’s trace log, $307C8 is the correct ROM address to change.

And, to reset the 5-write MMC1 bank-switch counter, at any time, simply write a value with bit7 set to a ROM address. (Learned that the hard way; I’m sure you all know too; just trying to help others.)


EDIT: Fiskbit even talked about a set bit7 resetting :oops: ; but, I guess it’s more clear now…


FINAL-EDIT: struck through my mistake; pointed out by Fiskbit below.
Last edited by unregistered on Tue Mar 08, 2022 3:32 pm, edited 1 time in total.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Where's fault? ROM? Emulator?

Post by Fiskbit »

$307D8 is the address in the ROM file, which includes the 16 byte header. $307C8 is the unheadered or PRG address.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Where's fault? ROM? Emulator?

Post by unregistered »

Fiskbit wrote: Tue Mar 08, 2022 2:39 pm $307D8 is the address in the ROM file, which includes the 16 byte header. $307C8 is the unheadered or PRG address.
Oooh! 😯 Sry Fiskbit, I didn’t consider the header. :oops: Obviously, I’ve never edited another’s ROM.

NOTICE: Please disregard my $307C8 mistake.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Where's fault? ROM? Emulator?

Post by Fiskbit »

On the off chance that the game itself was broken, I picked up a copy of it and have verified it does not crash on real hardware. I've also dumped it to verify it matches the known dump. I think this lends weight to my guess that consecutive-cycle writes aren't ignored for resets, but we still need someone to write and run a test.
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: Where's fault? ROM? Emulator?

Post by aquasnake »

Perhaps the soft reset logic of mmc1 needs to be packaged separately from the blocking of multiple writes of mmc1 mapper chip

It was tested by flashing it to my physical cart. If the write of bit [7] is released, the game will not freeze. Snow Bors was also tested and works fine
Post Reply