So, what I understood ( and tell me if I am wrong )
the read/write signal to 2007 determines if I will write to VRAM or not
if read from 2007 then the PPU will read the VRAM of address in 2006
if write to 2007 then the PPU will take the data in 2007 and write to VRAM of address in 2006
but , what about the timing of all this ?
PPU pinout
Moderator: Moderators
Re: PPU pinout
That's correct. I don't know much about the timing, just that there's a delay when reading, because there's not enough time for the PPU to fetch a byte from VRAM and return it to the CPU during the load instruction that triggered the read. For this reason, the byte fetched from VRAM is buffeted, and the CPU will get it on the NEXT read from $2007.
-
Muhammad_R4
- Posts: 66
- Joined: Sat Jun 25, 2016 5:33 am
Re: PPU pinout
Sorry I didn't get it , explain more please.tokumaru wrote:That's correct. I don't know much about the timing, just that there's a delay when reading, because there's not enough time for the PPU to fetch a byte from VRAM and return it to the CPU during the load instruction that triggered the read. For this reason, the byte fetched from VRAM is buffeted, and the CPU will get it on the NEXT read from $2007.
Re: PPU pinout
What was the first word in tokumaru's post that you failed to understand? If you don't tell us what part you misunderstood, it will be much more difficult for us to help you understand. ("Much detail" was the catchphrase: 1 2 3)
Getting this right is essential to making the title screen of Super Mario Bros. work.
The following is an example of writing a string to VRAM and reading it back:
Of the preceding code, which was the first line that you misunderstood?
Getting this right is essential to making the title screen of Super Mario Bros. work.
The following is an example of writing a string to VRAM and reading it back:
Code: Select all
PPUCTRL = $2000
VBLANK_NMI = $80
VRAM_DOWN = $04
PPUSTATUS = $2002
PPUADDR = $2006
PPUDATA = $2007
; Set write increment
lda #VBLANK_NMI
sta PPUCTRL ; set address increment to +1 (not +32)
bit PPUSTATUS ; set first/second write latch to first
; Video memory address $2222 means (2, 17) on the first nametable
lda #$22
sta PPUADDR ; set high byte of address: rows 16-23 of nametable 0
sta PPUADDR ; set low byte of address: 1 row down, column 2
; Write "HELLO". (In production code, you'd probably use a loop.)
lda #'H'
sta PPUDATA ; $2222 = 'H'
lda #'E'
sta PPUDATA ; $2223 = 'E'
lda #'L'
sta PPUDATA ; $2224 = 'L'
sta PPUDATA ; $2225 = 'L'
lda #'O'
sta PPUDATA ; $2226 = 'O'
; Point the video memory address at the start of the message again
lda #$22
sta PPUADDR
sta PPUADDR
; Reading PPUDATA returns the value in a latch holding the most
; recently read byte and then reads another byte into that latch.
; This means you have to read one byte and discard its value
; before making use of the rest of the bytes that you read.
lda PPUDATA ; A = unspecified
; PPU reads 'H' from $2222
lda PPUDATA ; A = 'H'
; PPU reads 'E' from $2223
lda PPUDATA ; A = 'E'
; PPU reads 'L' from $2224
lda PPUDATA ; A = 'L'
; PPU reads 'L' from $2225
lda PPUDATA ; A = 'L'
; PPU reads 'O' from $2226
lda PPUDATA ; A = 'O'
; PPU reads from $2227
-
Muhammad_R4
- Posts: 66
- Joined: Sat Jun 25, 2016 5:33 am
Re: PPU pinout
So , as I understood from the code , when I request a read from VRAM , what I really get on the data bus is the previous read
as I understood , what I get in read#2 is the result from read#1 and in read#3 is the read#2
so generally, the read to 2007 transfers the content of the buffer to the output data bus and the the VRAM of address 2006 to this buffer.
first , am I true ?
then , is writing to VRAM works the same ?
Code: Select all
read #1
read #2
read #3
so generally, the read to 2007 transfers the content of the buffer to the output data bus and the the VRAM of address 2006 to this buffer.
first , am I true ?
then , is writing to VRAM works the same ?
Re: PPU pinout
You understand the video memory read buffer correctly.
Palette memory ($3F00-$3FFF) does not use the read buffer because it is inside the PPU. Instead of returning the value in the read buffer, the PPU directly returns the value in that palette location, though it still reads the VRAM address "behind" that palette entry into the read buffer. So you can read video memory $3F13 (not the palette) like this:
Most games won't need this because the PPU never uses video memory $3000-$3FFF during rendering. The vast majority of cartridge boards just make it a mirror of $2000-$2FFF.
From the CPU's point of view, writing goes straight to memory. First the value goes to a write buffer, and then the PPU completes the write to video memory within four cycles, before the CPU gets a chance to make another write to any other PPU register. I'm guessing (but don't quote me on this because I haven't tested it on my own NES) that the write buffer and the read buffer use the same 8-bit latch. If this is true, it means that the first read after you've written something will be the value you just wrote.
Palette memory ($3F00-$3FFF) does not use the read buffer because it is inside the PPU. Instead of returning the value in the read buffer, the PPU directly returns the value in that palette location, though it still reads the VRAM address "behind" that palette entry into the read buffer. So you can read video memory $3F13 (not the palette) like this:
Code: Select all
lda $3F
sta PPUADDR
lda $13
sta PPUADDR
lda PPUDATA ; Returns the value in palette[$13] then reads $3F13 into buffer
lda #$00
sta PPUADDR
sta PPUADDR
lda PPUDATA ; Returns the buffer then reads $0000
From the CPU's point of view, writing goes straight to memory. First the value goes to a write buffer, and then the PPU completes the write to video memory within four cycles, before the CPU gets a chance to make another write to any other PPU register. I'm guessing (but don't quote me on this because I haven't tested it on my own NES) that the write buffer and the read buffer use the same 8-bit latch. If this is true, it means that the first read after you've written something will be the value you just wrote.
Re: PPU pinout
It's been established (and confirmed from Visual 2C02) that they are not the same buffer - reading $2007 returns the contents of a dedicated buffer (which is physically located just to the right of the sprite render units), while writing $2007 simply puts the value on the internal data bus and relies on capacitance (i.e. open bus) to maintain it until the VRAM write actually goes through.tepples wrote:I'm guessing (but don't quote me on this because I haven't tested it on my own NES) that the write buffer and the read buffer use the same 8-bit latch. If this is true, it means that the first read after you've written something will be the value you just wrote.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.