You are visitor to this page since July 29,1997
Lately a wealth of information has been released on various 1980s classic console systems. This comes as a result of the advent of Emulation software capable of running ROM images from the cartridges of those systems. Thus far there have been "Home-Brewed Games" released for some of the oldest platforms such as the Atari 2600 and Colecovision generation of machines and some code demos for the SNES (Super Nintendo Entertainment System) that was released by Nintendo in 1991. However, there have been no such games, demos, or even small source code examples released as of yet to aid developers with the creation of brand new ROMS for use with the most popular machine of the mid to late 1980s, the Nintendo Entertainment System (NES) which was the first generation 8-bit machine released by Nintendo of America in 1985. This machine made extraordinary advances beyond the capabilities of previous machines. The biggest change in home video gaming in the 1980s occured due to the release of this system. Its memory capabilities allowed games with complex worlds that could be explored for hours. The goal of a typical video game changed from attaining a high score to attempting to "beat a game" or explore the worlds until you reach the final goal.
My hope is that this page will allow developers, hackers, and even those beginners who are interested to easily find the information they need to write code and create ROMS from scratch for use with Nintendo emulation software such as Bloodlust's Nesticle.
Please remember that a great deal of effort went into getting this information together and writing the source code below. I would like to thank "Yoshi" (Jeremy Chadwick) for his efforts in creating excellent documentation of the technical aspects of the NES. Without his work, none of this would have been possible. I would also like to thank Marat for some information he gave me pertaining to the sound registers that helped me with my efforts.
This page has some information on the things I did step by step to accomplish the eventual development of the first non-commercial NES ROM and some details on the NES and the 6502. It must be realized that this is only a demo and the program itself is absolutely meaningless, but the point of distributing this ROM is to show that it is possible to create new "home-brewn" NES software to give new life to the Nintendo Entertainment System through it's emulation. Remember that I do not expect you to evaluate this ROM because I know it is of extremely poor quality :). What I do expect is for you to see that it is possible to program the NES.
For further information (this page will not help you without seeking more detailed information) see Yoshi's technical document and the 6502 programming info at Yoshi's NES development page
* IMPORTANT : Yoshi's page contains
all the documentation that I mention below.*
For further help or feedback email me at TYoung79@aol.com
The only information that I had available to me to begin researching the NES was Yoshi's document. It took awhile to learn the inner workings of the NES. The first step to creating Nintendo ROMS is to read this document. It does require a great deal of previous knowledge about computers. For those who do not know anything about computers at all, e-mail me or look for some general information on assembly language or microprocessors.
To clarify things a little.. The NES has an 8 bit 6502 cpu which is capable of addressing up to 64K. The address bus addresses things besides just RAM though.. Using the hexadecimal system, the 6502 can directly address the following:
$0000 - $1FFF ----------------------------------------------------------- RAM
$2000 - $7FFF ----------------------------------------------------------- This area contains REGISTERS which accomplish certain NES
functions. The rest of the space is generally not dealt with in
programming.
$8000 - $FFFF ------------------------------------------------------------ NES Program ROM (PRG ROM) where program data is stored
The 6502 processor itself can only address these areas. There are other areas of memory on the NES, but they are not made directly accessible to the 6502's address bus. Instead, these areas are accessed through special registers which are part of the 6502's address space. Reading Yoshi's document shows that $2006 and $2007 are used for writing to PPU RAM and $2003 and $2004 are used to write to SPRITE RAM. The PPU RAM is one of the most critical things that needs to be understood in order to understand the NES. The PPU RAM contains palettes for both sprites and the rest of the image, and three types of tables: PATTERN TABLES, NAME TABLES, and ATTRIBUTE TABLES. The pattern tables can be viewed through Bloodlust's Nesticle through the menu bar at the top under "View - Pattern Tables". The first half corresponds to the first pattern table and the second goes with the second. The pattern tables are data which represent 8x8 graphical blocks in a 4 color palette. The Name Table represents everything that doesn't need to be animated on the screen with blocks from the Pattern Tables. There are actually 2 Name Tables and a copy of each of these two Name Tables within the PPU RAM. In non-scrolling games which take place on one screen, only one Name Table is usually used. The second Name Table is written to in scrolling games and the screen can be scrolled from one Table to the next through one of the registers. The final type of table is the Attribute Table. There is an Attribute table for every Name Table. Remember that the Pattern Tables represent blocks in 4 colors. The Attribute Table designates which 4 color palette to use out of 4 possible palettes in the Image Palette area. The only catch is that the Attribute Table represents blocks of 2x2 which means all blocks in a 2x2 block starting with the top left corner of the name table must use the same palette. For more technical information on the NES, read Yoshi's document.
After reading Yoshi's document, I realized that I needed to learn 6502 assembly. I found a place on one of Yoshi's pages that gave a tutorial on 6502 assembly. If you have never programmed in assembly language and have no idea how a microprocessor works then keep reading. Otherwise you may want to skip ahead.
Basically the 6502 cpu has three primary registers (not to be confused with the type of registers above.. these are on the cpu chip and used exclusively by the cpu) used for data manipulation and other purposes. There are other registers, but they are usually not directly programmed but play an important part in some assembly commands.
The three most important 6502 registers are labeled A, X, and Y. A is the "accumulator" it is used for simple math operations but can only add, subtract, and shift the bits of its contents. X and Y are index registers because they can be used to add an offset to an address value. This is an important feature, but we'll get to this later.
Addresses? What are they? They are locations where things can be stored and accessed OUTSIDE of the cpu itself. An address is a number representing a specific location. When a cpu sends out a number on the "address bus", it can then read from or write values to the RAM, chip, device, or whatever is at that location. Usually addresses are associated with RAM.
Basically there are a limited number of things a CPU can do. It can read a value from an address and store that value in a register (A, X, or Y). It can take a value in a register and write it to an address. Also, there are commands which manipulate the data in registers based on either set numbers or data at a certain address, and there are commands which cause branching based on certain conditions. Branching is basically jumping from one place to another in a program if a certain condition is true.
Now for some examples of 6502 assembly language commands:
LDA #$00
This command loads the number 0 into the A register
LDA $00
This command will load the contents at address 0 into the A register
LDX or LDY can be used for the above
STX $2006 will store the current contents of the X register at the address $2006 ($ means hexidecimal)
LDA $8000, X makes use of the X register as an index register as mentioned earlier.. this adds the current contents of the X register to $8000 to get the actual address to be used.
LDX #$02
LDA $8000,X
The above code will put 2 into the X register then load the contents of the address $8002 into the A register by adding the current X register value to $8000
INX increments (add 1) the X register (INY works too)
DEX and DEY decrement X and Y
BNE label
This command will go to a label in a program if the last command did not result in a zero value. BEQ would only branch is there is a zero value involved. The label is specified by typing the label name with a colon ( : ) after it.
One last Note: ALL Assembly code must be indented no more or less than one column and labels must be completely to the left. Also, code must be edited using a text editor and not a formated word processing program. I use the dos "edit" program.
For more information on 6502 Assembly programming see the 6502 programming document.
Using the technical information in Yoshi's document and 6502 assembly language, I began writing functions that may be useful for programming the NES. The .NES rom format includes a 16-byte header, the program rom information, and then the character rom information (basically the pattern tables). The main program can start anywhere in the PRG ROM area. The only requirement is that the number of the starting address of the main program be put 2 bytes before the end of the PRG ROM area in the form of a 2 byte integer. The least significant byte comes first, followed by the most significant byte. Remember this is in terms of the 6502's address space, so $8000 is the address assigned to the first byte of the PRG ROM in the .NES file. Another important part of the NES code is the NMI code. NMI stands for Non-Maskable Interrupt. This code will be executed every time that the screen redraws. This is handy for timing out certain things and for keeping video functions in sync if necessary although I never needed to do that for my code. The number of the starting address of NMI code must be placed right before the number of the starting address of the main code. Then all that must be done is to assemble the actual program and NMI code and use a hex editor to copy it into a ROM (I used super mario bros. 1) template that has all the PRG ROM blanked to zeros. Make sure the starting addresses corresponds to the value at the end of the PRG ROM for the NMI and program code. Finally, any pattern table editing in the CHR ROM part of the file can be done with a hex editor also, or using Nesticle's built in Pattern Table editor.
This is the end for now. There is alot of information and many more details concerning everything I went through to learn the things that I did. I would like to hear from anyone who utilizes this information to create source code or a working demo ROM or maybe even an actual game. Any function libraries in 6502 assembly would be appreciated to accomplish such things as collision detection, advanced sprite handling, and writing to the Name Table as a game scrolls, or what ever ideas you may have. If you would like, send me the source code and/or ROM and I can post it here for the use of other developers.
This page was last updated on July 29, 1997