I've got a few questions about palettes and such..
1.- Well, you all know.. whenever the internal PPU address (a.k.a. loopy_v) points to the palette address range ($3Fxx) while rendering is disabled its lower byte is used as background color index, but which of its bits are used? I mean, what is the applied mask, 0x1F or 0x0C?
2.- According ot the wiki, indexes 0x10, 0x14, 0x18, and 0x1C are mirrors of 0x00, 0x04, 0x08, and 0x0C, respectively, none of them being really used except 0x00 (background color). Two questions here: a) when rendering, all pixels that use any of these indexes are mapped to background color, right?, and b) what is the point in having such unusable palette slots?
3.- On palette reads (through $2007), what color index is returned if the grayscale flag is set, the original one or the "greyed" one?
Thanks!
M.
2. I've read that 0x04, 0x08, and 0x0C (and their mirrors) can have unique data from 0x00 and its mirrors, but they can only be used by changing the PPU address when rendering is off.
3. I think the original colors would be returned, since I think you are just reading from palette RAM and not the converted colors for monochrome mode. I'm not 100% sure, though.
1) $1F. This has been confirmed by blargg's "full NES palette" demo.
2a) all pixels using those colors are TRANSPARENT because color 0 of any 4-color group is transparent. That is why those colors are never really rendered when the PPU is on. Basic layering is like so:
High priority sprite <--- top
BG
Low priority sprite
color $3F00
Transparent pixels reveal the layer beneath.
You are correct about the way they are mirrored. $00, $04, $08, $0C are all unique, but $10, etc are mirrors
2b) no idea.
3) the greyed one. I forget where, but this was confirmed. I don't think any test ROM checks for it though.
Disch wrote:
1) $1F. This has been confirmed by blargg's "full NES palette" demo.
So $00, etc..(and their mirrors) cannot be used "directly", but can actually be rendered.
Disch wrote:
You are correct about the way they are mirrored. $00, $04, $08, $0C are all unique, but $10, etc are mirrors
Uhm.. but, although $10, etc.. are the mirrors, writing to them will mirror the values back to $00.. Is that right?
Disch wrote:
3) the greyed one. I forget where, but this was confirmed. I don't think any test ROM checks for it though.
How's that? I mean, I thought that was a kind of postprocess, so I expected the stored indexes to be returned..
Muchaserres wrote:
So $00, etc..(and their mirrors) cannot be used "directly", but can actually be rendered.
When the PPU is on, $00 is the only one that can be displayed at all... and it is only displayed when the appropriate BG and sprite pixels are both transparent.
It is impossible for $04, $08, or $0C to be displayed while the PPU is on. Because they corespond to transparent pixels (and transparent pixels are never rendered -- hence making them transparent)
When the PPU is off... any color can be displayed, including $04, $08, $0C.
Quote:
Uhm.. but, although $10, etc.. are the mirrors, writing to them will mirror the values back to $00.. Is that right?
Yes. That's how mirroring works ;P
Addresses $1x and $0x are tied to the same palette entry... so reading/writing to either one affects both.
Quote:
How's that? I mean, I thought that was a kind of postprocess, so I expected the stored indexes to be returned..
I don't know the hardware details. I would guess that there's a mask tied directly to the output of the palette, so that whenever an entry is read, it will be greyscaled when the greyscale bit is set. If that is the case, the PPU wouldn't make any distinction between fetches for rendering, and fetches for $2007 reads -- they're both reads and both function the same way... they just go to different places.
Anyone want to translate these posts into
wiki articles?
Thanks for all your replies.
I didn't want to start another thread for my next question, as it is somewhat related to the actual one. Back to old blargg's vram_access.nes test rom, error code #6 says "6) Palette read should also read VRAM into read buffer". So, as I understand that, reading the palette should immediately return the palette value and should also buffer the corresponding VRAM byte. My question here is, is the VRAM area in question name/attribute tables #3 (that is, its shadow)?
This one may be blatantly obvious, just want to get it clear.
Thx.
Yes
Palette gets returned to CPU.... Name/Attribute data from $3Fxx (or really, $2Fxx) goes into the read buffer.
Disch wrote:
Palette gets returned to CPU.... Name/Attribute data from $3Fxx (or really, $2Fxx) goes into the read buffer.
Sorry to interrupt, but... What are you guys talking about? What do the attribute/name tables have to do with the palette? How does that affect anything?
Code:
LDA $2002
LDA #$3F
STA $2006
LDA #$00
STA $2006 ; PPU address = $3F00
LDA $2007 ; reading ppu$3F00
The above code will return the palette color at $3F00 (it is not buffered like normal $2007 reads). On top of that, it will also fill the read buffer with the nametable data at $3F00 (which is a mirror of $2F00).
Clarified Disch's code a bit by adding a few more $2007 reads:
Code:
LDA $2002
LDA #$3F
STA $2006
LDA #$FE
STA $2006 ; PPU address = $3FFE
LDA $2007 ; A = palette [$1E], PPU addr now = $3FFF
LDA $2007 ; A = palette [$1F], PPU addr now = $0000
LDA $2007 ; A = vram [$3FFF], PPU addr now = $0001
LDA $2007 ; A = vram [$0000], PPU addr now = $0002
etc.
Wow, that's some crazy s**t... at first I wasn't seeing the relevance of it, because the value from VRAM was only going to the buffer, but blargg gave an example of a case where you'll actually get those values that were previously buffered if you keep reading from $2007. Thanks for the info.
Does this apply to writes too? I mean, if PPU address points to palette, will the value be written into VRAM as well?
No it does not apply to writes. That would corrupt nametables every time the game changed the palette (which many games do every frame).
I'm sorry, but I didn't get the two last lines of code, regarding the vram[3fff]. This value of 3fff has any relation with the ppu address or is merely intentional?
Yes, the $3FFF is the data that got moved to the read buffer.
To add on to blargg:
Code:
LDA $2002
LDA #$3F
STA $2006
LDA #$FE
STA $2006 ; PPU address = $3FFE
LDA $2007 ; A = palette [$1E], readbuf = vram[$3FFE], addr = $3FFF
LDA $2007 ; A = palette [$1F], readbuf = vram[$3FFF], addr = $0000
LDA $2007 ; A = readbuf (vram[$3FFF]), readbuf = vram[$0000], addr = $0001
LDA $2007 ; A = readbuf (vram[$0000]), readbuf = vram[$0001], addr = $0002
readbuf is filled with address $3FFF on that 2nd read. Which is why you get it back on the 3rd read.
I hope I'm not missing the point (too much), but does this mean I can use something like this to query the current PPU address?
Lets say the PPU is at the beginnng of a nametable like $2400. Can I determine that by reading $2007 4 times, and using the 3rd and 4th read as the address.
My question is NES programming related rather than emulator related.
Al
no no... you don't get the address back. You get the data *at* that address. The [brackets] there are C notation to indicate that. Reading $2007 gives you the same data that you wrote to $2007. You can't read the address.
OK, that makes sense to me. I thought this might have been some sort of "interesting" side effect.
So is there no way to ask the NES where the PPU address is?
Al
albailey wrote:
So is there no way to ask the NES where the PPU address is?
Not that I'm aware of. Do you need to "save state" from within the emulated NES?
tepples wrote:
albailey wrote:
So is there no way to ask the NES where the PPU address is?
Not that I'm aware of. Do you need to "save state" from within the emulated NES?
No. Sorry, I know this is an emulator related thread, so my question side-tracked things, since its NES game programming related. I used to mess up by updating the background using vblank and either writing too much, or not setting the PPU address back to the address of the nametable (or $0000). I never actually knew which value to set it back to.
Al