nesdev.com
http://forums.nesdev.com/

Weird PPU writes
http://forums.nesdev.com/viewtopic.php?f=2&t=16721
Page 1 of 1

Author:  Fiskbit [ Sat Nov 18, 2017 9:20 pm ]
Post subject:  Weird PPU writes

I came across the following PPU write sequence a while back in The Legend of Zelda:

Code:
  Bank7_E4C4: A9 3F         LDA #$3F
  Bank7_E4C6: 8D 0620       STA PPU_ADDRESS
  Bank7_E4C9: A9 00         LDA #$00
  Bank7_E4CB: 8D 0620       STA PPU_ADDRESS
  Bank7_E4CE: 8D 0620       STA PPU_ADDRESS
  Bank7_E4D1: 8D 0620       STA PPU_ADDRESS


It does this during every vblank after the function that handles PPU writes. It's also done after each series of writes in that PPU write function if the writes started in the $3F page:

Code:
  Bank6_A0DA: C9 3F         CMP #$3F
  Bank6_A0DC: D0 0C         BNE $A0EA
  Bank6_A0DE: 8D 0620       STA PPU_ADDRESS
  Bank6_A0E1: 8E 0620       STX PPU_ADDRESS  ; X == 0
  Bank6_A0E4: 8E 0620       STX PPU_ADDRESS
  Bank6_A0E7: 8E 0620       STX PPU_ADDRESS


I can't find any reason why it needs to be writing to this 4 times, nor have I found any mention of this on nesdev. I wondered if this was unique to Zelda, but found the same pattern in SMB1, SMB3, Ninja Gaiden 3, Battle City, Mega Man 1, and TMNT1, which covers a pretty wide range of companies (Nintendo, Tecmo, Namco, Capcom, Konami) and years (1985-1991). Available disassemblies for SMB1, SMB3, and Mega Man 1 have comments indicating they have no idea what this code is for, so I'm clearly not the only one confused by this.

Can anyone shed some light on this code?

Author:  tepples [ Sat Nov 18, 2017 11:12 pm ]
Post subject:  Re: Weird PPU writes

Any write of $3F $00 $00 $00 to $2006 is cargo-cult programming. The inexperienced coders who worked on NROM and FDS games may have internalized an incorrect model of PPU operation such that palette access ($3F00-$3FFF) and ordinary video memory access ($0000-$3EFF) have separate pointers inside the PPU.

Correct behavior: When the video memory address is $3F00-$3FFF and rendering is off, the backdrop is replaced with the color at the palette index corresponding to bits 4-0 of the video memory address. Changing the video memory address to $0000-$3EFF restores typical behavior of using palette index 0 (as if the VRAM address is $3F00). This write sequence changes the video memory address to $3F00 (uselessly) then $0000.

What they thought: The palette memory address and video memory address are separate. When rendering is off, the backdrop is replaced with the color at the palette memory address. Writes to $2006 starting with $3F set the palette memory address, and writes to $2006 starting with $00-$3E set the video memory address. This write sequence changes the palette memory address to $3F00 and the video memory address to $0000.

Or did very early (square button) Famicom PPUs actually have two separate addresses? Most western reverse engineering has focused on the more common revisions E and G of the NES chipset, not the earliest one that Nintendo recalled. If the palette on square button Famicoms worked differently, this write sequence could be a workaround for the misbehavior, just as Super NES games have to work around the bug in the HDMA controller of S-CPU revision 1.

Author:  Memblers [ Sat Nov 18, 2017 11:30 pm ]
Post subject:  Re: Weird PPU writes

This exact thing is mentioned in a (not publicly available AFAIK) excerpt from a Nintendo doc, dated from 1993. It doesn't say why, it just one sentence saying to do that when you write the palette. Then it shows the sequence from that first code block. I can at least say it doesn't seem to be a problem on 2C02G or 2C03 (Playchoice).

Author:  Bregalad [ Mon Nov 20, 2017 12:05 am ]
Post subject:  Re: Weird PPU writes

Quote:
What they thought: The palette memory address and video memory address are separate. When rendering is off, the backdrop is replaced with the color at the palette memory address. Writes to $2006 starting with $3F set the palette memory address, and writes to $2006 starting with $00-$3E set the video memory address. This write sequence changes the palette memory address to $3F00 and the video memory address to $0000.

Dou you have any evidence they thought that ? Or is it pure speculaiton on your side ?

Author:  tepples [ Mon Nov 20, 2017 6:20 am ]
Post subject:  Re: Weird PPU writes

It's my best guess based on the hardware's behavior.

Author:  za909 [ Mon Nov 20, 2017 9:45 am ]
Post subject:  Re: Weird PPU writes

Misinterpreted documentation would make sense, there are similar cases for the APU, like in Ikari Warriors II, which plays RAW via $4011 but still sets up and starts the DPCM unit like during normal 1-bit delta playback. Or take some Capcom games that write $30 to $400C and then also a $07 to $4015, as if you had to make doubly sure to silence the noise channel.

Author:  Anders_A [ Mon Nov 20, 2017 10:59 am ]
Post subject:  Re: Weird PPU writes

tepples wrote:
Any write of $3F $00 $00 $00 to $2006 is cargo-cult programming.


memblers wrote:
This exact thing is mentioned in a (not publicly available AFAIK) excerpt from a Nintendo doc, dated from 1993. It doesn't say why, it just one sentence saying to do that when you write the palette. Then it shows the sequence from that first code block


I wouldn't call trusting documentation from the creators of the hardware a "cargo cult". I bet most of them didn't really care if it was needed, but just put it there because nintento told them to and then forgot all about it. It's not like it's a costly operation in any way.

Author:  tepples [ Mon Nov 20, 2017 11:19 am ]
Post subject:  Re: Weird PPU writes

To comply with the docs as I understand they are written, a generic video memory update buffer framework would have to check whether each string of writes to video memory is a palette update and write 3F 00 00 00 to $2006 afterward if so. This test costs valuable vblank cycles, as does the cost. For example, in Popslide, it'd add 11 cycles to each packet and 17 cycles to each palette write packet.

Code:
; When writing the address to $2006
  STA packet_dsthi

; Before checking for the end of a packet
  LDA packet_dsthi
  CMP #$3F
  BNE was_not_palette
    STA $2006
    LDA #0
    STA $2006
    STA $2006
    STA $2006
  was_not_palette:


Or does it mean write 3F 00 00 00 at the end if at least one update during this vblank was a palette update, the way a program has to write the scroll at the end anyway? Without access to this document, I couldn't be sure.

It might be useful to count licensed games that do write 3F 00 00 00 vs. games that don't in order to estimate how important this practice was to Lot Check.

Author:  Bregalad [ Mon Nov 20, 2017 12:00 pm ]
Post subject:  Re: Weird PPU writes

While it's false that having $2006 left pointing to the palette causes any problems, it's still true that palettes aren't buffered like other $2007 read/writes are.

The funny thing is that, even if the colour pointed to by the last palette write was to be used as background colour (this is not the case), then in most cases, the whole palette is written, so it'd point to $3f20, a mirror of $3f00. Even if only the BG palette is rewritten, $3f10 is still a mirror of $3f00. Only leaving the pointer at $3f01-$3f0f or $3f11-$3f1f would cause a problem, and those case would be very marginal.

So even if the take hypothesis that the last palette writen to is used as a BG colour was true, this "routine" would still be useless.

If the developers really tought they could use any colour as a background colour, they would eventually try this feature, and figure out that it doesn't work, isn't it ? If they did so and didn't change their code, then yes it's indeed cargo cult. If they just never tried anything else, we can't really call this cargo cult.

Quote:
It might be useful to count licensed games that do write 3F 00 00 00 vs. games that don't in order to estimate how important this practoce was to Lot Check.

I'd be very interested in such a statistic.

Page 1 of 1 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/