Weird PPU writes

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Weird PPU writes

Post by Pokun »

I've always been doing palette updates by rewriting all 32 palette entries from a palette buffer in RAM. I've been thinking of doing it in another way that only writes the palette entries that I want to change, but with this new intel I think I'll just stick with my old method.

I'm not sure I understand the fix though. The first fix he mentions is to set VRAM address to $0000 first and then to $3F00, but according to Fiskbit you first set VRAM address to $3F00 then to $0000, which is in nametable memory. I'm very confused.
Are you supposed to set this last in vblank after all PPU updates like Zelda seemingly does?

The other fix he mentions is also a bit confusing as he just says to write 16 bytes in a row, but palette memory space is 32 bytes large so it makes no sense to not say which 16 bytes he means.


I wonder if the PALETB and PALETS commands in Family BASIC are doing this properly, or else there could be incompatibility problems with BASIC programs and these earlier Famicoms.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Weird PPU writes

Post by Drag »

The fix just seems to be to write "3F 00 00 00" to 2006 (set address to 3F00 (bg color) then to 0000 (pattern 0)) whenever you finish doing a partial palette update. (Following what the actual source code examples show)

If you update all 16 bytes of either the BG or the sprite palette, the PPU address will end on either 3F10 or 3F20 (mirror of 3F00), which I think is the key: 3F00 seems to result in no glitch, and it's possible that 3F10 does result in a glitch but ends up harmless since it's a mirror of 3F00 (but since 3F10/3F14/3F18/3F1C are all invisible, it ends up harmless), but it's also possible 3F10 simply results in no glitch as well.

I don't know if it's important to switch specifically from 3F00 to 0000, or if you can simply switch from 3F00 to whatever else you want.
Last edited by Drag on Mon Jul 04, 2022 6:04 pm, edited 1 time in total.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Weird PPU writes

Post by Pokun »

Oh I see that makes much more sense. $3F10 isn't invisible though, it's a mirror of the backdrop color.

I suppose that Compile programmer on Twitter just mixed up the order of $3F00 and $0000.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Weird PPU writes

Post by Drag »

Pokun wrote: Mon Jul 04, 2022 4:42 pm $3F10 isn't invisible though, it's a mirror of the backdrop color.
Oops, you're right, I got mixed up. :P
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Weird PPU writes

Post by Fiskbit »

Yeah, I'm pretty sure he just misremembered the order. The workaround we see in code is that if v points into palette RAM, it should be moved out of palette RAM by setting it to $3F00 and then $0000. It's hard to speculate on what exactly is going on with this bug, especially since we don't know how to reproduce it or what hardware is vulnerable, but it sounds like $3F00, $3F10, and $3F20 are equivalently safe. Maybe the specific non-palette-RAM address doesn't actually matter, but I don't think we can meaningfully speculate here, especially when we don't know what event actually triggers the corruption (a v transition? Rendering turning on or off with a specific v? Something else?). It may be that the behavior of this bug is fairly complicated, like appears to be the case with the known but poorly understood palette glitch I linked earlier.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Weird PPU writes

Post by tokumaru »

I wonder if using the last mirror of palette RAM ($3FE0-$3FFF) so that the VRAM address lands outside of palette RAM after the last write helps at all. Probably not, since stopping on a multiple of 16 is apparently already safe in any mirror...
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Weird PPU writes

Post by Pokun »

I can at least say that I've played a lot of Xevious (possibly the early version but not entirely sure) on my Famicom which is a 1984 HVC-CPU-07 with a RP2C02E-0 PPU, and I've never seen any bugs where sprites are turning white.

There are a bunch of earlier PPUs than E-0 that we don't know a lot about, maybe some of those has this bug, they are quite rare though and early 1983 Famicoms tends to have all sorts of problems with games from what I can tell (besides they were recalled for that reason).
User avatar
Maxs
Posts: 1
Joined: Fri Jul 08, 2022 10:23 pm
Location: Brussels, Belgium

Re: Weird PPU writes

Post by Maxs »

I found another of these `Weird PPU writes` in mother (Japanese version) followed by a `weirder PPU writes`.

You can find this in the reset handler routine (fixed bank 15),
just after a standard reset (disabling interrupts, rendering and audio) and a double vblank wait:

Code: Select all

  ..            ; clear the palette
FF67  2C 02 20    bit $2002
FF6A  A0 3F       ldy #$3F
FF6C  A2 00       ldx #$00
FF6E  8C 06 20    sty $2006         ; PPU_ADDR = $3F00
FF71  8E 06 20    stx $2006
FF74  A2 20       ldx #$20          ; 32 colors
FF76  A9 0F       lda #$0F          ; black
  ..              clear_loop:
FF78  8D 07 20      sta $2007
FF7B  CA            dex
FF7C  D0 FA         bne clear_loop
  ..
  ..            ; the 'Weird PPU writes'
FF7E  8C 06 20    sty $2006
FF81  8E 06 20    stx $2006         ; PPU_ADDR = $3F00
FF84  8E 06 20    stx $2006
FF87  8E 06 20    stx $2006         ; PPU_ADDR = $0000
  ..
  ..            ; enable rendering
FF8A  A9 1E       lda #$1E
FF8C  8D 01 20    sta $2001
  ..
  ..            ; a 'Weirder PPU writes'
FF8F  2C 02 20    bit $2002
FF92  A9 10       lda #$10
FF94  AA          tax
  ..              weird_loop:
FF95  8D 06 20      sta $2006       ; PPU_ADDR = $1010
FF98  8D 06 20      sta $2006
FF9B  49 00         eor #$00        ; A XOR 0 = A
FF9D  CA            dex
FF9E  D0 F5         bne weird_loop
Any idea of the purpose of this code ?
Why change PPU_ADDR to $1010 16 times in a row ?
What's the purpose of the XOR opperation ?
Last edited by Maxs on Sat Jul 09, 2022 9:05 am, edited 1 time in total.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Weird PPU writes

Post by lidnariq »

Nintendo told people to do that to work around a flaw in the MMC3 - it's manually clocking the MMC3 scanline counter.

See, for example, this thread: viewtopic.php?t=19068
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Weird PPU writes

Post by Fiskbit »

Vectrex28 seems to have encountered this palette issue on an AV Famicom when doing mid-screen palette updates. Writing 3F 00 00 00 to $2006 after the palette write or writing a full palette both fix it. I guess we can call this confirmed at this point and just need to work out the details of what exactly is triggering it.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Weird PPU writes

Post by Fiskbit »

I've put a little bit of time into this and it looks like the issue is related to the value of v when rendering begins. In both places one place where Vectrex28 encountered this, rendering is turned on mid-screen with v pointing into palette RAM ($3F01 and $3F04). [Edit: This results in $3F00 being corrupted with a value from somewhere in indices 1-3, 5-7, and 9-B. Index 1 sounds most plausible. In the other case, I'm not sure yet what's going on and my initial analysis looks wrong.] In Xevious revision 0, v is $3F16 when rendering begins.

It looked to me like N-K's palette issue was related to the value of v when rendering ends, but that warrants more research. The issues feel very similar, but may be different bugs.

At this point, I guess my questions are:
- What specific values of v cause the corruption?
- What is the nature of the corruption? That is, what indices corrupt and where does the new color come from?
- What specific hardware is affected? (Vectrex encountered this on an AV Famicom, suggesting G or H, but I think the issue was discovered before G existed)
- What state does the hardware have to be in to be vulnerable? (Is it a specific CPU/PPU alignment? Xevious seems to hit this at start-of-frame, though, which would suggest alignment with CPU may not matter.)
- What's going on in the chip to produce this behavior?
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Weird PPU writes

Post by Fiskbit »

Some additional thoughts:

The 3rd version of N-K's palette glitch ROM doesn't write to palettes at all in the normal case. Instead, it turns rendering off mid-screen, and when rendering begins again on the next frame, v is $3F10, which is supposedly a 'safe' value. In this ROM, the corruption depends on the value of v when rendering disables, as moving the disable point changes the corruption and v is still always $3F10 at the start of the next frame. This definitely feels different from Vectrex28's new bug.

Given the apparent random nature of these glitches, in that the console boots up into a state that is consistently affected by N-K's test or consistently not affected, I find myself dissatisfied with the idea that Xevious is triggering it at the start of the frame, because this is a time that is not affected by CPU/PPU alignment. Digging in a little deeper, I see that Xevious turns rendering off mid-screen on death. I don't know if it can ever turn it off with a vulnerable value of v (notably, the game is using the left two tables, not the right two, and the bottom right table is the one currently known to have vulnerable v's), but perhaps this is when the palette corruption occurs. Copying all the palette bytes every vblank would correct any corruption before it would be seen, though the 3F 00 00 00 workaround presumably wouldn't help here.
ndiddy
Posts: 33
Joined: Tue Oct 24, 2017 11:07 pm

Re: Weird PPU writes

Post by ndiddy »

Couple things I haven't seen anyone bring up:
1. Nescartdb shows that the Xevious revision was done prior to October 1985, so you can limit investigation of what PPUs were available when the bug was discovered to before then (I think E would have been the latest but unsure).

2. The NES lotcheck spreadsheet has a number of games listed as "Incompatible with the Sharp C1TV", but I'm unsure if that's due to the DMC IRQ bug mentioned in this thread, or other bugs/RGB differences I'm not aware of. For example, the first revision of "Tokyo Pachislot Adventure" is listed as incompatible despite not being on the list of color emphasis games or having expansion audio.
Post Reply