Is PPU_DATA read slow?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

UsernameInUse
Posts: 2
Joined: Fri Dec 11, 2020 5:09 am

Is PPU_DATA read slow?

Post by UsernameInUse »

Hi!

I work on a platformer and I'm making collision check right now.
My question: is PPU_DATA ($2007) read as slow as write and can I use it for collision detection?
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Is PPU_DATA read slow?

Post by DRW »

My advice: You shouldn't use any of the PPU registers for anything that has to do with game logic.

Not only can most of the registers not be accessed outside of vblank, but this way, you're mixing graphics output with game logic.
If you want to check a character against a background, you should have an abstract data structure made up of regular variables that holds the state of the screen. It's not good practice to check game logic against the actual tile values of the graphics, no matter how fast or slow the access is. Because as soon as you want to have an invisible wall or as soon as you use the same tiles for a background and for a wall object, this attempt goes down the drain.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Is PPU_DATA read slow?

Post by tokumaru »

Everything DRW said. You don't want to deal with the limited access times of VRAM, and you don't want to decide the behavior of your tiles based on their graphics. Most games will either include the solidity information as an attribute of the metatiles (blocks used to construct the levels) themselves, or have a separate map with just the solidity data.
User avatar
Dwedit
Posts: 4921
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Is PPU_DATA read slow?

Post by Dwedit »

Reading from the PPU can only be during VBLANK time, or during Forced Blanking (sprites and background disabled).
Furthermore, using the DMC sound channel will corrupt your PPU reads, just like it does with joystick input.

Because reading from the PPU is so restrictive, it's generally only used for storing blocks of data in CHR-ROM. For example, SMB1's title screen, Dragon Quest 1's game script text, MC Kids's compressed levels, and Family Feud's nametable layouts and puzzle answers.

So don't read from the PPU unless you are storing data in CHR-ROM. You need to stop any DMC samples from playing during that time.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Is PPU_DATA read slow?

Post by rainwarrior »

An answer to the literal question: individual PPU reads/writes are the same speed as any other read/write on this CPU. It's probably worth saying so, just because there are lots of platforms (modern and old) where video memory access is slower.

As others have pointed out, you have a bandwidth problem due to the window of timing you have for access.

Other nitty details:

Serial access to the PPU data is actually more efficient than CPU, due to its auto-increment behaviour. On the CPU you have to increment an index between bytes to do the same. (Workaround: you can store a small amount of data on the stack area and auto-increment with PLA.)

Random access to the PPU data is grossly inefficient, since you have to write 2 extra bytes to $2006 to set the address. If reading, you also need to discard one byte read before you start getting valid results.
puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 7:25 am

Re: Is PPU_DATA read slow?

Post by puppydrum64 »

I'm guessing you're trying to use the tilemap data as a way to check collision in order to save ROM space? I think maybe one thing you could do instead, is have each different tile attribute also represent different collision data. This would limit which palettes you can use but it would save quite a bit of space.

EDIT: I don't think this works the way I thought. How much of the screen does one "attribute tile" take up again?
Last edited by puppydrum64 on Mon May 17, 2021 7:07 pm, edited 1 time in total.
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Is PPU_DATA read slow?

Post by dougeff »

You should represent the solid area of the screen in RAM or in ROM, as a byte array. Or, some other data structure.

You need to have immediate access to it at all times so that it doesn't lag the game.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Is PPU_DATA read slow?

Post by Bregalad »

Dwedit wrote: Tue Jan 12, 2021 10:53 am Because reading from the PPU is so restrictive, it's generally only used for storing blocks of data in CHR-ROM. [...]
So don't read from the PPU unless you are storing data in CHR-ROM. You need to stop any DMC samples from playing during that time.
Just to nickpit, there's another common usage of VRAM reading, which is to modify the attributes for a 2x2 region without affecting the rest of the 4x4 region for which they are stored.
An answer to the literal question: individual PPU reads/writes are the same speed as any other read/write on this CPU. It's probably worth saying so, just because there are lots of platforms (modern and old) where video memory access is slower.
I was going to say the same ;)
They're as fast as any other acess, with the exeption that they are delayed by 1 read.
Useless, lumbering half-wits don't scare us.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Is PPU_DATA read slow?

Post by tokumaru »

Bregalad wrote: Tue May 18, 2021 12:35 amJust to nickpit, there's another common usage of VRAM reading, which is to modify the attributes for a 2x2 region without affecting the rest of the 4x4 region for which they are stored.
Updating attributes like that is extremely inefficient though... I'm pretty sure the vast majority of programmers prefer to buffer attributes in RAM instead, either partially or completely.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Is PPU_DATA read slow?

Post by Bregalad »

Just saying I've seen games doing that. Shadowing $80 bytes for attributes isn't particularly efficient either.
Useless, lumbering half-wits don't scare us.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Is PPU_DATA read slow?

Post by tokumaru »

Bregalad wrote: Tue May 18, 2021 3:18 amJust saying I've seen games doing that.
I never saw any games doing that, but it's not like I've debugged the entire NES library... If I had to guess, based solely on how games look, I'd say that most games don't bother much with attributes once things are on screen... Most games with collectable/destructible blocks I can think of just erase the tiles and leave the attributes alone.
Shadowing $80 bytes for attributes isn't particularly efficient either.
Definitely not RAM-efficient, but I consider that less awkward than doing RMW operations using the PPU's address-data interface.
puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 7:25 am

Re: Is PPU_DATA read slow?

Post by puppydrum64 »

Bregalad wrote: Tue May 18, 2021 3:18 am Just saying I've seen games doing that. Shadowing $80 bytes for attributes isn't particularly efficient either.
The trade-off has to be made somewhere. A lot of hardware registers are write-only and can only be safely written to during vBlank, so most of the time having a shadow is basically required to do anything with them.

For me it depends on what I'm doing. Sometimes I'd rather define redundant data in ROM just to make loading easier (it's the whole concept behind lookup tables), other times things can be done in RAM. For example I think something like this is just waste:

multiples_of_four:
.byte $00, $04, $08, $0C, $10

There's no real need for this since you can just ASL twice and get the same result. I'll do it for multiples of 5 though because there's no quick way to make that happen.
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is PPU_DATA read slow?

Post by Controllerhead »

puppydrum64 wrote: Sat May 22, 2021 6:43 pm For example I think something like this is just waste:

multiples_of_four:
.byte $00, $04, $08, $0C, $10

There's no real need for this since you can just ASL twice and get the same result.
I have used this to preserve A like so:

Code: Select all

LDX multiples_of_four, y
It can be very useful when using A to calculate sprite things; and a bit quicker in some situations.
Image
puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 7:25 am

Re: Is PPU_DATA read slow?

Post by puppydrum64 »

Controllerhead wrote: Sat May 22, 2021 7:48 pm
puppydrum64 wrote: Sat May 22, 2021 6:43 pm For example I think something like this is just waste:

multiples_of_four:
.byte $00, $04, $08, $0C, $10

There's no real need for this since you can just ASL twice and get the same result.
I have used this to preserve A like so:

Code: Select all

LDX multiples_of_four, y
It can be very useful when using A to calculate sprite things; and a bit quicker in some situations.
Interesting. Somehow I never thought of using LDX $HHHH, y. I thought for some reason you could only do that with LDA.
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is PPU_DATA read slow?

Post by Controllerhead »

puppydrum64 wrote: Sat May 22, 2021 8:28 pm [Somehow I never thought of using LDX $HHHH, y. I thought for some reason you could only do that with LDA.
Well, it's weird, you can LDX $HHHH, y but you can't STX $HHHH, y; STX $HH, y only works in zero page.

Perhaps one of the local hardware wizards knows why this is the case, but i sure don't.
Image
Post Reply