PPU emulation

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
PPU emulation
by on (#690)
Hello everyone, I have written the 6502 core already for my emulator (in java), I just need to know how one should go about writing the code to handle the ppu? I have read many documents and bits of source code on the subject but am still lost as how to go about it. Thanks in advance

by on (#693)
Here are some threads you may want to read:

http://nesdev.com/cgi-bin/wwwthreads/showpost.pl?Board=NESemdev&Number=1931&page=0&view=collapsed&sb=5

http://nesdev.com/cgi-bin/wwwthreads/showpost.pl?Board=NESemdev&Number=1905&page=1&view=collapsed&sb=5

http://nesdev.com/cgi-bin/wwwthreads/showpost.pl?Board=newbie&Number=1392&page=0&view=collapsed&mode=threaded&sb=5#Post1392

You may also want to read Brad Taylor's document on PPU addressing logic.

by on (#696)
thanks a lot, ill get right on reading it and hopefully ill see graphics tonight or early tomorrow

by on (#697)
Thanks for the info, but I also need to know where to look in the ppu memory to find the graphics and how to draw them really because i cant figure out the docs that are out there.

by on (#705)
VRAM Area $0000-$1fff is where you'd find the pattern tables, which contain graphical information about tiles referenced by the nametables, i.e. the stuff that actually gets drawn to the screen.

VRAM Area $2000-$3000 is where you will find the nametables. Note that there are actually only two physical tables, whereas the others are just mirrors.

VRAM Area $3f00-$3f20 is where the palette data can be found.

Code:
      +---------+-------+-------+--------------------+
      | Address | Size  | Flags | Description        |
      +---------+-------+-------+--------------------+
      | $0000   | $1000 | C     | Pattern Table #0   |
      | $1000   | $1000 | C     | Pattern Table #1   |
      | $2000   | $3C0  |       | Name Table #0      |
      | $23C0   | $40   |  N    | Attribute Table #0 |
      | $2400   | $3C0  |  N    | Name Table #1      |
      | $27C0   | $40   |  N    | Attribute Table #1 |
      | $2800   | $3C0  |  N    | Name Table #2      |
      | $2BC0   | $40   |  N    | Attribute Table #2 |
      | $2C00   | $3C0  |  N    | Name Table #3      |
      | $2FC0   | $40   |  N    | Attribute Table #3 |
      | $3000   | $F00  |   R   |                    |
      | $3F00   | $10   |       | Image Palette #1   |
      | $3F10   | $10   |       | Sprite Palette #1  |
      | $3F20   | $E0   |    P  |                    |
      | $4000   | $C000 |     F |                    |
      +---------+-------+-------+--------------------+
                          C = Possibly CHR-ROM
                          N = Mirrored (see Subsection G)
                          P = Mirrored (see Subsection H)
                          R = Mirror of $2000-2EFF (VRAM)
                          F = Mirror of $0000-3FFF (VRAM)


(Note: Extracted directly from NESTech.)

How do you access all these VRAM areas? Well, first you set $2006 to the VRAM address you want to write to (i.e. $2000 if you wanna start writing data to the first nametable), then you write the data to $2007.

One thing that may be confusing you is that VRAM is not part of the main memory area. Here is a map of the main memory:

Code:
    +---------+-------+-------+-----------------------+
    | Address | Size  | Flags | Description           |
    +---------+-------+-------+-----------------------+
    | $0000   | $800  |       | RAM                   |
    | $0800   | $800  | M     | RAM                   |
    | $1000   | $800  | M     | RAM                   |
    | $1800   | $800  | M     | RAM                   |
    | $2000   | 8     |       | Registers             |
    | $2008   | $1FF8 |  R    | Registers             |
    | $4000   | $20   |       | Registers             |
    | $4020   | $1FDF |       | Expansion ROM         |
    | $6000   | $2000 |       | SRAM                  |
    | $8000   | $4000 |       | PRG-ROM               |
    | $C000   | $4000 |       | PRG-ROM               |
    +---------+-------+-------+-----------------------+


I think NESTech covers this process pretty well, but I doubt you still have not read it. Let me know if you have more questions (you probably will).

by on (#707)
thanks a lot, it is starting to make sense now, ill see if I can make my emu draw graphics now, other than strange grey boxes.

by on (#708)
Taken from nestech.txt (cant remember author) based on Fayzullin's nes.txt
Quote:

C. Name Tables
--------------
The NES displays graphics using a matrix of "tiles"; this grid is called
a Name Table. Tiles themselves are 8x8 pixels. The entire Name Table
itself is 32x30 tiles (256x240 pixels). Keep in mind that the displayed
resolution differs between NTSC and PAL units.

The Name Tables holds the tile number of the data kept in the Pattern
Table (continue on).


D. Pattern Tables
-----------------
The Pattern Table contains the actual 8x8 tiles which the Name Table
refers to. It also holds the lower two (2) bits of the 4-bit colour
matrix needed to access all 16 colours of the NES palette. Example:

VRAM Contents of Colour
Addr Pattern Table Result
------ --------------- --------
$0000: %00010000 = $10 --+ ...1.... Periods are used to
.. %00000000 = $00 | ..2.2... represent colour 0.
.. %01000100 = $44 | .3...3.. Numbers represent
.. %00000000 = $00 +-- Bit 0 2.....2. the actual palette
.. %11111110 = $FE | 1111111. colour #.
.. %00000000 = $00 | 2.....2.
.. %10000010 = $82 | 3.....3.
$0007: %00000000 = $00 --+ ........

$0008: %00000000 = $00 --+
.. %00101000 = $28 |
.. %01000100 = $44 |
.. %10000010 = $82 +-- Bit 1
.. %00000000 = $00 |
.. %10000010 = $82 |
.. %10000010 = $82 |
$000F: %00000000 = $00 --+

The result of the above Pattern Table is the character 'A', as shown
in the "Colour Result" section in the upper right.


I cannot understand the above, it does not really add up and Why would the 8x8 tile be split into two pieces?

[/quote]

E. Attribute Tables
-------------------
Each byte in an Attribute Table represents a 4x4 group of tiles on the
screen. There's multiple ways to describe what the function of one (1)
byte in the Attribute Table is:

* Holds the upper two (2) bits of a 32x32 pixel grid, per 16x16 pixels.
* Holds the upper two (2) bits of sixteen (16) 8x8 tiles.
* Holds the upper two (2) bits of four (4) 4x4 tile grids.

It's quite confusing; two graphical diagrams may help:

+------------+------------+
| Square 0 | Square 1 | #0-F represents an 8x8 tile
| #0 #1 | #4 #5 |
| #2 #3 | #6 #7 | Square [x] represents four (4) 8x8 tiles
+------------+------------+ (i.e. a 16x16 pixel grid)
| Square 2 | Square 3 |
| #8 #9 | #C #D |
| #A #B | #E #F |
+------------+------------+

The actual format of the attribute byte is the following (and corris-
ponds to the above example):

Attribute Byte
(Square #)
----------------
33221100
||||||+--- Upper two (2) colour bits for Square 0 (Tiles #0,1,2,3)
||||+----- Upper two (2) colour bits for Square 1 (Tiles #4,5,6,7)
||+------- Upper two (2) colour bits for Square 2 (Tiles #8,9,A,B)
+--------- Upper two (2) colour bits for Square 3 (Tiles #C,D,E,F)


[/quote]

The above sort of makes sense, but I still dont quite get it and dont know how to use this in my Emu.

I was just wondering if you could help explain some of this, thanks in advance and thanks for being patient with me

by on (#709)
You're joking... I can't believe the "tell-me-how-'n-next" thing! >_<;;.

by on (#710)
Sorry, dont mean to sound like "just gimme the code!" but I really dont understand how the heck it works

by on (#711)
Alright, i looked at a demo nes game and hededited the .chr file for the graphics, i found 8 bytes that draw a sprite of a ball, it is in binary format and thats easy enough to find and display, but what i have wanted to know (sorry, havnt been so clear up to now) is how the ppu decides what color to use for each pixel

by on (#712)
A tile is divided into two 8-byte bitplanes, each of which is divided into eight 1-byte rows. Each row has 8 pixels; the most significant bit of each row is drawn on the left (except in horizontally flipped sprites). Thus, each pixel corresponds to a bit in the first plane and a bit in the second plane, and the color index value for each pixel is computed as follows:
Code:
Second  First  Pixel color
 plane  plane  (low 2 bits)
  bit    bit
---------------------------
   0      0    Transparent
   0      1         1
   1      0         2
   1      1         3

A slightly easier to read example of a tile shaped like the fraction 1/2 is in the "Pattern tables" section of this NES Wiki page about the PPU.

by on (#722)
Ahh, thank you soo much, that has been bothering me, now Its all coming together. Thanks again, and btw merry christmas to everyone