Odd SMB glitch on player injury / pipe entrance

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Odd SMB glitch on player injury / pipe entrance
by on (#239410)
I'm up to the point in my NES emulator where I can play a good majority of games (at least for my humble aspirations), but have been stumped by an odd glitch I'm seeing in SMB. Before I go too crazy digging through logs, I wanted to see if it triggered anyone's memory.

When playing SMB, if the player is "large" Mario and is injured by an enemy and shrinks, or if the player enters a pipe (either in the middle of the level or in the post-flag section) I see the code go off the rails into random instructions until I hit a BRK or otherwise illegal instruction opcodes. The screen also pops back to the scroll position of the status bar at the top, but I believe this is just a consequence of the code going rogue and ignoring the sprite 0 hit.

I'm a little confused why being shrunk and going down a pipe cause the same behavior. My only clue is that the same sound is played for both circumstances.

Given that the ROM doesn't have any sort of bank switching to speak of, and the fact that the code isn't sitting in an endless loop but is in fact walking off into random PRG memory, I'm inclined to think it's something in the CPU, but that's very robust code in my emulator by this point.

Does that ring any bells for anyone who might have run into something similar?

Big thanks for all the great content on this site, it's been invaluable.
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239411)
gobblebit wrote:
I'm inclined to think it's something in the CPU, but that's very robust code in my emulator by this point.


Does your emulator pass all the CPU tests then?
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239412)
CPU emulation bug.
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239431)
zeroone wrote:
gobblebit wrote:
I'm inclined to think it's something in the CPU, but that's very robust code in my emulator by this point.


Does your emulator pass all the CPU tests then?


It does, yes. I've been playing all sorts of games without a hitch for a while, so it seems weird if I found an edge case that only lives in the SMB code at that point, but it's not impossible. The only time I've seen behavior like that is when you mess up the PRG banking, which isn't a factor here.

Guess it's off to log hunting! I'll report back if it's anything interesting.

Thanks
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239433)
Recommend referring to https://wiki.nesdev.com/w/index.php/Tri ... late_games which has details of SMB's nuances.

The one I always remember is that it reads from CHR-ROM (i.e. actual data is stored in CHR-ROM because they ran out of PRG space, thus does PPU reads via $2007) amongst other things. Don't know if that would be causing your issue, but it's one of the more notorious mapper 0 games to try and get working. I still strongly suspect a CPU bug given the manifestation.
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239437)
koitsu wrote:
Recommend referring to https://wiki.nesdev.com/w/index.php/Tri ... late_games which has details of SMB's nuances.

The one I always remember is that it reads from CHR-ROM (i.e. actual data is stored in CHR-ROM because they ran out of PRG space, thus does PPU reads via $2007) amongst other things. Don't know if that would be causing your issue, but it's one of the more notorious mapper 0 games to try and get working. I still strongly suspect a CPU bug given the manifestation.


Thanks, I believe I'm in good shape with all of those. I don't currently emulate open bus reads, but I don't think that's it. I think you're right that it's a CPU problem--just need to figure out what's not showing up in the test ROMs.
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239469)
After some digging through the logs this turned out to be an issue with relative addressing in branch instructions. I would take the signed byte returned by the relative offset and add one to it to account for the opcode's argument. However, if the signed byte was at its extents this would wrap it and cause the code to jump in the wrong direction. Simple error, but kind of amazing how rare this was out of all the games I tested!
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239485)
With SMB often being regarded as a game that pushes the ("stock" NROM) NES to its limits, it's a little amusing to know that somewhere within that, there is a branch at the limit of its boundary.
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239490)
No, it's not a branch at the limit of the boundary. This was just a branch ahead to 127 getting clipped by an emulation error (adding 1 to the 8-bit signed value).

Meanwhile, Sonic 1 on Game Gear does do a relative branch past a Sega Header that is fixed to the end of a bank.
Re: Odd SMB glitch on player injury / pipe entrance
by on (#239525)
Dwedit wrote:
No, it's not a branch at the limit of the boundary. This was just a branch ahead to 127 getting clipped by an emulation error (adding 1 to the 8-bit signed value).

Meanwhile, Sonic 1 on Game Gear does do a relative branch past a Sega Header that is fixed to the end of a bank.


Well, it was a jump at its extreme, which is apparently rare and worth testing out. Turns out TMNT does this in the first few seconds of its gameplay as well so that's now working too.

Thanks all.