Palette Mirroring

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Palette Mirroring
by on (#7891)
There is a lot of contradicting documentation about correct palette mirroring. Using one method works for some games but breaks the others and vice versa.

Which of the following are right/wrong?

1. Writes to 0x3F00 are mirrored to 0x3F04, 0x3F08, 0x3F0C, 0x3F10, 0x3F14, 0x3F18, 0x3F1C.

2. Writes to 0x3F10 are mirrored to 0x3F00, 0x3F04, 0x3F08, 0x3F0C, 0x3F14, 0x3F18, 0x3F1C.

3. Writes to 0x3F04, 0x3F08, 0x3F0C, 0x3F14, 0x3F18 and 0x3F1C have no effect.

4. 0x3F04 mirrors 0x3F14, 0x3F08 mirrors 0x3F18 and 0x3F0C mirrors 0x3F1C (and vice versa)

by on (#7892)
There are a total of 28 bytes of palette memory (each byte being 6 bits wide).
Addresses $3F10, $3F14, $3F18, and $3F1C do not contain distinct data; instead, they access the data at $3F00, $3F04, $3F08, and $3F0C.

Of these, only the value at $3F00 is used during rendering (as the background color) - the others are simply unused (but you CAN read them back via $2007).

by on (#7899)
Thanks for the response, but could I also have yes or no answers to my previous post, Cheers!

by on (#7900)
1. No.
2. No.
3. No.
4. Yes. 0x3F00 also mirrors 0x3F10 (and vice-versa).

by on (#7904)
Quote:
Of these, only the value at $3F00 is used during rendering (as the background color) - the others are simply unused (but you CAN read them back via $2007).


Aren't these other three "transparent" colors usable when rendering is turned off, by making use of the "background color uses current VRAM address if it's in palette area" feature? i.e. set $3F04 to some color, then reset the VRAM address to $3F04 and disable rendering, causing the screen to become that color?

by on (#7905)
Yes, that too.

by on (#7919)
That is good to know! I was just wondering today how I would turn off the screen and have it display a color not present in the current palettes. I guess you guys just gave the answer! Thanks!

Now tell me: How can a regular mortal make an accurate emulator when there are all sorts of little tiny details like this?

by on (#7920)
Quote:
I was just wondering today how I would turn off the screen and have it display a color not present in the current palettes.


Except you can't do anything with the VRAM address when using this technique. Probably simpler to just let it use color 0 and reload it once you're ready to turn the screen back on.

by on (#7922)
blargg wrote:
Except you can't do anything with the VRAM address when using this technique. Probably simpler to just let it use color 0 and reload it once you're ready to turn the screen back on.

It can still be useful... I wanted to do this to hide stuff I don't want to be rendered (add a black area at the bottom of the screen, for example), not to get more time to write to VRAM. In this case, it is faster to just point to one of those transparent colors (already set to the color I want) than to change color 0 to whatever I want.

by on (#8340)
So what you're saying is if during rendering the PPU Address is set to either 0x3F04, 0x3F08 or 0x3F0C during rendering that colour is drawn instead of what is at 0x3F00? Is that also true despite whether the background is turned on or not? What happens if the Address is equal to either a sprite palette number (i.e. > 0x3F0F) or a number that is not 0x3F00, 0x3F04, 0x3F08 or 0x3F0C?

by on (#8344)
This "select which palette entry is used for background color" effect only occurs when sprite and BG rendering are off as set by $2001. In this state, the background color is palette entry 0 unless VADDR is within the $3F00-$3FFF range (and I assume $7F00-$7FFF), in which case it's whatever palette entry the VADDR is current selecting. Any entry from the palette can be used as the background color.

As for which palette entry is selected, the low 5 bits of VADDR form an index in the range $00-$1F. Entries $10, $14, $18, and $1C are are treated as if they were $00, $04, $08, and $0C, respectively; the rest map normally. This totals 4*4+3*4=28 entries.

by on (#8346)
blargg wrote:
unless VADDR is within the $3F00-$3FFF range (and I assume $7F00-$7FFF)


Technically, the highest address the PPU can access is $3FFF - after all, there are only 14 address lines coming out of the PPU. There just happens to be a 15th bit in the VRAM address register for the sole purpose of handling fine vertical scroll, and this bit has no effect on palette selection (to my knowledge).