It is currently Tue Aug 22, 2017 9:56 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Sun Aug 20, 2017 11:08 pm 
Offline

Joined: Tue Apr 25, 2017 1:10 pm
Posts: 4
Hi guys,

I have a fully working and tested 6502 CPU working. Now I'd like to move on to the PPU. I've read the references on this site as well as many others. However, many of them seem extremely complex and go into detail about various features that dissuade me from even trying to make a working PPU. Therefore, I was wondering what the steps to making a basic PPU would be? I've already read in the CHR ROM data and set up the basic registers. My short term goal would be to simply get the start screen of super mario bros showing up. After that, I'd like to get super mario bros working completely. Only then do i want to worry about the complex potential features that would allow any game to work.

Thanks!


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 2:08 am 
Offline

Joined: Tue Oct 06, 2015 10:16 am
Posts: 496
Mario uses many of the complex features, so targeting it as the first game wouldn't save much.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 4:22 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9910
Location: Rio de Janeiro - Brazil
The simplest thing you can do to get games to display something is to first implement the PPU registers ($2000-$2007) to make sure that the basic settings work (pattern table addresses, sprite size, NMI generation, scroll, etc.) and that VRAM can be written to and read from. Then, you can create a simple function to draw a full frame at once, and call it 60 times per second, without bothering with CPUxPPU synchronization or with the exact processes the PPU uses to render pictures. You can do it at a higher level, gathering data from the pattern, name and attribute tables, OAM and palette RAM, and render a full frame. This should be enough to run simpler games, mainly those that don't use raster effects. More complex games might work to some extent, depending on when in the frame you sample the PPU data/settings for rendering.

Then you can start to implement the actual PPU behavior, making it run alongside the CPU and respect the real duration and order of all memory accesses and other processes (such as sprite evaluation). Depending on the level of accuracy (or performance) you're going for, you may get away with doing things 1 scanline at a time, rather than 1 pixel at a time.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 6:27 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 18833
Location: NE Indiana, USA (NTSC)
I agree with calima: Don't use Super Mario Bros. for initial testing, as it uses too much of the PPU's capability. Use something simpler, such as Concentration Room.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 4:27 pm 
Offline

Joined: Tue Apr 25, 2017 1:10 pm
Posts: 4
Thanks everyone! I very much appreciate the replies and advice.

tokumaru wrote:
The simplest thing you can do to get games to display something is to first implement the PPU registers ($2000-$2007) to make sure that the basic settings work (pattern table addresses, sprite size, NMI generation, scroll, etc.) and that VRAM can be written to and read from. Then, you can create a simple function to draw a full frame at once, and call it 60 times per second, without bothering with CPUxPPU synchronization or with the exact processes the PPU uses to render pictures. You can do it at a higher level, gathering data from the pattern, name and attribute tables, OAM and palette RAM, and render a full frame. This should be enough to run simpler games, mainly those that don't use raster effects. More complex games might work to some extent, depending on when in the frame you sample the PPU data/settings for rendering.

Then you can start to implement the actual PPU behavior, making it run alongside the CPU and respect the real duration and order of all memory accesses and other processes (such as sprite evaluation). Depending on the level of accuracy (or performance) you're going for, you may get away with doing things 1 scanline at a time, rather than 1 pixel at a time.


This really helps! I still am a little confused on the basic memory layout. What exactly is stored in the ROM vs the VRAM? Where is the code that controls what happens with the graphics? Is it all CPU code and are all the sprites etc controlled through writes to 2000-2008 or is it like the CPU where the PPU has its own instruction set that I read from the ROM?

At a high level I understand what OAM, and tiles etc are but i'm kind of confused how they all fit in together and what code is responsible for moving the Mario sprite up when it jumps.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 5:17 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 18833
Location: NE Indiana, USA (NTSC)
On the NES PPU:
$0000-$1FFF contains pattern tables, which define what each tile looks like. Each of the 512 tiles accessible at any given moment is 16 bytes in size.
$2000-$2FFF contains nametables, which define which tiles to use for each part of the background.

On most cartridges:
$0000-$1FFF is ROM or RAM in the cartridge.
$2000-$2FFF is RAM in the Control Deck. Only two of the four 1 KiB ($400 byte) regions are distinct; the other two are "mirrors", or the same piece of memory appearing at different parts of address space.

In either case, if it is RAM, the CPU copies data into RAM using $2006 and $2007 before displaying anything.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 5:38 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 701
Location: Sweden
If you by ROM means the PRG-ROM on the cartridge, it's where all the program code executed by the CPU is. CHR-ROM (also on the cartridge) is best viewed as part of VRAM. And if the cartridge has CHR-RAM it's writeable VRAM by the program, but from the PPUs perspective it's still just part of VRAM.

VRAM holds nametables (scrollable background screen data), pattern tables (the shape definitions for background characters and sprites) and palettes. The pattern tables are in the CHR-ROM/CHR-RAM that comes with the cartridge (although this doesn't make a difference for the PPU).
Sprites attributes are in OAM which is a separate memory from VRAM but it has a similar purpose, just only for sprite attributes.

What makes Mario go up? The program code runs and notices that the player presses the jump button, it processes all the necessary logic to jump and finally writes whatever changed on Mario's sprite to the OAM when the next vblank happens (usually via OAM-DMA). The PPU uses the information currently in OAM and VRAM to draw the screen every frame. There's also a bunch of internal memories and registers in the PPU that I don't know much about (I mostly only knows about things that a NES programmer needs to know). But you might not need to implement everything accurately right away, just get basic VRAM and OAM content to appear on screen.


Top
 Profile  
 
PostPosted: Mon Aug 21, 2017 5:40 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9910
Location: Rio de Janeiro - Brazil
nuker wrote:
I still am a little confused on the basic memory layout. What exactly is stored in the ROM vs the VRAM?

The video memory is separate from CPU memory and has the following layout (copied from the wiki):

$0000-$0FFF: Pattern table 0
$1000-$1FFF: Pattern Table 1
$2000-$23FF: Nametable 0
$2400-$27FF: Nametable 1
$2800-$2BFF: Nametable 2
$2C00-$2FFF: Nametable 3
$3000-$3EFF: Mirrors of $2000-$2EFF
$3F00-$3F1F: Palette RAM indexes
$3F20-$3FFF: Mirrors of $3F00-$3F1F

The pattern tables and the name tables can be RAM or ROM (defined by the cartridge), but ROM name tables are very rare (maybe only 1 or 2 games have them).

Quote:
Where is the code that controls what happens with the graphics? Is it all CPU code and are all the sprites etc controlled through writes to 2000-2008

This. The game code running in the CPU sets up all the backgrounds, sprites and various PPU configurations through the PPU registers. The PPU does perform a hardcoded sequence of operations by itself that involves reading data from all the tables in order to generate images, and this is the complicated part.

Quote:
At a high level I understand what OAM, and tiles etc are but i'm kind of confused how they all fit in together and what code is responsible for moving the Mario sprite up when it jumps.

The OAM is basically a list indicating where on the screen each sprite must be rendered, what tiles they use, and a few other parameters (palette, flipping, priority). This information is calculated by the game code and uploaded to the PPU via OAM DMA. When emulating the PPU, all you have to do is interpret this data as documented and draw all the sprites in the correct positions.

When the PPU draws sprites, it performs an operation called "sprite evaluation". Every scanline, it goes through the OAM comparing the current scanline number against the Y coordinates of each OAM entry, to detect whether they're in range or not. For each entry, it calculates Scanline - SpriteY, and when the result is smaller than the sprite height (8 or 16 pixels, as selected through register $2000), that means the sprite is in range, and that's the index of the sprite line to draw. The information about the sprite is then copied to secondary OAM (there's enough space and time to do this for 8 sprites at most), and when the scanline ends, the graphics are copied from the pattern tables so they can be drawn on the next scanline.

If you're shooting for accuracy, you have to research each of these steps very well, to make sure everything happens the same way and at the same time as in a real PPU. But if accuracy is not a priority, you can do what I said before and high-level all of this: just scan all 64 OAM entries and draw the 64 sprites at once at the specified positions. It should work for most games, but there are a few that manipulate rendering parameters mid-frame that will require you to respect the actual timing of the PPU.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Yahoo [Bot] and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group