Weird PPU writes
Moderator: Moderators
Re: Weird PPU writes
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.
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.
Re: Weird PPU writes
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.
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
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.
Re: Weird PPU writes
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.
I suppose that Compile programmer on Twitter just mixed up the order of $3F00 and $0000.
Re: Weird PPU writes
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.
Re: Weird PPU writes
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...
Re: Weird PPU writes
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).
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).
Re: Weird PPU writes
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:
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 ?
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
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.
Re: Weird PPU writes
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
See, for example, this thread: viewtopic.php?t=19068
Re: Weird PPU writes
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.
Re: Weird PPU writes
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?
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?
Re: Weird PPU writes
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.
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.
Re: Weird PPU writes
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.
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.