Skip to content

Instantly share code, notes, and snippets.

@benolee
Last active April 13, 2023 23:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benolee/d685cedb653fed3c76a68b60ae6a3cf8 to your computer and use it in GitHub Desktop.
Save benolee/d685cedb653fed3c76a68b60ae6a3cf8 to your computer and use it in GitHub Desktop.
NES DOOM

NES DOOM

https://www.youtube.com/watch?v=gCWhWBtu0LA

21_various_games

The NES is connected to the graphics memory on the cartridge via groups of signals called buses. There's the Address Bus and the Data Bus. When the NES wants to access graphics memory on the cartridge, it puts the memory address it wants in the Address Bus. The memory chip then grabs the data at this address and transfers it to the NES via the Data Bus.

10_address_bus_data_bus

Now, you'd think in order to emulate a memory chip, you'd have to watch the Address Bus to know what data to send back, which would be quite complicated to do. And that's true in general. However, the NES accesses memory in the exact same order each time for each frame of video. As we can predict exactly what data it will want at any given time, we can just feed it data in that exact order and ignore the Address Bus entirely. This means that our logic circuitry and software can be much simpler.

There's another benefit to ignoring the Address Bus, and it has to do with the way NES graphics work. The NES screen, which is 256×240 pixels, is divided into 16×16 pixel sections called attribute areas.

11_256_240

Each attribute area can only have four different colors displaying at one time, which makes for a pretty bad color resolution. The colors that each attribute can display are stored in an area of memory called the Attribute Table.

22_attribute_table_visualization

When the NES wants to check which colors a particular attribute can display, it reads that part of memory. But the NES actually does this 32 times per attribute area, once for each 8×1 pixel section of the attribute.

12_8_x_1

The NES looks at the same memory bus address for all of these 8×1 pixel sections, and it's expecting to get the same value back each time on the Data Bus.

13_address_data_expected

But since we're ignoring the Address Bus, we can feed it a different set of colors for each section, thus fooling the NES into giving us 8×1 pixel attribute areas instead of the normal 16×16 pixel.

14_address_data_different

And this results in a much better color resolution than NES games can normally achieve.

23_color_resolution

However, even with these techniques, we're limited to only 13 different colors on screen at once.

We can increase the perceived number of colors with a process called dithering, which is where you deliberately apply noise to the picture. This stops the banding effect you get on color gradients but gives the picture a kind of speckly appearance.

24_dithering

There are many things that could be done to increase the video quality, such as dynamic palette generation or using sprites to add additional colors to certain parts of the screen. Or even just using a better dithering algorithm, such as one of the ones invented by Joel Yliluoma.

25_doom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment