Random glitchy line in Super Mario Bros. on real hardware?

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

Moderator: Moderators

tepples
Posts: 21975
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by tepples » Tue May 21, 2013 6:47 pm

blargg wrote:
tepples wrote:I'm thinking the timing occasionally creates a bus conflict (or some other glitch) when reloading the horizontal scroll bits at x=257. Bus conflicts in NMOS tend to use AND logic, as seen in SAX instruction and discrete logic mappers, which produces a preponderance of zero bits. Games that don't scroll horizontally are already more likely to leave a zero in the horizontal scroll bits.
Can you elaborate? I don't think SMB is rewriting PPU registers mid-frame, or any registers for that matter. Do you mean a conflict in mapper PRG bank switching putting some spikes on the power rails and affecting the PPU?
No, I'm just saying that in NMOS, conflicts tend to cause things to become 0 more often than 1, and you discovered that bank switching is an example of this tendency to become 0. SMB1 doesn't use bank switching at all.
Implication for developers: This could be another reason why games need a timeout on their sprite 0 wait routines. The simplest timeout increases the sprite 0 jitter from 7 cycles (bit/bvc) to 9 (bit/bmi/bvc).
Huh, timeout? You're suggesting that sometimes it doesn't catch sprite hit and this causes the glitch?
No, the other way around. I'm saying the glitch causes it not to catch sprite hit, and games need to be prepared for a failure to catch sprite hit.
BTW, can't you use a bit/beq loop followed by a bmi timed_out to keep 7-cycle latency?
Good point.

Grapeshot
Posts: 85
Joined: Thu Apr 14, 2011 9:27 pm
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by Grapeshot » Wed May 22, 2013 10:22 pm

Question for anyone who understands Visual 2C02: Would writing to $2000 on one specific cycle (possibly only on one PPU/CPU clock alignment) while the bits in the PPU address are updated cause this?

The last thing Super Mario Bros. does in its NMI routine is write to $2000 to turn the NMI back on. If you mark every write to $2000 by changing the tint bits, you can see that this tends to occur about halfway down the screen (approximately where the glitchy line would be). Zelda does something similar when scrolling horizontally.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by blargg » Thu May 23, 2013 12:09 am

Nice, next chance I get I'm going to see if I can continuously trigger this effect. That's got to be it.

User avatar
mikejmoffitt
Posts: 1349
Joined: Sun May 27, 2012 8:43 pm

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by mikejmoffitt » Thu May 23, 2013 8:02 am

I managed to consistently trigger it at a spot in 1-2 towards the end. In about a year I can have a video uploaded, given my current connection speed...

Edit: here it is: http://www.youtube.com/watch?v=P6DAWhLz ... e=youtu.be

tepples
Posts: 21975
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by tepples » Thu May 23, 2013 9:18 am

If Grapeshot's hypothesis turns out true, it reminds me of the bug causing missed frames when spinning on bit 7 of $2002. Then perhaps one way to avoid it is not to write to $2000 except near a scroll split, and instead use some other way to work around NMI-in-NMI. If, as Drag claims, it is less common in later games, that could be three things: later games using SMB3-style horizontal mirroring with horizontal scrolling (and thus a bus conflict on bit 10 of v has no effect), later games doing less processing in the NMI handler as opposed to the SMB1-style "super loop", or just ignoring nested NMIs in software. But if $2000 write conflicts are the cause, sprite 0 spin waits would be less affected.

Statistics would be appreciated for what games turn NMI off and on mid-frame.

User avatar
MottZilla
Posts: 2832
Joined: Wed Dec 06, 2006 8:18 pm

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by MottZilla » Thu May 23, 2013 11:03 am

I believe I noticed this in Zelda 2, perhaps someone wants to check if it's programmed this way as well?

User avatar
thefox
Posts: 3141
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by thefox » Thu May 23, 2013 11:16 am

MottZilla wrote:I believe I noticed this in Zelda 2, perhaps someone wants to check if it's programmed this way as well?
Yes it is.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by blargg » Thu May 23, 2013 1:47 pm

Happens merely writing $01 to $2000 repeatedly in an infinite loop with vertical mirroring. Next to nail down the timing.
ppu 2000 glitch.jpg
EDIT: Seems that a write around pixel 255 is the cause. H/V scroll positions are irrelevant. Only occurs for two of the four CPU-PPU alignments (the two middle ones in the table I posted a while back, one of which is the "preferred" one). Hmmm, and only occurs reliably for preferred alignment (third in table).

Also, only occurs when write is at one particular dot. Not more than one. Clear now why it occurs so rarely in SMB, since you can only even hit this dot on every third scanline.

Maybe someone can probe this with Visual 2C02 now to see what's happening and exactly which dot it occurs on.

Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by Sik » Sat May 25, 2013 7:51 am

tepples wrote:If Grapeshot's hypothesis turns out true, it reminds me of the bug causing missed frames when spinning on bit 7 of $2002. Then perhaps one way to avoid it is not to write to $2000 except near a scroll split, and instead use some other way to work around NMI-in-NMI. If, as Drag claims, it is less common in later games, that could be three things: later games using SMB3-style horizontal mirroring with horizontal scrolling (and thus a bus conflict on bit 10 of v has no effect), later games doing less processing in the NMI handler as opposed to the SMB1-style "super loop", or just ignoring nested NMIs in software. But if $2000 write conflicts are the cause, sprite 0 spin waits would be less affected.

Statistics would be appreciated for what games turn NMI off and on mid-frame.
I would expect most games to use NMI to just set a flag and do the actual processing outside the interrupt. That's the usual way to handle vblank timing on most systems, really (though of course that didn't stop many programmers from doing it in other ways). Note that this means the interrupt itself would be most likely less than half a scanline long, it's just write a single value to RAM and then return =P Of course this would also happen in vblank so it would never be visible.

tepples
Posts: 21975
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by tepples » Sat May 25, 2013 8:34 am

What Sik is referring to is an NMI handler like that used in Concentration Room, Lawn Mower, Thwaite, and Zap Ruder:

Code: Select all

nmi:
  inc nmis
  rti
In before tokumaru points out that doing VRAM updates, the music engine, and the status bar split in the NMI handler makes sure that your music doesn't slow down and your sprite 0 split doesn't have a seizure even if the game slows down.

User avatar
tokumaru
Posts: 11700
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by tokumaru » Sat May 25, 2013 10:23 am

tepples wrote:In before tokumaru points out that doing VRAM updates, the music engine, and the status bar split in the NMI handler makes sure that your music doesn't slow down and your sprite 0 split doesn't have a seizure even if the game slows down.
Oh, you know me too well! I almost clicked the "quote" button as soon as I read the first sentence in Sik's post. But Yeah, this does make a huge difference in NES games IMO. It's as simple as this: if you don't interrupt the game logic for crucial PPU/APU updates that are timed from VBlank, things will screw up if there's any lag. The flag method is perfectly fine if you're absolutely sure the game logic will never take longer than a frame to finish (i.e. the entire game has no lag).

User avatar
Dwedit
Posts: 4306
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by Dwedit » Sat May 25, 2013 11:09 am

From looking at the SMB1 screenshot, it appears as if the X nametable bit for scrolling becomes 0, and no other bit of X scrolling is affected at all.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

User avatar
tokumaru
Posts: 11700
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by tokumaru » Sat May 25, 2013 11:38 am

So... writing to $2000 mid-frame near the end of the scanline messes up the horizontal scroll for the next scanline, is that it?

User avatar
rainwarrior
Posts: 7814
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by rainwarrior » Sat May 25, 2013 11:39 am

I'm with tokumaru w.r.t. what to put in your NMI.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Random glitchy line in Super Mario Bros. on real hardwar

Post by blargg » Sat May 25, 2013 12:03 pm

tokumaru wrote:So... writing to $2000 mid-frame near the end of the scanline messes up the horizontal scroll for the next scanline, is that it?
Yes, if you're not using horizontal mirroring and are writing an odd value (bit 0 set) to $2000.

Post Reply