Overview

I wanted to write CPU directly, but I thought I’d write a summary first, just to get a general idea.

It leaves out a lot of things, but that’s what it looks like. The gamepad is the input device, the TV is the output device, the CPU is the processor, the PPU is the graphics processor, and the tape can be regarded as part of the storage

Nintendo’s CPU-related summary is as follows:

You can see that the address bus is 16 bits, but the data bus is only 8 bits.

As shown in the figure above, the ADDRESS space of CPU is divided into three parts, one is ROM, which is located in the cassette, RAM is CPU’s own memory, I/O is some memory-mapped registers, through which CPU communicates with PPU, handle and so on.

Nintendo’s map is not very clear about the CPU PPU address space, so we drew our own map, as shown above, to briefly explain the nouns that appear:

CHR: Character Memory, which stores the patterns used in the game

PGR: Program Memory, which stores game code

Nametable: VRAM, this part is the PPU’s own memory, storing the index of the pattern and certain color information.

Pallete: a palette of colors used for rendering (an index of colors)

CPU RAM: The CPU’s own memory

The ADDRESS space of a CPU consists of three parts, from lowest to highest: CPU RAM -> Memory mapped register -> PRG

The PPU’s address space also consists of three parts, from lowest to highest: Nametable->CHR->Pallete

Memory-mapped registers are used by the CPU to communicate with other subsystems, such as the PPU, accessing data in the PPU address space, communicating with input device handles, communicating with the internal APU, etc.

Also note that although PRG and CHR are both inside the tape, they map to different address Spaces.

The following is a brief description of these parts:

Let’s start with the cassette tape. There are two main Memory chips in the cassette tape. The first one is PRG, which is a read-only ROM.

The second is CHR, Character Memory, ROM and RAM are all possible, different in different cassettes. This is where the graphics used in the game are stored. For example, we are familiar with Super Mario CHR:

This is a screenshot I took after OPENING Super Mario With FCEUX using the PPU Viewer tool. If you are interested, download the emulator and try it out.

You can see that there are mainly two patternTables in super Mario’s CHR. The two patternTables have no specific names, but you can see that in Super Mario, The PatternTable on the left is mostly used by sprites (sprites are character health bar scores, etc.), and the background is mostly used on the right.

Each PatternTable is made up of 256 “tiles” called tiles. A tile is a set of pixels 8×88 \times 88×8.

To represent a pixel pattern, 1 pixel can be represented by 1bit, for example, 0 means transparent, 1 means opaque, then 8×8=64bit8 \times 8=64bit8×8=64bit can represent a pattern, but tile uses 2 bits to represent a pixel, Here’s an example:

This tile is the upper right corner of the head of the grown Mario, so what is essentially a tile? A tile is 64 2-bits of information, but note that the 2-bits of a pixel are stored separately, as shown above.

The reason for using 2 bits to represent a pixel is that the 2 bits can be indexed in 4 colors (actually only 3, because of the transparent “color “), so you can know that a tile can never have more than 4 colors. Remember what I said about “stinginess”? This is one of the “stingy”.

So for PatternTable, even though it’s called PatternTable, it stores not only pattern information, but color information as well.

As you know, a video, a continuous frame, was made up of frames, whereas on the NES, every frame displayed to the TV was made up of tiles.

How many tiles does that frame consist of? So how many pixels does the image have? Each frame is 256×240256 times 240256×240 pixels, that is, 32×30=96032 times 30=96032 ×30=960 tiles.

The 960 tiles must be arranged in some order to make a correct image, so where is the order recorded? This is the PPU’s own RAM, also known as VRAM, also known as Nametable.

A screen or frame has 960 tiles, but the information recorded in Nametable is not the tile itself, but the index of the tile. Here’s an example:

As you can see in the figure above, M uses tiles with an index of $16, gold uses tiles with an index of $2E, haystells and corners of clouds both use tiles with an index of $36, $represents hexadecimal, and $is used for hexadecimal instead of 0x in NES CPU assembles.

At one point, the background will simply select tiles from one of the PatternTables, which, as shown in the Mario example above, is PatternTable on the right.

The cloud and the haystack are actually the same thing, but of a different color. It looks colorful, but many of them are the same thing. No matter how colorful a frame is, it can’t be more than 256×2=512256 times 2=512256×2=512 tiles. That’s the second “cheapness”

PPU Nametable is used to store tile indexes.

A PatternTable has 256 tiles, so the index needs to be 8 bits. There are 960 tiles in a screen, so the index needs to be 960B. Nametable has two tiles, each 1KB = 1024B. So 2 Nametables can hold 2 screens of tile indexes.

Physically there are 2 screens, but logically there are 4 screens, 2 of which are mirrored, that’s another story, but it’s important to know that having more space to store indexes makes scrolling easier (emM is not easy either). Here’s an example of scrolling horizontally:

The top of the image is the index of the two screens, but instead of the pattern, the box is the screen, and the contents of the box are rendered to the screen, as shown below.

So now we know that the Nametable contains the tile index of the two screens, and the PPU will render the background based on the index of the two screens.

So who fills this Nametable? This is controlled by the game code, and when and what to fill is logically controlled by the code.

Back to the simple calculation, a Nametable 1024B, but a screen of tile index only uses 960B, 64B? Throw it away? That’s impossible. In those days, there was no such thing as wasting an inch of land.

This 64B is called the Atrribute Table, which is essentially the color property of the background. What? 64B can record the color properties of a screen? Of course not, but close enough.

Speaking of color, there are many ways to express color. For example, RGB is the most familiar. A triplet (R, G, B) can represent a color, and the reference range of each element is [0, 255].

In NES, there were 64 theoretically available colors. Remember from the address space diagram, there was a space in the PPU for color information, but it wasn’t the colors themselves, it was an index of the colors in the NES palette.

There are 8 items in PPU Pallete, and each item is indexed in 4 colors. You can only use the first 4 colors for backgrounds, and the last 4 for sprites. That’s not the end of the story. All Pallete backgrounds should have the same background color, so you can only use 3×4+1=133 \times 4+1=133 ×4+1=13 colors. Sprites need to be transparent, so sprites actually only have 3×4=123 \times4 =123 ×4=12 colors available.

Back to the Attribute, the Attribute is used to select which Pallete item, but the 64B Attribute is 32×3032 \times 3032×30 tiles, 256×240256 \times 240256×240 pixel Pallete, that will inevitably cause some tiles to use the same Pallete, which is why these games are so flat color, which is also “cheap” number three. Specific color how to choose a choice, or some complex, in a few words or two can not explain, to be left behind in detail.

PatternTable, and here AttributeTable, Pallete, are all talking about colors. What’s going on with colors? Let’s get this straight: AtrributeTable is used to select the Pallete entry, and PatternTable is used to select the color index in the Pallete, which in turn points to the actual color.

I’ve been talking about backgrounds, but I’m going to talk about sprites. Have you noticed something missing from some of the above pictures? Less characters and other sprites, sprites and background is separate and separate control.

The PPU has a dedicated INTERNAL RAM(not displayed in the address space, which cannot be accessed directly, but needs to be accessed through a specific port) to store Sprite information. This part of the space is called OAM(Object Attribute Memory), also known as Sprite RAM. OAM can hold 64 Sprite entries, but can only render up to 8 sprites at a time.

Each Sprite item controls some properties of the Sprite, such as which tile the Sprite uses (the tile index), the Sprite’s position (the X and Y coordinates), the Pallete item the Sprite uses, whether it flips, and so on.

To give you a simple example, let’s say Mario grew up:

Obviously, this grown Mario is made up of 8 tiles, which are PatternTable tiles I won’t label.

Look carefully at the words of Mario, you can also find that his lower part is symmetrical, there are no tiles circled with red box inside the PatternTable, and there are only symmetrical patterns on the left side inside the PatternTable, which is the fourth of “Matting”. The same tiles are directly reversed and used. Here we have a horizontal flip, and then we have a vertical flip, which I won’t do here.

In one frame, the background of the screen is 960 tiles arranged in an orderly manner, which is determined by the logic of the game code. The game code states that the cloud is in the sky, so it cannot move in the sky unless the code is changed.

However, sprites are different. The Sprite entries in OAM have attribute items that specifically control the Sprite position (X and Y coordinates). Theoretically, sprites can be anywhere in a Sprite frame, but a game has a game logic.

The position of a general character can be controlled by a Controller, such as a Controller. The general process is that the Controller buttons send signals to the CPU, and then monitor the corresponding buttons to change the position properties of the Sprite in the OAM, and then the PPU will render to the corresponding position.

To render the background and Sprite, the two pixels must overlap. The PPU has its own logic to control which pixel to output, which will be discussed later.

The interesting thing about this is that if the opaque pixel of the 0th Sprite overlapped with the opaque pixel of the background, it would cause Sprite 0 hit, and you could use this feature to split creen. “, basically means that only part of the screen is rendered scrolling.

The expression of emMM sensation is not accurate. For example, when playing Super Mario Bros, you will find that the score, time and other information at the top of the screen do not scroll out of the screen, but remain relatively still at the top of the screen:

This is what Sprite 0 hit does.

Also can make the effect of the blockbuster level, the most talked about is the ninja Gaiden too long animation.

This is no problem blockbuster effect!!

As for rendering to the screen, render in the same order as we read and write, from top to bottom and left to right, as follows:

The output signal of this PPU needs to be picked up by a CRT TV, commonly known as a big ass TV, which is the kind of TV with a big mess behind the screen. The idea is that an electron gun fires electrons at a phosphor screen, which glows when excited by high-speed electrons.

There are a few terms to know, the rendered line is called a scanline, and there are 240 scanlines visible in each frame, which corresponds to the 256×240256 \times 240256×240 pixels we mentioned earlier.

There is a gap between each frame of the render because the gun needs to return to the upper left corner after the last line of the render. This is called a vblank. This part actually triggers an NMI interrupt, during which time the CPU can update NameTable, OAM and other information for the next rendering.

It’s highly recommended to check out this video:

The working principle of TV in slow motion is popular science (CRT/LED/OLED)

What is the process of rendering?

For the background, the tile index of the background is usually stored in the Nametable before rendering the background. Based on the tile index, the color information stored in the tile and the color information in the AttributeTable is obtained. The combination of the two is the index of the actual color.

And elves? The Sprite tile index and Attribute are stored in the OAM(the Sprite items being rendered are actually stored in a buffer), and the index of the actual color is also synthesized from the color information in the Attribute and tile

The PPU then decides whether to output the background color or the Sprite color according to some state information. The color signal is sent to the TV, and the TV outputs to the screen.

Rendering is one of the most complex processes, a few words will not suffice, but more on this later.

Mapper, also known as Memory Management Chip (MMC), is mainly used to solve the limitation of game size. The address space of CPU and PPU is limited. If the game is too big, it may not be mapped. Therefore, Mapper is required to control which space of the current address space is mapped to the tape. The term is called bank switching, which is to divide the space inside the tape into banks one by one, and then Mapper controls the bank mapping to the corresponding address space.

Ok, this article roughly said so much, mainly want to let everyone have a general concept first, in fact, I wrote later already felt self-defeating, these things are not clear in a few words, but I want to say clearly, there may be some places expressed not too clear, then wait for me to slowly talk about it later.

CPU and PPU both have their own bus, and the address space is mainly composed of three parts. The cassette contains the code of the game and the pattern used by the game, but these two are respectively mapped to the address space of CPU and PPU.

The tile index used by the background is stored in NameTable, which contains the Attribute Table. The tile index and Attribute used by the Sprite are stored in the OAM. The tile itself has two bits of color information, and the Attribute has two bits of color information, which together is the index of the actual color in the palette.

For rendering, the PPU takes 256×240256 \times 240256×240 pixels of color information and sends it to TV. The rendering sequence is top to bottom and left to right. There is an idle time called vblank between each frame of rendering. During this time, the CPU can update some information in NameTable and OAM for the next rendering.

I had first contact with some fields, but I had no Chinese materials about NES. I only read English materials directly, so I had some misunderstanding in some places. I didn’t see many English terms and didn’t bother to find an official translation, so I used English directly. If you have any questions, please also criticize and correct, and welcome to communicate with me, the next article should be really about the CPU 6502.