Where are graphics located on NES roms?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
ArsonIzer
Posts: 115
Joined: Fri Jul 19, 2013 11:38 am

Where are graphics located on NES roms?

Post by ArsonIzer » Fri Jul 19, 2013 12:09 pm

Hello there guys, I'm a new member to this site, and I'm also pretty new to the emulation scene. The NES is going to be my first console emulator, and I hope you can help me with my problems.

I'm already mostly done with the CPU, and it works well, cycles seem accurate up until now, and it just seems to function like it should. My problem now is the PPU. I'm stuck with all the graphics stuff. After having read up on name tables, pattern tables, attribute tables, palettes, sprites, etc, I'm wondering, where on an ROM/cartridge is all this stuff located? Now, I know the generic answer would be: "in the CHR memory banks", but here's the problem: How do I figure out which thing to find where? Where are the pattern tables located? Where are the name tables located? The PPU seems to have access to 16KB memory, which mostly contains graphics-related stuff, but I don't know how to find the location/memory area of these things.

What confuses me is that games don't have a fixed amount of CHR banks, and some have none at all. Imagine if a game has only 1 CHR memory bank of 8KB, that wouldn't fit all these things, would it? And what if a game doesn't have any CHR banks? How do I figure out where all the tables/palettes are located? Can someone give me a breakdown of how to figure these things out? I'm assuming the answer is pretty simple, but I just can't seem to figure it out.

Thanks.

User avatar
tokumaru
Posts: 11991
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Where are graphics located on NES roms?

Post by tokumaru » Fri Jul 19, 2013 12:43 pm

ArsonIzer wrote:After having read up on name tables, pattern tables, attribute tables, palettes, sprites, etc, I'm wondering, where on an ROM/cartridge is all this stuff located? Now, I know the generic answer would be: "in the CHR memory banks", but here's the problem: How do I figure out which thing to find where?
The CHR banks are mapped to the pattern tables, and the rest (name, attribute, etc.) have absolutely nothing to do with the CHR banks in the ROM file.
Where are the pattern tables located? Where are the name tables located? The PPU seems to have access to 16KB memory, which mostly contains graphics-related stuff, but I don't know how to find the location/memory area of these things.
All of these are visible in the PPU addressing space. If you look at the CPU memory map, you'll see that certain ranges of it are mapped to different things ($0000-$07FF is RAM, $8000-$FFFF is ROM, etc.), the PPU memory map (look it up in the wiki) is similarly divided into palettes, pattern, name and attribute tables. Only the pattern tables are "ready to use" on power up (only if the cart uses CHR-ROM, though!), everything else must be initialized by the program itself, because it's all RAM.
What confuses me is that games don't have a fixed amount of CHR banks, and some have none at all.
None at means that the cart uses CHR-RAM. In this case, the pattern tables are "empty" on power up and the game program itself takes care of filling it with tiles.
Imagine if a game has only 1 CHR memory bank of 8KB, that wouldn't fit all these things, would it?
Depends on the game. Lots of early games (SMB1 included) make do with just those 512 tiles.
And what if a game doesn't have any CHR banks? How do I figure out where all the tables/palettes are located?
You don't have to figure out anything, that's up to the game program. It will take care of putting everything where it needs to be. All you have to do is render the frame according to the rules of the PPU. For rudimentary PPU support, you can once per frame (like, at the end of VBlank) read it all and generate a picture: use the scroll values to know what part of the name tables to use, then get the tiles indicated there, apply the attribute bits from the attribute tables and look up the final colors in the palettes. After that, you can read the OAM and overlay sprites. This will get the simplest games working, but to actually simulate a NES you'll have to run the PPU in parallel with the CPU (vs. rendering the whole frame at once).

ArsonIzer
Posts: 115
Joined: Fri Jul 19, 2013 11:38 am

Re: Where are graphics located on NES roms?

Post by ArsonIzer » Fri Jul 19, 2013 12:59 pm

tokumaru wrote:
ArsonIzer wrote:After having read up on name tables, pattern tables, attribute tables, palettes, sprites, etc, I'm wondering, where on an ROM/cartridge is all this stuff located? Now, I know the generic answer would be: "in the CHR memory banks", but here's the problem: How do I figure out which thing to find where?
The CHR banks are mapped to the pattern tables, and the rest (name, attribute, etc.) have absolutely nothing to do with the CHR banks in the ROM file.
Where are the pattern tables located? Where are the name tables located? The PPU seems to have access to 16KB memory, which mostly contains graphics-related stuff, but I don't know how to find the location/memory area of these things.
All of these are visible in the PPU addressing space. If you look at the CPU memory map, you'll see that certain ranges of it are mapped to different things ($0000-$07FF is RAM, $8000-$FFFF is ROM, etc.), the PPU memory map (look it up in the wiki) is similarly divided into palettes, pattern, name and attribute tables. Only the pattern tables are "ready to use" on power up (only if the cart uses CHR-ROM, though!), everything else must be initialized by the program itself, because it's all RAM.
What confuses me is that games don't have a fixed amount of CHR banks, and some have none at all.
None at means that the cart uses CHR-RAM. In this case, the pattern tables are "empty" on power up and the game program itself takes care of filling it with tiles.
Imagine if a game has only 1 CHR memory bank of 8KB, that wouldn't fit all these things, would it?
Depends on the game. Lots of early games (SMB1 included) make do with just those 512 tiles.
And what if a game doesn't have any CHR banks? How do I figure out where all the tables/palettes are located?
You don't have to figure out anything, that's up to the game program. It will take care of putting everything where it needs to be. All you have to do is render the frame according to the rules of the PPU. For rudimentary PPU support, you can once per frame (like, at the end of VBlank) read it all and generate a picture: use the scroll values to know what part of the name tables to use, then get the tiles indicated there, apply the attribute bits from the attribute tables and look up the final colors in the palettes. After that, you can read the OAM and overlay sprites. This will get the simplest games working, but to actually simulate a NES you'll have to run the PPU in parallel with the CPU (vs. rendering the whole frame at once).
Alright, I get most of what you're saying, but here's the thing:

I've currently only gotten the CPU to work, so the actual interaction between the CPU and PPU isn't there in any way. This is the thing I don't get: the PPU memory map shows the from $2000 to $2400, name table 0 and attribute table 0 can be found. Where is this $2000 to $2400? As far as I was concerned, the PPU only had 2KB internal memory. This #$400 of space is on the cartridge, right? So when I instruct the PPU to get name table 0 from $2000 in the emulated memory space, how would I let my program "know" where this $2000 starts? As an emulated memory space I'd have an array of bytes of size #$4000 or so (off the top of my head), but nothing is ever written to memory address $2000 and beyond. I only know that I can extract an 8KB pattern table from the CHR bank of the ROM and push it into memory, but other than that I know nothing.

Sorry for the confusion and possibly stupid questions. I started a couple of months ago with absolutely 0 knowledge of processors, graphical processing units and memory management of any kind. This is all a bat to the face for me (:

tepples
Posts: 22278
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Where are graphics located on NES roms?

Post by tepples » Fri Jul 19, 2013 1:15 pm

Just in case you may have missed something: The CPU communicates with the PPU by reading and writing ports mapped at CPU $2000-$2007. This is a separate area of memory from PPU $2000-$2007, which refers to the first eight bytes of the first nametable.

You'll want to read through PPU memory map on the wiki.

Nametables sit at $2000-$2FFF in PPU address space. There is enough address space for four nametables, each 1 KiB ($400 bytes) in size, but CIRAM (the video memory in the NES Control Deck) can hold only two. It brings CIRAM A10 out to the cart edge, and the Game Pak PCB usually connects it to PPU A10 or PPU A11.
  • If CIRAM A10 = PPU A11, then CIRAM $000-$3FF is mapped to $2000-$23FF and $2400-$27FF, and CIRAM $400-$7FF is mapped to PPU $2800-$2BFF and $2C00-$2FFF. This produces vertical arrangement or horizontal mirroring and is used by Ice Climber.
  • If CIRAM A10 = PPU A10, then CIRAM $000-$3FF is mapped to $2000-$23FF and $2800-$2BFF, and CIRAM $400-$7FF is mapped to PPU $2400-$27FF and $2C00-$2FFF. This produces horizontal arrangement or vertical mirroring and is used by Super Mario Bros.
  • Some mappers, or support chips on the Game Pak PCB, allow CIRAM A10 to be turned on or off. When it's turned off, CIRAM $000-$3FF is mapped to all four nametables; when it's turned on, CIRAM $400-$7FF is mapped to all four nametables. This produces one-screen mirroring and is most commonly seen in games developed by Rare.
  • Some mappers have switchable mirroring, which allows the program to choose from some all of the above methods.
Which mirroring type is used depends on in which directions a game scrolls, how far, and whether the game includes a status bar.

User avatar
tokumaru
Posts: 11991
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Where are graphics located on NES roms?

Post by tokumaru » Fri Jul 19, 2013 2:01 pm

ArsonIzer wrote:This #$400 of space is on the cartridge, right?
No. The only part of the PPU memory that's in the cart are the pattern tables. Some carts also have name table memory in them (the ones that use 4-screen "mirroring"), but the vast majority don't.
So when I instruct the PPU to get name table 0 from $2000 in the emulated memory space, how would I let my program "know" where this $2000 starts? As an emulated memory space I'd have an array of bytes of size #$4000 or so (off the top of my head), but nothing is ever written to memory address $2000 and beyond. I only know that I can extract an 8KB pattern table from the CHR bank of the ROM and push it into memory, but other than that I know nothing.
First, I want to be sure that you know that there are 2 separate addressing spaces, one for the CPU and one for the PPU. This means that "LDA $2000" will try to load a value from address $2000 in the CPU address space, and not from the name tables. The program can only access VRAM (the memory used by the PPU) through the registers mapped at $2006/$2007, like tepples said.

Once you understand that, you have to study the PPU memory map to see how the VRAM (2KB of memory that are inside the NES + pattern tables) are mapped to the PPU addressing space. The pattern tables will always be at $0000-$1FFF, the name tables will always be at $2000-$2FFF, and so on. You don't have to "guess" where things are, they'll always be at the same places. These things are not static, you won't be loading them from somewhere and be done with them, the games will be constantly modifying VRAM in order to animate things on screen.

Think of it this way: is your emulator specifically worrying about where in RAM to put the variable that indicates how many lives the player has? It isn't, because the game program is the one that has to worry about that. It doesn't matter if it puts the number of remaining lives in $0020, $0125 or $05A0, the game engine will deal with that, as long as you have RAM mapped at $0000-$07FF. Graphics are the same: you don't have to worry about where the tile with the player's arm is. The game itself will make sure that the tile is in the correct place in the attribute tables. As long as you implement the PPu memory map, the game will take care of accessing it and storing everything in the correct places. The only exception is CHR-ROM, that you'll have to map yourself according to the rules of the mapper. Please start simple and use something with 8KB or CHR-ROM (no CHR bankswitching), so that you can easily map it to $0000-$1FFF. You can deal with more complex CHR mapping later.

ArsonIzer
Posts: 115
Joined: Fri Jul 19, 2013 11:38 am

Re: Where are graphics located on NES roms?

Post by ArsonIzer » Fri Jul 19, 2013 2:11 pm

tokumaru wrote:
ArsonIzer wrote:This #$400 of space is on the cartridge, right?
No. The only part of the PPU memory that's in the cart are the pattern tables. Some carts also have name table memory in them (the ones that use 4-screen "mirroring"), but the vast majority don't.
So when I instruct the PPU to get name table 0 from $2000 in the emulated memory space, how would I let my program "know" where this $2000 starts? As an emulated memory space I'd have an array of bytes of size #$4000 or so (off the top of my head), but nothing is ever written to memory address $2000 and beyond. I only know that I can extract an 8KB pattern table from the CHR bank of the ROM and push it into memory, but other than that I know nothing.
First, I want to be sure that you know that there are 2 separate addressing spaces, one for the CPU and one for the PPU. This means that "LDA $2000" will try to load a value from address $2000 in the CPU address space, and not from the name tables. The program can only access VRAM (the memory used by the PPU) through the registers mapped at $2006/$2007, like tepples said.

Once you understand that, you have to study the PPU memory map to see how the VRAM (2KB of memory that are inside the NES + pattern tables) are mapped to the PPU addressing space. The pattern tables will always be at $0000-$1FFF, the name tables will always be at $2000-$2FFF, and so on. You don't have to "guess" where things are, they'll always be at the same places. These things are not static, you won't be loading them from somewhere and be done with them, the games will be constantly modifying VRAM in order to animate things on screen.

Think of it this way: is your emulator specifically worrying about where in RAM to put the variable that indicates how many lives the player has? It isn't, because the game program is the one that has to worry about that. It doesn't matter if it puts the number of remaining lives in $0020, $0125 or $05A0, the game engine will deal with that, as long as you have RAM mapped at $0000-$07FF. Graphics are the same: you don't have to worry about where the tile with the player's arm is. The game itself will make sure that the tile is in the correct place in the attribute tables. As long as you implement the PPu memory map, the game will take care of accessing it and storing everything in the correct places. The only exception is CHR-ROM, that you'll have to map yourself according to the rules of the mapper. Please start simple and use something with 8KB or CHR-ROM (no CHR bankswitching), so that you can easily map it to $0000-$1FFF. You can deal with more complex CHR mapping later.
I see. The part I wasn't really getting was HOW exactly the tables are written to the VRAM. Is it the game itself? Does the game do it through the CPU, or can it directly write to the PPU? But I'm a lot closer to getting this answer now, and I'll discover as I go along writing my emulator (just like I did with the 6502). Thanks a lot guys, this has helped immensely!

User avatar
tokumaru
Posts: 11991
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Where are graphics located on NES roms?

Post by tokumaru » Fri Jul 19, 2013 3:34 pm

ArsonIzer wrote:The part I wasn't really getting was HOW exactly the tables are written to the VRAM. Is it the game itself?
Yes. Everything but CHR-ROM (which you have to put in $0000-$1FFF yourself) is put in VRAM by the game itself. Where the data actually comes from doesn't matter at all... the game is free to do all kinds of processing on the data before uploading it to VRAM, but this is a problem for the game's engine, not you.
Does the game do it through the CPU, or can it directly write to the PPU?
Like we've pointed out already, the program doesn't have direct access to VRAM, the CPU and the PPU have their individual addressing spaces, completely independent of each other. The CPU/game can only communicate with the PPU through the registers mapped at $2000-$2007. To write data to VRAM, the program has to go like "Hey PPU, please point to address $2400 of VRAM for me, and then store #45 in this location, please". The CPU has to "ask" the PPU to load/store data from/to VRAM, it can't go barging in and access the memory itself. Read more about the PPU registers in the wiki and you'll eventually get it.

What you have to do now is implement the PPU's memory map, just like you have done for the CPU. Once the memory is there and the game has access to it through the PPU ports, you can go about implementing a rendering system, which will use the data from VRAM to generate a picture. Like I said, at this early stage, it would be better if you rendered the whole picture at once, so you can better understand how everything comes together to form an image. However, that's not how the NES works... the PPU and CPU run in parallel, and at the same time the game is running in the CPU, the PPU is rendering the picture. It's important to emulate them running side by side because games can make changes to PPU registers and to VRAM in the middle of the frame, and these changes affect how the picture looks. If you keep rendering a whole picture at once, you won't catch these changes. But don't worry about that now.

BTW, when I say "VRAM" I mean the PPU memory, even though some of it is not RAM if the cart uses CHR-ROM. So, by "VRAM" I basically mean pattern tables + name tables + attribute tables + palettes. Sprites are not included in that pack, since OAM is not mapped to the same addressing space. The OAM has its own 256-byte addressing space, which can be accessed through registers $2003/$2004 (although that method of access has been recently found to be buggy, and should be avoided in favor of OAM DMA, which 100% of the commercial games use), much like VRAM is accessed through $2006/$2007.

ArsonIzer
Posts: 115
Joined: Fri Jul 19, 2013 11:38 am

Re: Where are graphics located on NES roms?

Post by ArsonIzer » Fri Jul 19, 2013 4:17 pm

tokumaru wrote:
ArsonIzer wrote:The part I wasn't really getting was HOW exactly the tables are written to the VRAM. Is it the game itself?
Yes. Everything but CHR-ROM (which you have to put in $0000-$1FFF yourself) is put in VRAM by the game itself. Where the data actually comes from doesn't matter at all... the game is free to do all kinds of processing on the data before uploading it to VRAM, but this is a problem for the game's engine, not you.
Does the game do it through the CPU, or can it directly write to the PPU?
Like we've pointed out already, the program doesn't have direct access to VRAM, the CPU and the PPU have their individual addressing spaces, completely independent of each other. The CPU/game can only communicate with the PPU through the registers mapped at $2000-$2007. To write data to VRAM, the program has to go like "Hey PPU, please point to address $2400 of VRAM for me, and then store #45 in this location, please". The CPU has to "ask" the PPU to load/store data from/to VRAM, it can't go barging in and access the memory itself. Read more about the PPU registers in the wiki and you'll eventually get it.

What you have to do now is implement the PPU's memory map, just like you have done for the CPU. Once the memory is there and the game has access to it through the PPU ports, you can go about implementing a rendering system, which will use the data from VRAM to generate a picture. Like I said, at this early stage, it would be better if you rendered the whole picture at once, so you can better understand how everything comes together to form an image. However, that's not how the NES works... the PPU and CPU run in parallel, and at the same time the game is running in the CPU, the PPU is rendering the picture. It's important to emulate them running side by side because games can make changes to PPU registers and to VRAM in the middle of the frame, and these changes affect how the picture looks. If you keep rendering a whole picture at once, you won't catch these changes. But don't worry about that now.

BTW, when I say "VRAM" I mean the PPU memory, even though some of it is not RAM if the cart uses CHR-ROM. So, by "VRAM" I basically mean pattern tables + name tables + attribute tables + palettes. Sprites are not included in that pack, since OAM is not mapped to the same addressing space. The OAM has its own 256-byte addressing space, which can be accessed through registers $2003/$2004 (although that method of access has been recently found to be buggy, and should be avoided in favor of OAM DMA, which 100% of the commercial games use), much like VRAM is accessed through $2006/$2007.
I did not expect an answer back, but I'm glad I got one, because things are a LOT clearer because of it. Pieces are coming together rapidly, and I'm sure I won't have a lot of trouble implementing the PPU now. I tip my hat off to you, thank you very much for your patience.

I hope that one day I'll be telling this stuff to the newbies, sitting behind my PC knowing how easy it all actually is.

Thanks again!

User avatar
Dartht33bagger
Posts: 59
Joined: Sat Jan 03, 2009 3:28 pm
Location: Oregon
Contact:

Re: Where are graphics located on NES roms?

Post by Dartht33bagger » Mon Aug 05, 2013 9:14 pm

After reading this post I still have a few questions:

1. So I only need to load the pattern tables from CHR-ROM and the rest of the tables will be filled up by the program code (I assume by writing values to $2006?)? I'm still a bit fuzzy on how the attribute and nametables are filled.
2. Where exactly is the CHR data located inside of the ROM file? I know that PRG data starts after the iNes header, but what address does the CHR data start and end at?
3. How do I go about rendering one image at a time instead of running the PPU in parallel with the CPU? Do I just run the CPU until enough cycles have passed for one frame to be drawn and then have the PPU draw the frame from the data in VRAM at that moment? Won't the PPU miss changes to it's registers since it will only be checking them once per frame?

lidnariq
Posts: 10238
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Where are graphics located on NES roms?

Post by lidnariq » Mon Aug 05, 2013 9:24 pm

Dartht33bagger wrote:1. So I only need to load the pattern tables from CHR-ROM
Assuming the game only has 8 KiB CHR-ROM, yes. Get that working first before you worry about the exceptions.
and the rest of the tables will be filled up by the program code (I assume by writing values to $2006?)? I'm still a bit fuzzy on how the attribute and nametables are filled.
The program in PRG writes specific values to $2006 and $2007
2. Where exactly is the CHR data located inside of the ROM file? I know that PRG data starts after the iNes header, but what address does the CHR data start and end at?
Specifically in the case of iNES or NES2.0: CHR starts at 16+16384*PRGSIZE and is 8192*CHRSIZE long.
3. How do I go about rendering one image at a time instead of running the PPU in parallel with the CPU?
There are a whole slew of sophisticated techniques to manage this (Catch-up, prediction, rewinding). Given that you sound like you're on really shaky footing right now, though, I'd strongly recommend doing the simplest thing that could possibly work, and just rendering 3·N pixels to the pixel buffer after each CPU instruction completes (that took N cycles)
Do I just run the CPU until enough cycles have passed for one frame to be drawn and then have the PPU draw the frame from the data in VRAM at that moment?
That will only work on the simplest of games.
Won't the PPU miss changes to it's registers since it will only be checking them once per frame?
Also, the PPU will change some things during rendering, and if you emulate that way, the CPU won't notice.

Post Reply