NES Advantage

Making NES Development Less Hard

Implementing OAMDMA

OAMDMA is the best practice technique for loading sprite data into the PPU's OAM tables. It involves keeping live sprite data in a single page of RAM and making changes to it during the game loop. Then, during the NMI interrupt, the entire contents of the RAM page are dumped at once to the PPU's Object Attribute Memory (OAM) by writing to a special OAMDMA port.

I'll start with the full code block, then I'll explain what each line does. Note that this code block lives inside your NMI interrupt. There might be other code around it (for example, there will certainly be an RTI, "return from interrupt," somewhere after it).

; ... other NMI code LDA #$00 STA $2003 LDA #$02 STA $4014 ; ... other NMI code

That's not a lot of code for such a crucial function. So how does it work? To start with, note that the PPU's OAM tables total 256 bytes, the size of one RAM page. Handy, right? It's almost like Nintendo's hardware team designed it this way. To use this automated technique, all we need to do is tell the OAM where to start writing, and the OAMDMA function itself what RAM page to copy over.

With that said, let's look at the code. The first two lines write the value $00 to memory address $2003. As you might know, $2003 is known as OAMADDR. It's the memory port dedicated to telling OAM where to write. So these two lines are just making sure that when we copy over our sprite data, we're starting at the beginning ($00) of the OAM memory.

Now we just have to fire off the copy itself, making sure it reads from the right place. Handily, that's done with a single move: writing the value $02 to memory address $4014. Why $02? It's the high byte of the RAM page we've chosen to use to prep our sprite data, which runs from $0200 to $02FF. Again, page 2 is used by convention, but you could theoretically use page $05 or something.

Anyway, memory address $4014 is the dedicated OAMDMA port. By writing $02 to it, we kick off the entire process: the NES knows to copy the entire contents of RAM page 2, from start to end, to the OAM, which we initialized back to its own beginning. Voila!

Copyright ©2024 Nathaniel Webb/Nat20 Games