OAM corruption in StarTropics

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderator: Moderators

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

OAM corruption in StarTropics

Post by rainwarrior »

I found an interesting instance of what I believe is OAM corruption due to $2001=0 at the wrong timing in the frame.

This seems to happen on every vertical transition through a dungeon door. When Mike's shadow crosses the blanking region at the top of the status bar (where $2001=0 temporarily to change palettes) you can see some white corruption briefly on the scanlines in that area.

1/6th speed video:
startropics_oam_corruption.mp4
(2.89 MiB) Downloaded 48 times
Now that I'm looking for it, I can see it in other hardware recordings: speedrun example

According to our Errata Wiki article, the window for turning sprites off without corrupting shrinks when there's a sprite crossing the line where $2001 is written.

BTW are there forum threads we could cite in that article as reference for this specific effect? I couldn't find any sources to elaborate/corroborate, and I'm finding it difficult to search the forums for material about this.

.

I discovered this while trying to improve the PowerPak MMC3 mapper. If the timing of the IRQ even slightly delayed, I started to see a lot of OAM corruption issues with this game. Basically some or lots of the sprites would start flickering as a result of the corruption being emphasized.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: OAM corruption in StarTropics

Post by rainwarrior »

I think I've partially mischaracterized what's happening in StarTropics, after noticing that emulators get this partially right.

As Mike's shadow crosses the relevant area, we get a CHR banking at the end of the 2nd last line of the play field, showing 1 sliver of wrong-CHR for the shadow sprite before rendering goes off. Then when it turns back on, we get another wrong sliver of it. The reason we don't see more of the wrong sprite is that the 4 items always have 8 sprites displaying (with empty tiles if there is no item in the slot), which are higher priority. So below that top edge of the item rectangles, the wrong-CHR-sprite is hidden by this, and we only ever see 2 slivers of it.

However... on hardware there is a second wrong sliver that appears on the line where rendering resumes (showing mostly to the right of the hearts, but moves erratically, some frames it shows on the left edge of the screen). You can see this in hardware recordings, but not when emulating.

So... the extra sprite corruption seems unemulated, and can't be explained by the CHR bankswitch.

Also, the timing of $2001=0 writes doesn't seem to be outside the safe window unless delayed... so maybe this isn't that kind of sprite evaluator corruption at all? I'm noticing there is a write to $2000 then $2005-$2005-$2005-$2006 to set scroll just to the right of the hearts where one of the strange artifacts appears... but as far as I can tell the artifact is a sprite and not anything from a nametable (it looks like a second copy of the half-cube sprite that is what the shadow looks like with its wrong-CHR).

So... looking at the timing of events in Mesen, maybe this isn't an instance of corruption due to $2001... (though I was almost certainly seeing that type of problem in sprite flicker when I had a hardware IRQ implementation that was delayed by a cycle or so)... Maybe $2000 writes can also corrupt sprites somehow? Though... maybe $2000's position is a red herring, the actual glitchy sliver on the following line's X position probably wouldn't be determined by the X position of a $2000 write on the previous line. :S

In the other thread I started to discuss the OAM corruption issue more generally lidnariq suggested that there are yet-undescribed issues with turning rendering back on mid-frame.

A visual diagram from Mesen:
startropics_frame_events.png
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: OAM corruption in StarTropics

Post by Drag »

This is the cleanest video I could find on YT which shows the glitch and doesn't have any frustrating deinterlacing artifacts.

Based on your Mesen graph, it looks like rendering is disabled after (or very near to the end of) the part where all of the sprite data is loaded into the hardware for rendering. Therefore, secondary OAM would be 100% valid data, and sprite hardware would be fully and correctly loaded most of the time, and then rendering gets disabled, and this state gets locked-in for now.

Then, when rendering is enabled again, I'm just eyeballing this but it looks like it happens right around when the data for the third or fourth sprite from secondary OAM is copied into rendering hardware. This should mean that the hardware for the first sprite hasn't been touched since it got loaded back before we disabled rendering, and that would explain why the first sprite sliver we see is consistently the next row of (wrong-bank) pattern data for the shadow sprite with the correct attribute and horizontal position.

In addition, secondary OAM was 100% valid when we disabled rendering, and we re-enable rendering after the sprite evaluation portion of the scanline has completely passed, so secondary OAM ought to still contain the same 100% valid data, hypothetically. Based on the scene composition, it should contain exactly the data for the shadow sprite, and 7 dummy "FF FF FF FF" sprites.

We see the expected consistent sliver of the first hardware sprite, but then two extra unexpected sprites appear to the right, with random graphics and random attributes (or at least to my eyes the graphics don't belong to the half-box that the shadow appears as).

One of the sprites hovers over the hearts and appears to have the position X=MikesShadowY, and it seems like it steps through the same sequence of "random" patterns each time too (also based on MikesShadowY?), and the other looks like it's at position X=FF, giving us just a single pixel on the far right.

Sometimes, the shadow sprite sliver jumps over to position X=0 (but still contains the expected graphics/attribute), and when this happens, the unexpected sprites don't appear. I think this is a clue that secondary OAM may remain intact since only the shadow sprite gets affected, and the rest of the hardware sprites are correctly deactivated from being the all-FF dummy data.


Edit: If anyone's wondering how to avoid a scanline of glitchy sprites after you re-enable rendering: Enable only BG first, then enable sprites on the next scanline. That should give you a full scanline of sprite evaluation while not rendering the "stale" data, and then valid sprites afterwards (provided OAM didn't get corrupted)
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: OAM corruption in StarTropics

Post by rainwarrior »

Drag wrote: Fri Nov 04, 2022 9:32 pmThis is the cleanest video I could find on YT which shows the glitch and doesn't have any frustrating deinterlacing artifacts.
Hunh, I guess that has to be an RGB modded NES...? I'm suppose it has to be an original RGB PPU. Good to know it has the same behaviour... also the usual horizontal wobble at the top. (The Analogue NT does not duplicate the glitch, for example.)
...or at least to my eyes the graphics don't belong to the half-box that the shadow appears as...
I thought the opposite. The extra slivers look to me always look likes part of the same dithered-half-cube as the shadow sprite? Seems to have the same palette too.
...the rest of the hardware sprites are correctly deactivated from being the all-FF dummy data.
Is FF dummy data an internal OAM thing? Startropics' offscreen sprites seem to be Y=$F1.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: OAM corruption in StarTropics

Post by Drag »

rainwarrior wrote: Fri Nov 04, 2022 10:24 pm
...or at least to my eyes the graphics don't belong to the half-box that the shadow appears as...
I thought the opposite. The extra slivers look to me always look likes part of the same dithered-half-cube as the shadow sprite? Seems to have the same palette too.
If you look closely at the vid I posted, there's some frames where the "extra" sprite is green, and some where it's gray. Since the palette is changing, that means the attribute byte is changing, so I imagine the sprite is also flipping horizontally and vertically too. It does occasionally show some dithering patterns like the cube sprite, but there's a few frames that show a full 8-pixels of graphics, and the cube sprite only ever has a width of 6, so it must be pulling patterns from other tiles too.
...the rest of the hardware sprites are correctly deactivated from being the all-FF dummy data.
Is FF dummy data an internal OAM thing? Startropics' offscreen sprites seem to be Y=$F1.
Oops, yes, I'm referring to when the internal secondary OAM gets cleared at the beginning of sprite evaluation; all 8 sprites get initialized to all FFs. At the end of evaluation, all of the "unused" hardware sprites wind up with all FFs as their data, except for the first "unused" hardware sprite, which ends up with sprite 63's Y coordinate as a side effect of how evaluation unconditionally copies the "current" sprite's Y coordinate into secondary OAM (if it isn't full).


Another thing I noticed is, from pixel 320 to the end of the scanline, the sprite circuitry is simply reading the first byte of secondary OAM over and over, and that's when the game is disabling rendering. In Startropics' case, this would be the Y coordinate of Mike's shadow. The extra sprite seems to receive this as its X coordinate (notice how it consistently slides to the left with each transition, while Mike is moving upwards), and I suspect it might also be getting this as its tile number and its attribute as well, since it seems to step through the same sequence of patterns and colors each time (with some slight variations sometimes).

I don't know if this is just a coincidence, but this would seem like a pathway for the sprite circuitry to have the Y coordinate of Mike's shadow in its hands in the first place, but then how is it getting used as the X (and probably also Y) coordinate(s), the tile number, and the attribute, all at once for one sprite?
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: OAM corruption in StarTropics

Post by rainwarrior »

Maybe notable that the shadow sprite is always in the 3rd OAM position from the end. It never appears anywhere else.

So, the 4 values are always this (with Y going up and down a little from here), and always starting at $F4 in OAM.

Code: Select all

Y  T  A  X
B8 2F 03 74
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: OAM corruption in StarTropics

Post by Drag »

Ugh, my brain just isn't big enough to operate Visual 2C02 I'm afraid, so someone else will need to dig into this further. :P
Post Reply