Posted on Mar 17th, 2011 at 2:57 PM by Eric Wright
Welcome to my intro on NES development. In this multi-part post, we will look at different aspects of the home-brew NES development process.
  • Setting up an NES development environment, planning your NES ROM, and assembling your NES ROM
  • Creating an NROM development cart by re-purposing an actual game cartridge (or for a ROM swap)
  • Creating a new development cart capable of running NROM, UROM, CNROM, and AROM using new parts from RetroUSB
  • Programming (E)EPROM, Flash, or PROM chips for use with development cartridges (or ROM swaps)
What we need (and what I suggest)
Alright, now that we have that out of the way, lets get started with our Development environment. I will be showing you how I personally setup my NES Development environment for a Windows XP machine.
  • NESASM 6502 Assembler - There are other options for an assembler, many people dislike NESASM due to its lack of features and a few small bugs. NESASM is easy to use for beginners. NESASM is currently part of MagicKit. Another popular assembler option is CA65, but I am not going to go in to setting up CA65 at this time.
  • YY-CHR Tile Editor - Older versions of YY-CHR contained code that was similar to a Trojan signature. The newest version, 0.99, does not. YY-CHR is a versatile tile editor capable of editing not only NES tiles, but a handful of other console tiles as well.
  • NNNesterJ NES Emulator - I prefer to use NNNesterJ for debugging and testing because of the memory map viewer. You may want to expirement with various emulators until you find one you are comfortable using. Please keep in mind, no emulator Is perfect and just because a ROM runs on an emulator, IT DOES NOT MEAN IT WILL RUN ON AN ACTUAL NES
  • Notepad++ - Notepad++ is an excellent text editor, it features syntax highlighting and a tabbed view. It is very flexable and will come in very handy during your NES development.
Lets get things rolling
Now that you have downloaded everything that we will be needing, it is time to start setting up the development environment. Lets start by creating our director structure. I like to create an NES folder in the root directory on my "C" drive with the following folders:
  • C:\
    • nes
      • bin      - This will house ALL the binary files for YY-CHR, NNNesterJ, and NESASM
      • src      - This is where we will put our source files and other info for our NES ROM
      • doc      - Sometimes it comes in handy to have a reference or two
  • Extracting YY-CHR
    Open the YY-CHR archive and extract everything inside of the YYCHR99 folder to c:\nes\bin. Open an explorer window and navigate to c:\nes\bin and rename yychr.ENG to yychr.ENU (if you dont live in the United States, see yychr_language for other instructions). If you do not follow this step, YY-CHR's interface will not be in English and you may have a hard time reading things.
  • Extracting NNNesterJ
    Extract all three files in the NNNesterJ archive to c:\nes\bin. We dont need to do anything special for NNNesterJ to work.
  • Extracting NESASM
    NESASM is now part of MagicKit, a PCEngine development kit. Open the MagicKit archive and navigate to the BIN subfolder. Copy NESASM.EXE to c:\nes\bin. Go up one level and open the DOC folder. Copy the NES documents to c:\nes\doc for future reference (if needee).
  • Quick directory check
    At this point in time, your c:\nes\bin directory should have the following files:
    • lang_eng.dll
    • nesasm.exe
    • nnnesterj.exe
    • plugins (directory)
    • screen.bmp
    • yychr.adf
    • yychr.chr
    • yychr.col
    • yychr.dat
    • yychr.enu
    • yychr.exe
    • yychr.ini
    • yychr.pal
    • yychr.txt
    • yychr_history.txt
    • yychr_j.txt
    • yychr_language.txt
  • Install Notepad++
    There is nothing special about installing notepad++, just open the executable installer and follow the on-screen instructions
  • Setting environment variables:
    I suggest adding c:\nes\bin to the path environment variable, this will allow you to type just "nesasm" rather than "c:\nes\bin\nesasm" every time you attempt to assemble your rom from the command line. It is much easier and will save time.
    1. Click the "Windows" Start menu.
    2. Right-Click on "My Computer" and select "Properties" from the popup menu.
    3. Select the "Advanced" tab from the top of the "System Properties" window.
    4. Click the "Environment Variables" button
    5. Under the "System Variables" section, find and select "Path". Click the "Edit" button.
    6. Add ";c:\nes\bin\", without the quotes, to the end of the "Variable Value" string and click "OK". Mine shows as the following "%SystemRoot%\system32;%SystemRoot%;c:\nes\bin\".
    7. Close out of all the "system properties" windows and restart your computer for the new path variable to take effect.
A Quick architecture refresher
The heart of the NES is a modified 6502 CPU. Certain features (Decimal mode for example) have been removed while others (Joypad strobe, APU) have been added. The 6502 processor used in the NES has a 16/8 bit bus, that is, the address bus is 16bits wide while the data bus is only 8bits wide. The NES contains 2kb of RAM mapped to $0000-$0800 in the memory map. The NES also contains a PPU with its own bus for video purposes, the PPU's address bus is 16bits wide (8 of the address bus bits are set via a latch and signal line due to a limited number of pins on the chip and are shared with the data bus) . The PPU also has an 8bit data bus. The PPU contains 2kb of onboard RAM background (NAM) storage. Additional PPU ram can be added on the game cartridge to to store more NAM information. There are also two controller ports for various input on the NES, these are controlled via registers $4016 and $4017.
CPU Memory Map:
  • $0000 - $0800 - RAM
    • $0000 - $00FF
      Zero Page - this area of RAM is used for quick storage and has special instructions to access this range in a faster manor than the rest of the memory map.
    • $0100 - $01FF
      Processor Stack - Each time a sub-routine is called, the processor writes the return address to the stack so that it can return to where it branched from once the sub-routine has completed. The stack can also be used for various trucks to use one routine with multiple sets of data.
  • $2000 - $2007 - PPU Registers
    • $2000
      PPUCTRL - Controls NMI enable, sprite sizes, NAM/sprite tile addresses, and NAM table address
    • $2001
      PPUMASK - Controls color intensity, NAM/sprite enable, NAM/sprite clipping on left side of screen, and Gray-scale/color enable.
    • $2002
      PPUSTATUS - Returns various information about the PPU such as Vblank status, sprite overflow, and sprite 0 hit.
    • $2003
      OAMADDR - This register chooses the OAM (sprite) address to read or write using OAMDATA ($2004), this value ranges from $00 - $FF
    • $2004
      OAMDATA - This register will write to or read from the address choosen via OAMADDR ($2003). Reads/Writes to this register will increment OAMADDR under most conditions.
    • $2005
      PPUSCROLL - This register controls the NAM scroll offset, the first write controls the horizontal offset, the second write controls the vertical offset.
    • $2006
      PPUADDR - This register chooses the VRAM address to read/write to and consists of two writes. The first write is the high byte of the VRAM address, while the second is the LOW byte.
    • $2007
      PPUDATA - This register reads from or writes to the address choosen via PPUADDR ($2006). Reads/Writes to this register will increment the PPUADDR by either 1 or 32, depending on how PPUCTRL ($2000) is set.
  • $4000 - $4017 - CPU Registers (Sound / Controller)
    • $4000 - $4013
      Sound related registers, I am going to skip these for now and come back to them later
    • $4014
      OAMDMA - Writing to this register will copy 256 bytes from $XX00 to the start address choosen via OAMADDR($2003). (where XX is the value written to $4014). This register is typically used during Vblank for major Sprite (OAM) updates.
    • $4015
      SNDCHN - Sound status/selection
    • $4016
      JOY1 - Reads from joypad 1 one button at a time or reset joypad latch when written to (strobbed). Strobbing this line will reset both joypad latches.
    • $4017
      JOY2 - Reads from joypad 2 one button at a time.
PPU Memory Map:
  • $0000 - $0FFF
    Pattern Table 0, on cartridge. Can be RAM or ROM. Contains 256 8x8 pixel tiles (16 cols x 16 rows)
  • $1000 - $1FFF
    Pattern Table 1, on cartridge. Can be RAM or ROM. Contains 256 8x8 pixel tiles (16 cols x 16 rows)
  • $2000 - $23BF
    NAM Table 0, 32 x 30 tile grid (256x240 pixel picture). References Pattern Table tiles.
  • $23C0 - $23FF
    NAM Table 0 Attributes. Each byte references a palette entry for 4 blocks of 4 tiles each (4 tiles wide, 4 tiles tall).
  • $2400 - $27BF
    NAM Table 1, 32 x 30 tile grid (256x240 pixel picture). References Pattern Table tiles.
  • $27C0 - $27FF
    NAM Table 1 Attributes. Each byte references a palette entry for 4 blocks of 4 tiles each (4 tiles wide, 4 tiles tall).
  • $2800 - $2BBF
    NAM Table 2, 32 x 30 tile grid (256x240 pixel picture). References Pattern Table tiles.
  • $2BC0 - $2BFF
    NAM Table 2 Attributes. Each byte references a palette entry for 4 blocks of 4 tiles each (4 tiles wide, 4 tiles tall).
  • $2C00 - $2FBF
    NAM Table 3, 32 x 30 tile grid (256x240 pixel picture). References Pattern Table tiles.
  • $2FC0 - $2FFF
    NAM Table 3 Attributes. Each byte references a palette entry for 4 blocks of 4 tiles each (4 tiles wide, 4 tiles tall).
  • $3F00 - $3F0F
    NAM Palette, organized as 4 sets of 4 bytes. $3F00, $3F04, $3F08, and $3F0C of the NAM palette and $3F10, $3F14, $3F18, and $3F1C of the Sprite palette are mirrored as the background color. The three remaining bytes of each set can be any combination.
  • $3F10 - $3F1F
    Sprite Palette, organized as 4 sets of 4 bytes. $3F00, $3F04, $3F08, and $3F0C of the NAM palette and $3F10, $3F14, $3F18, and $3F1C of the Sprite palette are mirrored as the background color. The three remaining bytes of each set can be any combination.
A few more PPU things you should know
The NES has a screen resolution of 256x240 pixels comprised of 8x8 pixel "tiles". This leaves us with a grid of 32columns by 30 rows that make up the NAM table. The NAM table data is mapped out in a Linear fashion. For example, for NAM table 0, row 0 is stored in $2000-$201F, row 1 is stored in $2020-$203F, etc. The NES has enough VRAM on-board to hold the contents of two NAM tables and can be arranged in several ways using the horizontal and vertical mirroring options. The other two NAM table addresses will mirror these two NAM tables. Four NAM tables can be used with on-cart VRAM.

Each NAM table corresponds to an Attribute table that tells the PPU what color set to use when rendering. This table is made up of 40 bytes in which every 8 bytes represents the color data for 4 rows on the NAM table. The following 8 bytes represent another 4 rows located under the first set. Each of these bytes represents a group of 16 tiles divided up in to 4 blocks of 4 tiles as shown in the image below. One of four NAM palette sets can be choosen for each of these 4 tile blocks. The images below show not only how each byte represents color for each of the four blocks, but also how each group of 8 bytes are arranged.


Speaking of palettes, the PPU stores the palette choices in the VRAM memory at locations $3F00 thru $3F1F. These memory locations are divided in to two groups of four sets each. the first group belongs to the NAM (background) and the second to the OAM (sprites). Each set is made up of 4 bytes representing 4 color choices for that set. The 1st byte in each color set is mirrored to $3F00, this is the background color and allows us to do some neat tricks. Depending on if a sprite is behind or infront of the background, this color can act as being transparent. Below is a diagram of the palette memory locations and a PPU color chart.


What to expect for Part 2 and beyond
We will be planning and coding a demo ROM for the NES during Part 2, This will be a "digital" alarm clock that will keep time based off of the PPU's 60hz vblank interrupt (NMI interrupt). In part 3, we will be re-purposing an NROM cart to be used as a develpment cart and testing our Alarm clock on an actual NES.

Intro to NES Development Series
  

Comments:

There are currently no comments to display.
Site
Categories
Some Ads
© 2013 Eric Wright. SiteMap