8

According to the Nesdev wiki's article on the NES/FC's PPU (https://www.nesdev.org/wiki/PPU) : "while the palette is made of static memory, OAM uses dynamic memory (which will slowly decay if the PPU is not rendering). "

As I've just started picking up 6502 assembly to develop on the NES, this struck me as odd. From what I understand, Nintendo developed the PPU using SRAM entirely, but left that out specifically for the OAM

What this essentially means is that I HAVE to spend CPU cycles sending 64 sprites to the OAM each time, even if my screen never changes, causing me to spend precious CPU cycles to 'refresh' the OAM memory

Given how performance-constrained the NES already is, why did Nintendo opt to use dynamic instead of static ram on the OAM?

And given this decay is random, could the OAM potentially decay in the middle of a frame being rendered?

4
  • 8
    Static memory costs more per bit. Commented May 25 at 16:39
  • 9
    Same reason we use DRAM today. Commented May 25 at 16:45
  • 2
    Why do you believe you must write to the OAM to refresh the DRAM? The wiki page says the DRAM fades "if the PPU is not rendering." Is there any moment while the unit is powered on that the PPU is not by itself rendering to the video output? Commented May 25 at 16:54
  • 4
    This question could be improved by defining PPU and OAM. Commented May 26 at 14:10

2 Answers 2

36

You don't have to send sprites to prevent decay. The only time decay becomes an issue is if you turn off rendering (black screen). As long as the PPU is rendering, it will scan the sprite list on each scanline and these OAM reads will refresh its contents.

The reason it decays is because it's DRAM rather than SRAM. SRAM requires 6-8 transistors per bit, while DRAM is one transistor and a capacitor, meaning you can pack much more into the same space.

DRAM works by charging the capacitor - a charged capacitor means 1, a discharged one means 0. However this has consequences. Every time you read a DRAM cell you are effectively draining the capacitor - if charge comes out you know it was a '1', otherwise it's '0'. DRAM circuitry is normally designed so that every time it reads a row it will then also write it back, recharging the capacitors that should be '1'.

However those capacitors will also slowly drain on their own, as little as 1 to 2 ms before it might not be clear if the contents are a '1' or a '0'.

So often times DRAM will include a refresh circuit, essentially a loop that uses idle time to read each row and write it back, ensuring the capacitors stay charged.

The NES PPU doesn't have anything like that. Instead it relies on the fact that for each scanline to be rendered it must read the sprite list, thus indirectly refreshing the contents. (This is similar to the Apple II, designed by Steve Woz, where the circuit that rendered the graphics was designed so that it would refresh the system's DRAM as a side effect of reading the pixels which were spread across the rows of RAM.)

The only times the PPU is not refreshing the sprite DRAM in this way is during the vertical refresh period and when rendering is explicitly turned off by the programmer (technically the PAL version does some fake rendering during the second part of the vertical refresh, since it's longer than the NTSC refresh and could allow for decay).

8
  • 1
    It might be good to emphase the first paragraph as it hold all there is to know in relation to the NES/PPU. (also, there are many systems that use video display as primary resource for refresh, thus not needing dedicated refresh circuitry. Commented May 25 at 17:33
  • Very good answer, upvoted. That OAM reads refresh the OAM contents wasn't said outright til much further down so I've added a few words to first paragraph to introduce that, you can change it if you don't like the edit or would say it differently there. Commented May 26 at 9:07
  • 1
    @Justme where's the difference? Commented May 27 at 7:54
  • 1
    @Justme: Using a special DRAM process would allow the use of single-transistor memory cells. If I'm understanding the die layout correctly, the PPU uses two-transistor cells which take twice as much space as special-process DRAM, but less space than required for three-transistor dynamic latches or four-transistor SRAM cells. I think the way the design works is that the column wires are paired, and so writing a 0 charges one transistor toward +5 and the other to ground. The column wires then have RS latch with gated feedback. Normally, an RS latch's power-on state would be random... Commented May 27 at 14:53
  • 1
    ...but I think what's going on here is that between accesses the RS latch connected to a pair of column wires is powered down and the columns are discharged and then floated. After that, a row is connected and the latch is powered up. The residual charge on the memory cell attached to one of the columns will cause that column to win the "power-up race", after which it will ground the other column while it gets charged the rest of the way toward +5 (as close as it can get with NMOS technology, which probably isn't terribly close). Commented May 27 at 14:57
0

dram memory cells are smaller/cheaper than sram memory cells, however.

  1. Dram reads are destructive, so any DRAM requires a support circuit that after the DRAM is read, will write-back the values that were read out.
  2. Data in dram "decays", so for reliable reads the cells must be periodically refreshed.

Fortunately, refresh typically doesn't require an access to every individual memory location, instead accessing any location in a "row" will cause the entire row to be refreshed. This reduces the number of cycles needed for refresh, and with careful design can mean a circuit that only accesses a portion of the memory can double up as a refresh controller (this was exploited by the apple II and the BBC micro to refresh main memory).

As the other answer points out, on the NES as the PPU was "running" the OAM would be refreshed by the normal PPU activity.

Dram is also in general more of a hassle to work with than SRAM. With SRAM, a read or write cycle happens in a single operation. DRAM typically requires sequential selection of "row" and "column", re-using the same address lines for both. DRAM chips were also initially only a single bit wide, later increasing to 4 bits, while SRAM chips were readily available in a full 8 bit width.

I would therefore speculate that.

  • SRAM was chosen for the palette because it was relatively small, and the access patterns did not guarantee it would be refreshed adequately.
  • DRAM was chosen for OAM because the chip area savings were worthwhile and the access patterns automatically resulted in a refresh.
  • SRAM was chosen for nametable ram, because it was easier to interface to the external bus of the PPU (which was shared with the CHR rom in the cart) and because SRAM chips were readily available in 8-bit widths, while DRAM chips tended to be narrower.
2
  • Designing the PPU to interface with DRAM only would be cheaper than interfacing with a combination of RAM and ROM, since there would be no need for the external address latch, nor for the connections between the PPU and the cartridge. A modernized version of the display chip used in the Colecovision, paired with a couple of 16Kx4 DRAMs, could have been quite powerful. Commented Jun 2 at 20:03
  • Looking at retrocomputing.stackexchange.com/questions/28194/… it seems x4 DRAMs existed when the famicom was being designed, but were a bit esoteric. Commented Jun 2 at 20:23

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.