Nestech.txt: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(It starts)
(→‎Screen and Sprite Layering: remove misspelled "synonmous"; EXT doesn't exist in a stock NES)
 
(13 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This will become an updated version of "Nintendo Entertainment System Documentation" by Jeremy Chadwick, aka "koitsu".
This is an updated version of "Nintendo Entertainment System Documentation" by Jeremy Chadwick, aka "koitsu".
It may prove easier to understand, particularly for programmers new to the NES, than some of the other, more technical documentation.
It provides a brief overview of the NES hardware and may prove easier to understand, particularly for programmers new to the NES, than some of the other, more technical documentation on this wiki.


== Introduction ==
== Introduction ==
Line 9: Line 9:
I am not trying to hinder anyone financially: if you wish to do development on Nintendo's current platforms, contact Nintendo via developer.nintendo.com.
I am not trying to hinder anyone financially: if you wish to do development on Nintendo's current platforms, contact Nintendo via developer.nintendo.com.


All titles of cartridges and console systems are trademarks of their respective owners. (I just don't deem it necessary to list every single one by hand).
All titles of cartridges and console systems are trademarks of their respective owners. (I just don't deem it necessary to list every single one by hand.)


=== Why? ===
=== Why? ===
Line 30: Line 30:


<pre>
<pre>
       Alex Krasivsky           - bcat@lapkin.rosprint.ru
       Alex Krasivsky
       Andrew Davie
       Andrew Davie
       Avatar Z                 - swahlen@nfinity.com
       Avatar Z
       Barubary                 - barubary@mailexcite.com
       Barubary
       Bluefoot                 - danmcc@injersey.com
       Bluefoot
       CiXeL
       CiXeL
       Chi-Wen Yang             - yangfanw@ms4.hinet.net
       Chi-Wen Yang
       Chris Hickman             - typhoonz@parodius.com
       Chris Hickman
       D                         - slf05@cc.usu.edu
       D
       Dan Boris                 - dan.boris@coat.com
       Dan Boris
       David de Regt             - akilla@earthlink.net
       David de Regt
       Donald Moore             - moore@futureone.com
       Donald Moore
       Fredrik Olsson           - flubba@hem2.passagen.se
       Fredrik Olsson
       Icer Addis               - bldlust@maelstrom.net
       Icer Addis
       Jon Merkel               - jpm5974@omega.uta.edu
       Jon Merkel
       Kevin Horton             - khorton@iquest.net
       Kevin Horton
       Loopy                     - zxcvzxcv@netzero.net
       Loopy
       Marat Fayzullin           - fms@cs.umd.edu
       Marat Fayzullin
       Mark Knibbs               - mark_k@iname.com
       Mark Knibbs
       Martin Nielsen           - mnielsen@get2net.dk
       Martin Nielsen
       Matt Conte               - itsbroke@classicgaming.com
       Matt Conte
       Matthew Richey           - mr6v@andrew.cmu.edu
       Matthew Richey
       Memblers                 - 5010.0951@tcon.net
       Memblers
       MiKael Iushin             - acc@tulatelecom.ru
       MiKael Iushin
       Mike Perry               - mj-perry@uiuc.edu
       Mike Perry
       Morgan Johansson         - morgan.johansson@mbox301.swipnet.se
       Morgan Johansson
       Neill Corlett             - corlett@elwha.nrrc.ncsu.edu
       Neill Corlett
       Pat Mccomack             - splat@primenet.com
       Pat Mccomack
       Patrik Alexandersson     - patrikus@hem2.passagen.se
       Patrik Alexandersson
       Paul Robson               - AutismUK@aol.com
       Paul Robson
       Ryan Auge                 - rauge@hay.net
       Ryan Auge
       Stumble                   - stumble@alpha.pulsar.net
       Stumble
       Tennessee Carmel-Veilleux - veilleux@ameth.org
       Tennessee Carmel-Veilleux
       Thomas Steen             - Thomas.Steen@no.jotankers.com
       Thomas Steen
       Tony Young               - KBAAA@aol.com
       Tony Young
       Vince Indriolo           - indriolo@nm.picker.com
       Vince Indriolo
       \FireBug\                 - lavos999@aol.com
       \FireBug\
</pre>
</pre>
Special thanks goes out to Stumble, for providing a myriad of information over IRC, while avoiding sleep to do so.
Special thanks goes out to Stumble, for providing a myriad of information over IRC, while avoiding sleep to do so.
Line 73: Line 73:


=== Internals ===
=== Internals ===
<pre>
;CPU: Central Processing Unit: Self-explanatory. The NES uses a standard 6502 (NMOS).
    CPU     - Central Processing Unit: Self-explanitory. The NES uses a
;PPU: Picture Processing Unit: Used to control graphics, sprites, and other video-oriented features.
              standard 6502 (NMOS).
;[[APU|pAPU]]: pseudo-Audio Processing Unit: Native to the CPU; generates waveforms via (5) audio channels:: four (4) analogue, and one (1) digital. There is no separate IC for audio processing nor generation inside the NES.
    PPU     - Picture Processing Unit: Used to control graphics, sprites,
;[[Mapper|MMC]]: Multi-Memory Controller or Memory Management Controller: Integrated circuits used in NES games to access memory beyond the 6502 64Kbyte boundary. They can also be used to access extra CHR-ROM, and may be used for "special effects" such as forcing an IRQ, and other things.
              and other video-oriented features.
;VRAM: Video RAM: The RAM which is internal to the PPU. There is 16kbits of VRAM installed in the NES.
    pAPU   - pseuedo-Audio Processing Unit: Native to the CPU; generates
;SPR-RAM: Sprite RAM: 256 bytes of RAM which is used for sprites. It is not part of VRAM nor ROM, though it's local to the PPU.
              waveforms via (5) audio channels:: four (4) analogue, and
;OAM: Object Attribute Memory: Synonymous with SPR-RAM.
              one (1) digital. There is no separate IC for audio process-
;PRG-ROM: Program ROM: The actual program-code area of memory. Also can be used to describe areas of code which are external to the actual code area and are swapped in via an MMC.
              ing nor generation inside the NES.
;PRG-RAM: Program RAM: Synonymous with PRG-ROM, except that it's RAM.
    MMC     - Multi-Memory Controller or Memory Management Controller:
;CHR-ROM: Character ROM: The VRAM data which is kept external to the PPU, swapped in and out via an MMC, or "loaded" into VRAM during the power-on sequence.
              Integrated circuits used in NES games
;VROM: Synonymous with CHR-ROM.
              to access memory beyond the 6502 64Kbyte boundary. They can
;SRAM: Save RAM: RAM which is commonly used in RPGs such as ''Crystalis,'' the ''Final Fantasy'' series, and ''The Legend of Zelda.''
              also be used to access extra CHR-ROM, and may be used for
;WRAM: Work RAM: Synonymous with SRAM.
              "special effects" such as forcing and IRQ, and other things.
;[[APU DMC|DMC]]: Delta Modulation Channel: The channel of the APU which handles digital data. Commonly referred to as the PCM (Pulse Code Modulation) channel.
    VRAM   - Video RAM: The RAM which is internal to the PPU. There is
;EX-RAM: Expansion RAM: This is the memory used within Nintendo's MMC5, allowing games to extend the capabilities of VRAM.
              16kbits of VRAM installed in the NES.
    SPR-RAM - Sprite RAM: 256 bytes of RAM which is used for sprites. It is
              not part of VRAM nor ROM, though it's local to the PPU.
    OAM     - Object Attribute Memory: Synonymous with SPR-RAM.
    PRG-ROM - Program ROM: The actual program-code area of memory. Also can
              be used to describe areas of code which are external to the
              actual code area and are swapped in via an MMC.
    PRG-RAM - Program RAM: Synonymous with PRG-ROM, except that it's RAM.
    CHR-ROM - Character ROM: The VRAM data which is kept external to the PPU,
              swapped in and out via an MMC, or "loaded" into VRAM during the
              power-on sequence.
    VROM   - Synonymous with CHR-ROM.
    SRAM   - Save RAM: RAM which is commonly used in RPGs such as "Cry-
              stalis," the Final Fantasy series, and "The Legend of Zelda."
    WRAM   - Work RAM: Synonymous with SRAM.
    DMC     - Delta Modulation Channel: The channel of the APU which handles
              digital data. Commonly referred to as the PCM (Pulse Code
              Modulation) channel.
    EX-RAM - Expansion RAM: This is the memory used within Nintendo's MMC5,
              allowing games to extend the capabilities of VRAM.
</pre>


=== Hardware ===
=== Hardware ===
<pre>
;NES: Nintendo Entertainment System: Self-explanatory.
    NES     - Nintendo Entertainment System: Self-explanitory.
;Famicom: Family Computer: Synonymous with the NES, except for also supporting external audio synthesizers in the cartridge.
    Famicom - Family Computer: Synonymous with the NES, except for also
;FDS: [[Famicom Disk System]]: Unit which sits atop the Famicom, supporting the use of 3" double-sided floppy disks for games.
              supporting external audio synthesizers in the cartridge.
;Dendy: Third-party clone of the Famicom for PAL TV systems, distributed in Russia and elsewhere in the East.
    FDS     - Famicom Disk System: Unit which sits atop the Famicom, support-
              ing the use of 3" double-sided floppy disks for games.
    Dendy   - Third-party clone of the Famicom for PAL TV systems,
              distributed in Russia and elsewhere in the East.
</pre>


== Unwikified ==
== CPU ==
The remainder of this document has not yet been converted to wiki markup, nor have its obsolete parts been corrected.
Hang tight...


=== General Information ===


<pre>
The NES uses a customized NMOS 6502 CPU, engineered and produced by Ricoh. Its primary customization adds audio.


+--------+
Different regional variants of the NES run the CPU different clock speeds.
| 3. CPU |
+--------+


  A. General Information
* The Famicom and NTSC NES runs at 1.789773 MHz.
  ----------------------
* The PAL NES runs at 1.662607 MHz.
    The NES uses a customized NMOS 6502 CPU, engineered and produced by
* The Dendy and other PAL famiclones run at 1.773448 MHz.
    Ricoh. It's primary customization adds audio.


    The NTSC NES runs at 1.7897725MHz, and 1.773447MHz for PAL.
=== Memory Map ===
 
<pre>
 
  B. Memory Map
  -------------
     +---------+-------+-------+-----------------------+
     +---------+-------+-------+-----------------------+
     | Address | Size  | Flags | Description          |
     | Address | Size  | Flags | Description          |
Line 152: Line 119:
     | $2008  | $1FF8 |  R    | Registers            |
     | $2008  | $1FF8 |  R    | Registers            |
     | $4000  | $20  |      | Registers            |
     | $4000  | $20  |      | Registers            |
     | $4020  | $1FDF |      | Expansion ROM         |
     | $4020  | $1FE0 |      | Expansion I/O         |
     | $6000  | $2000 |      | SRAM                  |
     | $6000  | $2000 |      | SRAM                  |
     | $8000  | $4000 |      | PRG-ROM              |
     | $8000  | $4000 |      | PRG-ROM              |
Line 160: Line 127:
                         R = Mirror of $2000-2008 every 8 bytes
                         R = Mirror of $2000-2008 every 8 bytes
                             (e.g. $2008=$2000, $2018=$2000, etc.)
                             (e.g. $2008=$2000, $2018=$2000, etc.)
</pre>


=== Interrupts ===


  C. Interrupts
The 6502 has three (3) interrupts: IRQ/BRK, NMI, and RESET.
  -------------
    The 6502 has three (3) interrupts: IRQ/BRK, NMI, and RESET.


    Each interrupt has a vector. A vector is a 16-bit address which spec-
Each interrupt has a vector.
    ifies a location to "jump to" when the interrupt is triggered.
A vector is a 16-bit address which specifies a location to "jump to" when the interrupt is triggered.


    IRQ/BRK is triggered under two circumstances, hence it's split name:
IRQ/BRK is triggered under two circumstances, hence it's split name: when a software IRQ is executed (the BRK instruction), or when a hardware IRQ is executed (via the IRQ line).
    when a software IRQ is executed (the BRK instruction), or when a
    hardware IRQ is executed (via the IRQ line).


    RESET is triggered on power-up. The ROM is loaded into memory, and
RESET is triggered on power-up.
    the 6502 jumps to the address specified in the RESET vector. No registers
The ROM is loaded into memory, and the 6502 jumps to the address specified in the RESET vector.
    are modified, and no memory is cleared; these only occur during power-up.
No registers are modified, and no memory is cleared; these only occur during power-up.


    NMI stands for Non-Maskable Interrupt, and is generated by each refresh
NMI stands for Non-Maskable Interrupt, and is generated by each refresh (VBlank), which occurs at different intervals depending upon the system used (PAL/NTSC).
    (VBlank), which occurs at different intervals depending upon the system
    used (PAL/NTSC).


    NMI is updated 60 times/sec. on NTSC consoles, and 50 times/sec on PAL.
NMI is updated 60 times/sec. on NTSC consoles, and 50 times/sec on PAL.
    Interrupt latency on the 6502 is seven (7) cycles; this means it takes
Interrupt latency on the 6502 is seven (7) cycles; this means it takes seven (7) cycles to move in and out of an interrupt.
    seven (7) cycles to move in and out of an interrupt.


    Most interrupts should return using the RTI instruction. Some NES carts
Most interrupts should return using the RTI instruction.
    do not use this method, such as SquareSoft's "Final Fantasy 1" title.
Some NES carts do not use this method, such as SquareSoft's ''Final Fantasy'' title.
    These carts return from interrupts in a very odd fashion: by manipul-
These carts return from interrupts in a very odd fashion: by manipulating the stack by hand, and then doing an RTS.
    ating the stack by hand, and then doing an RTS. This is technically
This is technically valid, but morally shunned.
    valid, but morally shunned.


    The aforementioned nterrupts have the following vector addresses,
The aforementioned interrupts have the following vector addresses, mapped to areas of ROM:
    mapped to areas of ROM:


      $FFFA = NMI
* $FFFA = NMI
      $FFFC = RESET
* $FFFC = RESET
      $FFFE = IRQ/BRK
* $FFFE = IRQ/BRK


    Interrupt priorities are as follows:
Interrupt priorities are as follows:


      Highest = RESET
* RESET (highest)
                NMI
* NMI
      Lowest = IRQ/BRK
* IRQ/BRK (lowest)


=== NES-specific Customizations ===


  D. NES-specific Customizations
The NES's 6502 does not contain support for decimal mode.
  ------------------------------
Both the CLD and SED opcodes function normally, but the 'd' bit of P is unused in both ADC and SBC.
    The NES's 6502 does not contain support for decimal mode. Both the
It is common practice for games to CLD prior to code execution, as the status of 'd' is unknown on power-on and on reset.
    CLD and SED opcodes function normally, but the 'd' bit of P is unused
    in both ADC and SBC. It is common practice for games to CLD prior to
    code execution, as the status of 'd' is unknown on power-on and on
    reset.


    Audio registers are mapped internal to the CPU; all waveform gener-
Audio registers are mapped internal to the CPU; all waveform generation is done internal to the CPU as well.
    ation is done internal to the CPU as well.


=== Notes ===


  E. Notes
Please note the two separate 16K PRG-ROM segments; they may be linear, but they play separate roles depending upon the size of the cartridge.
  --------
Some games only hold one (1) 16K bank of PRG-ROM, which should be loaded into both $C000 and $8000.
    Please note the two separate 16K PRG-ROM segments; they may be linear,
    but they play separate roles depending upon the size of the cartridge.
    Some games only hold one (1) 16K bank of PRG-ROM, which should be
    loaded into both $C000 and $8000.


    Most games load themselves into $8000, using 32K of PRG-ROM space. The
Most games load themselves into $8000, using 32K of PRG-ROM space.
    first game to use this method is Super Mario Brothers. However, all
The first game to use this method is _Super Mario Bros._
    games wit more than one (1) 16K bank of PRG-ROM load themselves into
However, almost all games with more than one (1) 16K bank of PRG-ROM load themselves into $8000 as well.
    $8000 as well. These games use Memory Mappers to swap in and out PRG-ROM
These games use Memory Mappers to swap in and out PRG-ROM data, as well as CHR-ROM.
    data, as well as CHR-ROM.
A few Memory Mappers, especially on later games, allow swapping in half of a 16K segment.
 
    When a BRK is encountered, the NES's 6502 pushes the CPU status flag
    onto the stack with the 'b' CPU bit set. On an IRQ or NMI, the CPU
    pushes the status flag onto the stack with the 'b' bit clear. This is
    done because of the fact that a hardware IRQ (IRQ) and a software
    IRQ (BRK) both share the same vector. For example, one could use the
    following code to distinguish the difference between the two:


When a BRK is encountered, the NES's 6502 pushes the CPU status flag onto the stack with the 'b' CPU bit set.
On an IRQ or NMI, the CPU pushes the status flag onto the stack with the 'b' bit clear.
This is done because of the fact that a hardware IRQ (IRQ) and a software IRQ (BRK) both share the same vector.
For example, one could use the following code to distinguish the difference between the two:
<pre>
       C134: PLA                ; Copy CPU status flag
       C134: PLA                ; Copy CPU status flag
       C135: PHA                ; Return status flag to stack
       C135: PHA                ; Return status flag to stack
       C136: AND #$10            ; Check D4 ('b' CPU bit)
       C136: AND #$10            ; Check D4 ('b' CPU bit)
       C138: BNE is_BRK_opcode  ; If set then it is a software IRQ (BRK)
       C138: BNE is_BRK_opcode  ; If set then it is a software IRQ (BRK)
</pre>
Executing BRK inside of an interrupt handler (IRQ or NMI) will result in the pushed 'b' bit being set.


    Executing BRK inside of NMI will result in the pushed 'b' bit being
The 6502 has a bug in opcode $6C (jump absolute indirect).
    set.
The CPU does not correctly calculate the effective address if the low-byte is $FF.
 
Example:
    The 6502 has a bug in opcode $6C (jump absolute indirect). The CPU does
<pre>
    not correctly calculate the effective address if the low-byte is $FF.
       C100: EF
    Example:
 
       C100: 4F
       C1FF: 00
       C1FF: 00
       C200: 23
       C200: C3
         ..
         ..
       D000: 6C FF C1 - JMP ($C1FF)
       D000: 6C FF C1 - JMP ($C1FF)
</pre>
Logically, this will jump to address $C300. However, due to the fact that the high-byte of the calculate address is *NOT* increased on a page-wrap, this will actually jump to $EF00.


    Logically, this will jump to address $2300. However, due to the fact
It should be noted that page wrapping does *NOT* occur in indexed-indirect addressing modes. Due to limitations of zero-page, all indexed-indirect read/writes should apply a logical AND #$FF to the effective address after calculation. Example:
    that the high-byte of the calculate address is *NOT* increased on a
<pre>
    page-wrap, this will actually jump to $4F00.
 
    It should be noted that page wrapping does *NOT* occur in indexed-
    indirect addressing modes. Due to limitations of zero-page, all
    indexed-indirect read/writes should apply a logical AND #$FF to
    the effective address after calculation. Example:
   
       C000: LDX #3        ; Reads indirect address from $0002+$0003,
       C000: LDX #3        ; Reads indirect address from $0002+$0003,
       C002: LDA ($FF,X)  ;  not $0102+$0103.
       C002: LDA ($FF,X)  ;  not $0102+$0103.
</pre>


== PPU ==


=== General Information ===
Mirroring (also referred to as "shadowing") is the process of mapping particular addresses or address ranges to other addresses/ranges via hardware.


+--------+
=== Memory Map ===
| 4. PPU |
Included here are two (2) memory maps.
+--------+
The first is a "RAM Memory Map," which despite being less verbose describes the actual regions which point to physical memory in the NES Control Deck and most Game Paks.
 
The second is a "Programmer Memory Map" which is quite verbose and describes the entire memory region of the NES and how it's used/manipulated.
  A. General Information
<pre>
  ----------------------
    Mirroring (also referred to as "shadowing") is the process of mapping
    particular addresses or address ranges to other addresses/ranges via
    hardware.
 
 
  B. Memory Map
  -------------
    Included here are two (2) memory maps. The first is a "RAM Memory
    Map," which despite being less verbose describes the actual regions
    which point to physical RAM in the NES itself. The second is a
    "Programmer Memory Map" which is quite verbose and describes the
    entire memory region of the NES and how it's used/manipulated.
 
         RAM Memory Map
         RAM Memory Map
       +---------+-------+--------------------+
       +---------+-------+----------------+
       | Address | Size  | Description       |
       | Address | Size  | Description   |
       +---------+-------+--------------------+
       +---------+-------+----------------+
       | $0000  | $1000 | Pattern Table #0  |
       | $0000  | $2000 | Pattern Tables |
      | $1000  | $1000 | Pattern Table #1  |
       | $2000  | $800  | Name Tables   |
       | $2000  | $800  | Name Tables       |
       | $3F00  | $20  | Palettes       |
       | $3F00  | $20  | Palettes           |
       +---------+-------+----------------+
       +---------+-------+--------------------+
 


         Programmer Memory Map
         Programmer Memory Map
Line 319: Line 252:
       | $4000  | $C000 |    F |                    |
       | $4000  | $C000 |    F |                    |
       +---------+-------+-------+--------------------+
       +---------+-------+-------+--------------------+
                           C = Possibly CHR-ROM
                           C = Either CHR-ROM or CHR-RAM
                           N = Mirrored (see Subsection G)
                           N = Mirrored (see Subsection G)
                           P = Mirrored (see Subsection H)
                           P = Mirrored (see Subsection H)
                           R = Mirror of $2000-2EFF (VRAM)
                           R = Mirror of $2000-2EFF (VRAM)
                           F = Mirror of $0000-3FFF (VRAM)
                           F = Mirror of $0000-3FFF (VRAM)
</pre>


=== 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.


  C. Name Tables
The Name Tables holds the tile number of the data kept in the Pattern Table (continue on).
  --------------
    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:


=== 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:
<pre>
       VRAM    Contents of                    Colour  
       VRAM    Contents of                    Colour  
       Addr  Pattern Table                    Result
       Addr  Pattern Table                    Result
Line 363: Line 290:
         ..  %10000010 = $82  |
         ..  %10000010 = $82  |
       $000F: %00000000 = $00 --+
       $000F: %00000000 = $00 --+
</pre>
The result of the above Pattern Table is the glyph for the letter 'A', as shown in the "Colour Result" section in the upper right.


    The result of the above Pattern Table is the character 'A', as shown
=== Attribute Tables ===
    in the "Colour Result" section in the upper right.
Each byte in an Attribute Table represents a 4x4 group of tiles on the screen.
There are 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.


  E. Attribute Tables
It's quite confusing; two graphical diagrams may help:
  -------------------
<pre>
    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
       |  Square 0  |  Square 1  |  #0-F represents an 8x8 tile
Line 389: Line 312:
       |  #A  #B  |  #E  #F  |
       |  #A  #B  |  #E  #F  |
       +------------+------------+
       +------------+------------+
 
</pre>
    The actual format of the attribute byte is the following (and corris-
The actual format of the attribute byte is the following (and corres ponds to the above example):
    ponds to the above example):
<pre>
 
       Attribute Byte
       Attribute Byte
         (Square #)
         (Square #)
       ----------------
       ----------------
           33221100
           33221100
           ||||||+--- Upper two (2) colour bits for Square 0 (Tiles #0,1,2,3)
           ||||||++-- 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 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 2 (Tiles #8,9,A,B)
           +--------- Upper two (2) colour bits for Square 3 (Tiles #C,D,E,F)
           ++-------- Upper two (2) colour bits for Square 3 (Tiles #C,D,E,F)
</pre>


=== Palettes ===
The NES has two 16-colour "palettes": the Image Palette and the Sprite Palette.
These palettes are more of a "lookup table" than an actual palette, since they do not hold physical RGB values.
They're actually closer to HSV, with lightness in D5-D4 and hue in D3-D0.


  F. Palettes
D7-D6 of bytes written to $3F00-3FFF are ignored.
  -----------
    The NES has two 16-colour "palettes": the Image Palette and the Sprite
    Palette. These palettes are more of a "lookup table" than an actual
    palette, since they do not hold physical RGB values.


    D7-D6 of bytes written to $3F00-3FFF are ignored.
For details see [[PPU palettes]] and [[NTSC video]].


=== Name Table Mirroring ===
One should keep in mind that there are many forms of mirroring when understanding the NES.
Some methods even use CHR-ROM-mapped Name Tables (mapper-specific).


  G. Name Table Mirroring
The NES itself only contains 2048 ($800) bytes of RAM used for Name Tables.
  -----------------------
However, as shown in Subsection B, the NES has the capability of addressing up to four (4) Name Tables.
    One should keep in mind that there are many forms of mirroring when
    understanding the NES. Some methods even use CHR-ROM-mapped Name
    Tables (mapper-specific).


    The NES itself only contains 2048 ($800) bytes of RAM used for Name
By default, many carts come with "horizontal" and "vertical" mirroring, allowing you to change where the Name Tables point into the NES's PPU RAM. This form of mirroring affects two (2) Name Tables simultaneously; you cannot switch Name Tables independently.
    Tables. However, as shown in Subsection B, the NES has the capability
    of addressing up to four (4) Name Tables.
 
    By default, many carts come with "horizontal" and "vertical" mirroring,
    allowing you to change where the Name Tables point into the NES's PPU
    RAM. This form of mirroring affects two (2) Name Tables simultaneously;
    you cannot switch Name Tables independently.
 
    The following chart should assist in understanding all the types of
    mirroring encountered on the NES. Please note that the addresses
    shown (12-bit in size) refer to the Name Table portion of the NES's
    PPU RAM; one may consider these synonymous with "$2xxx" in the VRAM
    region:


The following chart should assist in understanding all the types of mirroring encountered on the NES.
Please note that the addresses shown (12-bit in size) refer to VRAM.
Mirroring determines how raw addresses in VRAM are translated into addresses that the PPU sees in the "$2xxx" region.
<pre>
         Name                      NT#0  NT#1  NT#2  NT#3  Flags
         Name                      NT#0  NT#1  NT#2  NT#3  Flags
       +--------------------------+------+------+------+------+-------+
       +--------------------------+------+------+------+------+-------+
Line 452: Line 366:
             However, this feature can be controlled via the mapper itself,
             However, this feature can be controlled via the mapper itself,
             allowing you to enable or disable this feature.
             allowing you to enable or disable this feature.
</pre>


=== Palette Mirroring ===
Mirroring occurs between the Background Palette and the Sprite Palette on addresses that are multiples of 4.
Any data which is written to $3F00 is mirrored to $3F10. Any data written to $3F04 is mirrored to $3F14, etc. etc...


  H. Palette Mirroring
Colour #0 in the upper three (3) palettes of both the Image and Sprite palette defines transparency (the actual colour stored there is not drawn on-screen).
  --------------------
    Mirroring occurs between the Image Palette and the Sprite Palette.
    Any data which is written to $3F00 is mirrored to $3F10. Any data
    written to $3F04 is mirrored to $3F14, etc. etc...


    Colour #0 in the upper three (3) palettes of both the Image and Sprite
In most cases, the PPU uses the value in $3F00 to define background colour.
    palette defines transparency (the actual colour stored there is not
    drawn on-screen).


    The PPU uses the value in $3F00 to define background colour.
For a more verbose explanation, assume the following:


    For a more verbose explanation, assume the following:
* $0D has been written to $3F00 (mirrored to $3F10)
* $03 has been written to $3F08 (mirrored to $3F18)
* $1A has been written to $3F18
* $3F08 is read into the accumulator


      * $0D has been written to $3F00 (mirrored to $3F10)
The PPU will use $0D as the background colour, despite $3F08 holding a value of $03 (since colour #0 in all the palette entries defines transparency, it is not drawn).
      * $03 has been written to $3F08 (mirrored to $3F18)
Finally, the accumulator will hold a value of $1A, which is mirrored from $3F18.
      * $1A has been written to $3F18
Again, the value of $1A is not drawn, since colour #0 defines transparency.
      * $3F08 is read into the accumulator


    The PPU will use $0D as the background colour, despite $3F08 holding
The entire Background and Sprite Palettes are both mirrored to other areas of VRAM as well; $3F20-3FFF are mirrors of both palettes, respectively.
    a value of $03 (since colour #0 in all the palette entries defines
    transparency, it is not drawn). Finally, the accumulator will hold
    a value of $1A, which is mirrored from $3F18. Again, the value of $1A
    is not drawn, since colour #0 defines transparency.


    The entire Image and Sprite Palettes are both mirrored to other areas
Again, D7-D6 of bytes written to $3F00-3FFF are ignored.
    of VRAM as well; $3F20-3FFF are mirrors of both palettes, respectively.


    D7-D6 of bytes written to $3F00-3FFF are ignored.
=== Background Scrolling ===
 
The NES can scroll the background (pre-rendered Name Table + Pattern Table + Attribute Table) independently of the sprites which are overlaid on top of it. The background can be scrolled horizontally and vertically.
 
  I. Background Scrolling
  -----------------------
    The NES can scroll the background (pre-rendered Name Table + Pattern
    Table + Attribute Table) independently of the sprites which are over-
    layed on top of it. The background can be scrolled horizontally and
    vertically.
 
    Scrolling works as follows:


Scrolling works as follows:
<pre>
       Horizontal Scrolling            Vertical Scrolling
       Horizontal Scrolling            Vertical Scrolling
         0          512
         0          512
Line 505: Line 407:
                                           |    |
                                           |    |
                                           +-----+ 480
                                           +-----+ 480
</pre>
Name Table "A" is specified via Bits D1-D0 in register $2000, and "B" is the Name Table after (due to mirroring, this is dynamic).
Games which use Horizontal & Vertical scrolling simultaneously need special attention paid to mirroring.


    Name Table "A" is specified via Bits D1-D0 in register $2000, and "B" is
The background will span across multiple Name Tables, as shown here:
    the Name Table after (due to mirroring, this is dynamic). This doesn't
<pre>
    work for game which use Horizontal & Vertical scrolling simultaneously.
      +---------------+---------------+
 
      | Name Table #0 | Name Table #1 |
    The background will span across multiple Name Tables, as shown here:
      |    ($2000)    |    ($2400)    |
 
       +---------------+---------------+
       +---------------+---------------+
       | Name Table #2 | Name Table #3 |
       | Name Table #2 | Name Table #3 |
       |    ($2800)    |    ($2C00)    |
       |    ($2800)    |    ($2C00)    |
       +---------------+---------------+
       +---------------+---------------+
       | Name Table #0 | Name Table #1 |
</pre>
 
But depending on mirroring, some of them will be repeated:
<pre>
      Horizontal Mirroring
      +---------------+---------------+
       | Name Table #0 | Duplicate #|
       |    ($2000)    |    ($2400)    |
       |    ($2000)    |    ($2400)    |
      +---------------+---------------+
      | Name Table #2 | Duplicate #2  |
      |    ($2800)    |    ($2C00)    |
       +---------------+---------------+
       +---------------+---------------+


    Writes to the Horizontal Scroll value in $2005 range from 0 to 256.
    Writes to the Vertical Scroll value range from 0-239; values above 239
    are considered negative (e.g. a write of 248 is really -8).


      Vertical Mirroring
      +---------------+---------------+
      | Name Table #0 | Name Table #1 |
      |    ($2000)    |    ($2400)    |
      +---------------+---------------+
      | Duplicate #0  | Duplicate #1  |
      |    ($2800)    |    ($2C00)    |
      +---------------+---------------+
</pre>


  J. Screen and Sprite Layering
Writes to the Horizontal Scroll value in $2005 range from 0 to 255.
  -----------------------------
Writes to the Vertical Scroll value range from 0-239.
    There is a particular order in which the NES draws it's contents:
Vertical Scroll values above 239 are considered negative (e.g. a write of 248 is really -8).
This is because values above 239 cause the PPU to interpret Attribute Table data as Name Table data.


=== Screen and Sprite Layering ===
There is a particular order in which the NES draws its contents:
<pre>
       FRONT                                BACK
       FRONT                                BACK
       +----+-----------+----+-----------+-----+
       +----+-----------+----+-----------+-----+
Line 536: Line 459:
           | BGPRI==0  |    | BGPRI==1  |
           | BGPRI==0  |    | BGPRI==1  |
           +-----------+    +-----------+
           +-----------+    +-----------+
</pre>
CI stands for 'Colour Intensity', or 'Emphasis', or 'Tint', set in D7-D5 of $2001.
BG is the BackGround.
EXT is for the EXTension port video signal (not available in a stock NES).


    CI stands for 'Colour Intensity', which is synonmous with D7-D5 of
'BGPRI' represents the 'Background Priority' bit in SPR-RAM, on a per-sprite basis (D5, Byte 2).
    $2001. BG is the BackGround, and EXT is for the EXTension port video
    signal.


    'BGPRI' represents the 'Background Priority' bit in SPR-RAM, on a
OBJ numbers represent actual Sprite numbers, not Tile Index values.
    per-sprite basis (D5, Byte 2).


    OBJ numbers represent actual Sprite numbers, not Tile Index values.
FRONT is considered what is seen atop all other layers (drawn last), and BACK is deemed what is below most other layers (drawn first).


    FRONT is considered what is seen atop all other layers (drawn last),
If a sprite with BGPRI==1 has a lower index in SPR-RAM than a sprite with BGPRI==0, the front-to-back ordering is more complicated.
    and BACK is deemed what is below most other layers (drawn first).
See [[PPU sprite priority]] for full details.


=== Sprites and OAM ===
The NES supports 64 sprites, which can be either 8x8 or 8x16 pixels in size.
The sprite data is kept within the Pattern Table region of VRAM.


  K. Sprites and SPR-RAM
Sprite attributes such as flipping and priority, are stored in SPR-RAM, which is a separate 256 byte area of memory, independent of ROM and VRAM.
  ----------------------
The format of SPR-RAM is as follows:
    The NES supports 64 sprites, which can be either 8x8 or 8x16 pixels in
<pre>
    size. The sprite data is kept within the Pattern Table region of VRAM.
 
    Sprite attributes such as flipping and priority, are stored in SPR-RAM,
    which is a separate 256 byte area of memory, independent of ROM and
    VRAM. The format of SPR-RAM is as follows:
 
       +-----------+-----------+-----+------------+
       +-----------+-----------+-----+------------+
       | Sprite #0 | Sprite #1 | ... | Sprite #63 |
       | Sprite #0 | Sprite #1 | ... | Sprite #63 |
Line 579: Line 500:
         |  3  | XXXXXXXX | X Coordinate (upper-left corner)    |
         |  3  | XXXXXXXX | X Coordinate (upper-left corner)    |
         +------+----------+--------------------------------------+
         +------+----------+--------------------------------------+
</pre>
The Tile Index # is obtained the same way as Name Table data.


    The Tile Index # is obtained the same way as Name Table data.
Sprites which are 8x16 in size function a little bit differently.
An 8x16 sprite which has an even-numbered Tile Index # use the Pattern Table at $0000 in VRAM; odd-numbered Tile Index #s use $1000.
*NOTE*: Register $2000 D3 has no effect on 8x16 sprites.


    Sprites which are 8x16 in size function a little bit differently. A
All 64 sprites contain an internal priority; sprite #0 is of a higher priority than sprites #63 (sprite #0 should be drawn last, etc.).
    8x16 sprite which has an even-numbered Tile Index # use the Pattern
    Table at $0000 in VRAM; odd-numbered Tile Index #s use $1000.
    *NOTE*: Register $2000 has no effect on 8x16 sprites.


    All 64 sprites contain an internal priority; sprite #0 is of a higher
Only eight (8) sprites can be displayed per scan-line.
    priority than sprites #63 (sprite #0 should be drawn last, etc.).
Each entry in SPR-RAM is checked to see if it's in a horizontal range with the other sprites.
Remember, this is done on a per scan-line basis, not on a per sprite basis (e.g. done 256 times, not 256/8 or 256/16 times).


    Only eight (8) sprites can be displayed per scan-line. Each entry in
NOTE: On a real NES unit, if both background and sprites are disabled (D4-D3 of $2001 is 00) for a long period of time, SPR-RAM will gradually degrade.
    SPR-RAM is checked to see if it's in a horizontal range with the other
Photographs of a decapped PPU have confirmed that SPR-RAM is actually DRAM, and rendering controls the DRAM refresh cycle.
    sprites. Remember, this is done on a per scan-line basis, not on a per
    sprite basis (e.g. done 256 times, not 256/8 or 256/16 times).


    (NOTE: On a real NES unit, if sprites are disabled (D4 of $2001 is 0)
=== Sprite #0 Hit Flag ===
    for a long period of time, SPR-RAM will gradually degrade. A proposed
The PPU is capable of figuring out where Sprite #0 is, and stores its findings in D6 of $2002.
    concept is that SPR-RAM is actually DRAM, and D4 controls the DRAM
The way this works is as follows:
    refresh cycle).


As the PPU draws each line, it scans for the first actual non-transparent "sprite pixel" and the first non-transparent "background pixel."
A "background pixel" is a tile which is in use by the Name Table.
Remember that colour #0 defines transparency.


  L. Sprite #0 Hit Flag
The pixel which causes D6 to be set *IS* drawn.
  ---------------------
    The PPU is capable of figuring out where Sprite #0 is, and stores
    it's findings in D6 of $2002. The way this works is as follows:
 
    The PPU scans for the first actual non-transparent "sprite pixel" and
    the first non-transparent "background pixel." A "background pixel" is
    a tile which is in use by the Name Table. Remember that colour #0
    defines transparency.
 
    The pixel which causes D6 to be set *IS* drawn.
      
      
    The following example should help. The following are two tiles.
The following example should help.
    Transparent colours (colour #0) are defined via the underscore ('_')
The following are two tiles.
    character. An asterisk ('*') represents when D6 will be set.
Transparent colours (colour #0) are defined via the underscore ('_') character.
 
An asterisk ('*') represents when D6 will be set.
<pre>
       Sprite        BG        Result
       Sprite        BG        Result
       ------        --        ------
       ------        --        ------
Line 627: Line 541:
       _111111_    __211111    _1111111
       _111111_    __211111    _1111111
       __1111__    _2111111    _2111111
       __1111__    _2111111    _2111111
</pre>
This also applies to sprites that are underneath the BG (via the 'Background Priority' SPR-RAM bit), though the above example would be 'BG+Sprite'.


    This also applies to sprites that are underneathe the BG (via the
However, D6 does not get set if the overlap is at the far right of the screen (X==255).
    'Background Priority' SPR-RAM bit), though the above example would
    be 'BG+Sprite'.


    Also, D6 is cleared (set to 0) after each VBlank.
Also, D6 is cleared (set to 0) at the end of each VBlank.


=== Horizontal and Vertical Blanking ===
The NES, like every console, has a refresh: where the display device relocates the electron gun to display visible data.
The most common display device is a television set.
The refresh occurs 60 times a second on an NTSC device, and 50 on a PAL device.


  M. Horizontal and Vertical Blanking
The gun itself draws pixels left to right: this process results in one (1) horizontal scanline being drawn.
  -----------------------------------
After the gun is done drawing the entire scanline, the gun must return to the left side of the display device, becoming ready to draw the next scanline.
    The NES, like every console, has a refresh: where the display device
The process of the gun returning to the left side of the display is the Horizontal Blank period (HBlank).
    relocates the electron gun to display visible data. The most common
    display device is a television set. The refresh occurs 60 times a
    second on an NTSC device, and 50 on a PAL device.


    The gun itself draws pixels left to right: this process results in
When the gun has completed drawing all of the scanlines, it must return to the top of the display device.
    one (1) horizontal scanline being drawn. After the gun is done drawing
The time it takes for the gun to re-position itself atop the device is called the Vertical Blank period (VBlank).
    the entire scanline, the gun must return to the left side of the
    display device, becoming ready to draw the next scanline. The process
    of the gun returning to the left side of the display is the Horizontal
    Blank period (HBlank).
 
    When the gun has completed drawing all of the scanlines, it must return
    to the top of the display device; the time it takes for the gun to
    re-position itself atop the device is called the Vertical Blank period
    (VBlank).
 
    As you can see from the below diagram, the gun more or less works in
    a zig-zag pattern until VBlank is reached, then the process repeats:


As you can see from the below diagram, the gun more or less works in a zig-zag pattern until VBlank is reached, then the process repeats:
<pre>
           +-----------+
           +-----------+
       +--->|***********| <-- Scanline 0
       +--->|***********| <-- Scanline 0
Line 668: Line 573:
       |          |
       |          |
       +--VBlank--+
       +--VBlank--+
</pre>
The screen is 256 pixels wide, and the HBlank time that follows each line adds an additional 85 for a total of 341.


    An NTSC NES has the following refresh and screen layout:
An NTSC NES has the following refresh and screen layout:
<pre>
      0      256 340
      +--------+  |  0 --+
      |        |  |      |
      |        | H |      |
      | Screen | B |      +-- (0-239) 256x240 on-screen results
      |        | l |      |
      |        |  |      |
      +--------+  | 239 --+
      +--------+    240 --+-- (240) Post-render
      +--------+    241 --+
      |        |          |
      | VBlank |          +-- (241-260) VBlank
      |        |          |
      +--------+    260 --+
      +--------+    261 --+-- (261) Pre-render
</pre>


      +--------+ 0 ----+
The Vertical Blank (VBlank) flag is contained in D7 of $2002.
      |        |      |
It indicates whether PPU is in VBlank or not.
      |        |      |
A program can reset D7 by reading $2002.
      | Screen |      +-- (0-239) 256x240 on-screen results
Reading $2002 at the very start of VBlank will reset $2002 even though D7 appears false.
      |        |      |
      |        |      |
      +--------+ 240 --+
      |  ??  |      +-- (240-242) Unknown
      +--------+ 243 --+
      |        |      |
      | VBlank |      +-- (243-262) VBlank
      |        |      |
      +--------+ 262 --+


    The Vertical Blank (VBlank) flag is contained in D7 of $2002. It
=== $2005/$2006 Magic ===
    indicates whether PPU is in VBlank or not. A program can reset D7 by
Games can split the screen by changing the video memory address using both the $2005 and $2006 registers.
    reading $2002.
This is often used to draw a status bar at the top or bottom of the screen.
For detailed information pertaining to splits, refer to Loopy's $2005/2006 document.
His document provides entirely accurate information regarding how these registers work.
See [[PPU scrolling]] for more information


=== Reading VRAM ===
The first byte read from VRAM is invalid.
Due to this aspect, the NES will returned pseudo-buffered values from VRAM rather than linear as expected.
See the below example:


  N. $2005/2006 Magic
* VRAM $2000 contains $AA $BB $CC $DD.
  -------------------
* VRAM incrementation value is 1.
    For detailed information pertaining to the $2005 and $2006 registers,
* The result of execution is printed in the comment field.  
    refer to Loopy's $2005/2006 document. His document provides entirely
<pre>
    accurate information regarding how these registers work. Contact
    Loopy for more information.
 
 
  O. PPU Quirks
  -------------
    The first read from VRAM is invalid. Due to this aspect, the NES will
    returned pseudo-buffered values from VRAM rather than linear as expec-
    ted. See the below example:
 
    VRAM $2000 contains $AA $BB $CC $DD.
    VRAM incrementation value is 1.
    The result of execution is printed in the comment field.  
 
       LDA #$20
       LDA #$20
       STA $2006
       STA $2006
Line 721: Line 629:
       LDA $2007        ; A=$CC    VRAM Buffer=$AA
       LDA $2007        ; A=$CC    VRAM Buffer=$AA
       LDA $2007        ; A=$AA    VRAM Buffer=$BB
       LDA $2007        ; A=$AA    VRAM Buffer=$BB
</pre>
As shown, the PPU will post-increment it's internal address data after the first read is performed.
This '''only applies''' to VRAM $0000-3EFF (e.g. Palette data and their respective mirrors do not suffer from this phenomenon).


    As shown, the PPU will post-increment it's internal address data after
=== Notes ===
    the first read is performed. This *ONLY APPLIES* to VRAM $0000-3EFF
The PPU will auto-increment the VRAM address by 1 or 32 (based on D2 of $2000) after accessing $2007.
    (e.g. Palette data and their respective mirrors do not suffer from
    this phenomenon).


While rendering is off ($2001 D4-D3 set to 00), and the current video memory address is at $3F00-$3FFF, the PPU outputs the palette entry at that address.
To avoid streaks of rainbow colours, make sure to update the palette during VBlank.


  P. Notes
== pAPU ==
  --------
This section was not completed in time for Nestech.txt version 2.00.
    The PPU will auto-increment the VRAM address by 1 or 32 (based on D2
See [[APU]] for accurate information.
    of $2000) after accessing $2007.


== Joypads, paddles, expansion ports ==


=== General Information ===
The NES supports several different input devices, including joypads, Zapper (light guns), and four-player devices.


+---------+
Joypad #1 and #2 are read via $4016 and $4017, respectively.
| 5. pAPU |
+---------+
  To be written. Prior information was inaccurate or incorrect. No one
  has 100% accurate sound information at this time. This section will
  be completed when someone decides to reverse engineer the pAPU section
  of the NES, and provide me with information (or a reference to infor-
  mation).


The joypads are reset via a strobing-method: writing 1, then 0, to $4016.
This address controls the strobe on both joypads.
See "Expansion ports" for information regarding "half-strobing."


After a full strobe, the joypad's button status will be returned in a single-bit stream (D0).
Multiple reads need to be made to read all the information about the controller.


+--------------------------------------+
The standard controller can be read 8 times, once for each button:
| 6. Joypads, paddles, expansion ports |
<pre>
+--------------------------------------+
      1 = A
      2 = B
      3 = SELECT
      4 = START
      5 = UP
      6 = DOWN
      7 = LEFT
      8 = RIGHT
</pre>
Reads after the eighth return a 1 bit on most controllers.
A few return 0 instead.


  A. General Information
=== The Zapper ===
  ----------------------
The Zapper (otherwise known as the "Light Gun") uses bits within $4016 and $4017, described in Section 8.
    The NES supports a myriad of input devices, including joypads, Zappers
D4 and D3 are connected to the trigger and light sensor respectively.
    (light guns), and four-player devices.
The light sensor needs to be read throughout the frame, as it returns a light signal for only about 2000 cycles.


    Joypad #1 and #2 are accessed via $4016 and $4017, respectively.
It is possible to have two Zapper units connected to both joypad ports simultaneously.
The unlicensed games ''Chiller'' and ''Zap Ruder'' use this.


    The joypads are reset via a strobing-method: writing 1, then 0, to
=== Four-player devices ===
    $4016. See Subsection H for information regarding "half-strobing."
Some NES games allow the use of a four-player adapter, extending the number of usable joypads from two (2) to four (4).
Carts which use the NES Four Score or NES Satellite are Mindscape/Tengen's ''Gauntlet II'' and Nintendo/Rare's ''R.C. Pro-Am 2''.


    On a full strobe, the joypad's button status will be returned in a
All four (4) controllers read their status-bits from D0 of $4016 or $4017, as Subsection A states.
    single-bit stream (D0). Multiple reads need to be made to read all the
    information about the controller.


      1 = A          9 = Ignored  17 = +--+
For register $4016, reads #1-8 control joypad #1, reads #9-16 control joypad #3, and reads #17-24 return a signature.
      2 = B        10 = Ignored  18 =    +-- Signature
For $4017, it is respective for joypad #2 and #4.
      3 = SELECT    11 = Ignored  19 =    |
      4 = START    12 = Ignored  20 = +--+
      5 = UP        13 = Ignored  21 = 0
      6 = DOWN      14 = Ignored  22 = 0
      7 = LEFT      15 = Ignored  23 = 0
      8 = RIGHT    16 = Ignored  24 = 0
 
    See Subsection G for information about Signatures.
 
 
  B. The Zapper
  -------------
    The Zapper (otherwise known as the "Light Gun") simply uses bits
    within $4016 and $4017, described in Section 8. See bits D4, D3, and
    D0.
 
    It is possible to have two Zapper units connected to both joypad
    ports simultaneously.
 
 
  C. Four-player devices
  ----------------------
    Some NES games allow the use of a four-player adapter, extending the
    number of usable joypads from two (2) to four (4). Carts which use
    the quad-player device are Tengen's "Gauntlet II," and Nintendo's
    "RC Pro Am 2."
 
    All four (4) controllers read their status-bits from D0 of $4016 or
    $4017, as Subsection A states.
 
    For register $4016, reads #1-8 control joypad #1, and reads #9-16
    control joypad #3. For $4017, it is respective for joypad #2 and #4.
 
    The following is a list of read #s and their results.


The following is a list of read #s and their results.
<pre>
       1 = A          9 = A        17 = +--+
       1 = A          9 = A        17 = +--+
       2 = B        10 = B        18 =    +-- Signature
       2 = B        10 = B        18 =    +-- Signature
Line 809: Line 698:
       7 = LEFT      15 = LEFT      23 = 0
       7 = LEFT      15 = LEFT      23 = 0
       8 = RIGHT    16 = RIGHT    24 = 0
       8 = RIGHT    16 = RIGHT    24 = 0
</pre>


    See Subsection G for information about Signatures.
The Famicom has a different four-player adapter.
On that system (not the NES), $4016 reads controllers 1 and 3 at the same time, with controller 1 in D0 and controller 3 in D1.
Likewise, $4016 returns controller 2 in D0 and controller 4 in D1.
In Famicom games that do not use four players, the player expects to be able to use controllers 3 and 4 as if they were controllers 1 and 2.


=== Paddles ===
Taito's ''Arkanoid'' uses a paddle as it's primary controller.


  D. Paddles
The paddle position on the Famicom version is read via D1 of $4017; the read data is inverted (0=1, 1=0).
  ----------
The first value read is the MSB, and the 8th value read is (obviously) the LSB.
    Taito's "Arkanoid"  uses a paddle as it's primary controller.
The valid value range is about 160 units wide.
One unit was measured with a range 98 to 242, where 98 represents the paddle being turned completely counter-clockwise.


    The paddle position is read via D1 of $4017; the read data is inverted
For example, if %01101011 is read, the value would be NOT'd, making %10010100 which is 146.
    (0=1, 1=0). The first value read is the MSB, and the 8th value read is
    (obviously) the LSB. Valid value ranges are 98 to 242, where 98 rep-
    resents the paddle being turned completely counter-clockwise.


    For example, if %01101011 is read, the value would be NOT'd, making
The paddle also contains one button, which is read via D1 of $4016.
    %10010100 which is 146.
A value of 1 specifies that the button is being pressed.


    The paddle also contains one button, which is read via D1 of $4016. A
On the NES version of the Arkanoid, D3 and D4 of $4017 are used instead.
    value of 1 specifies that the button is being pressed.
See [[Arkanoid controller]] for full information.


=== Signatures ===
A signature allows the programmer to detect if a device is connected to one of the four (4) ports or not, and if so, what type of device it is.


  E. Power Pad
The NES Four Score and NES Satellite have a signature in bits 17-24:
  ------------
* %0001 0000 = Joypad ($4016 only)
    No information is currently available.
* %0010 0000 = Joypad ($4017 only)


Other controllers may or may not have a signature.


  F. R.O.B. (Robot Operated Buddy)
=== Expansion ports ===
  --------------------------------
The joypad strobing process requires dual writes: 1, then 0.
    No information is currently available.
Some specialised controllers, especially for the Famicom's front expansion port, use a non-standard order for the strobing process.


 
For example, reading a Super NES Mouse while it is half strobed changes its sensitivity.
  G. Signatures
A program would execute the following code:
  -------------
<pre>
    A signature allows the programmer to detect if a device is connected
       LDA #%00000001     ; Begin half strobe
    to one of the four (4) ports or not, and if so, what type of device it
    is. Valid/known signatures are:
 
      %0000 = Disconnected
      %0001 = Joypad ($4016 only)
      %0010 = Joypad ($4017 only)
 
 
  H. Expansion ports
  ------------------
    The joypad strobing process requires dual writes: 1, then 0. If the
    strobing process is not completed, or occurs in a non-standard order,
    the joypads are no longer the item of communication: the expansion
    port is.
 
    For NES users, the expansion port is located on the bottom of the unit,
    covered by a small grey piece of plastic. Famicom users have a limited
    expansion port on the front of their unit, which was commonly used for
    joypads or turbo-joypads.
 
    Such an example of communicating with the expansion port would be the
    following code:
 
       LDA #%00000001
       STA $4016
       STA $4016
       STA $4017          ; Begin read mode of expansion port
       LDA $4017          ; Send one clock while half strobed
       LDA #%00000011     ; Write %110 to the expansion port
       LDA #%00000000     ; End half strobe
       STA $4016
       STA $4016
</pre>


    I have yet to encounter a cart which actually uses this method of
== Memory Mapping Hardware ==
    communication.
Due to the hundreds of different mappers in use, both discrete logic and integrated MMCs, this document cannot describe them all.
See [[Mapper]] for complete information.


== Registers ==
Programmers communicate with the PPU and pAPU via registers, which are nothing more than pre-set memory locations which allow the coder to make changes to the NES.
Without registers, programs would have no way to communicate with the outside world.


  I. Notes
Each register is a 16-bit address. Each register has a statistics field in parentheses located immediately after its description. The legend:
  --------
    None.
 
 
 
+----------------------------+
| 7. Memory Mapping Hardware |
+----------------------------+
 
  Due to the large number of mappers used (over 64), the "MMC" section
  which was once fluid in v0.53 of this document, has now been removed.
 
  All is not lost, as another document by \FireBug\ of Vertigo 2099 con-
  tains accurate information about nearly every mapper in existence. You
  can retrieve a copy via one of the following URLs:
 
    http://free.prohosting.com/~nintendo/mappers.nfo
 
  Please note I take no responsibility for the information contained in the
  aforementioned document. Contact lavos999@aol.com for more information.
 
 
 
+--------------+
| 8. Registers |
+--------------+
  Programmers communicate with the PPU and pAPU via registers, which are
  nothing more than pre-set memory locations which allow the coder to make
  changes to the NES. Without registers, programs wouldn't work: period.
 
  Each register is a 16-bit address. Each register has a statistics field
  in parentheses located immediately after its description. The legend:


     R = Readable                    W = Writable
     R = Readable                    W = Writable
     2 = Double-write register      16 = 16-bit register
     2 = Double-write register      16 = 16-bit register


  NOTE: 16-bit registers actually consist of two linear 8-bit registers,
Notes:
        which can (and will be) *INDEPENDANTLY* assigned. The reason for
        specifying them as 16-bit is for ease of documentation. For
        instance, "$4002+$4003" would mean that D15-D8 would be in $4003,
        and D7-D0 would be in $4002.
  NOTE: Bits not listed are to be considered unused.


* 16-bit registers actually consist of two linear 8-bit registers, which can (and will be) *INDEPENDENTLY* assigned. The reason for specifying them as 16-bit is for ease of documentation. For instance, "$4002+$4003" would mean that D15-D8 would be in $4003, and D7-D0 would be in $4002.
* Bits not listed are to be considered unused.
<pre>
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
     | Address | Description                                              |
     | Address | Description                                              |
Line 927: Line 771:
     |        |          0 = Disabled                                  |
     |        |          0 = Disabled                                  |
     |        |          1 = Enabled                                    |
     |        |          1 = Enabled                                    |
     |        |    D6: PPU Master/Slave Selection --+                   |
     |        |    D6: PPU Master/Slave Selection --+   Always write 0  |
     |        |          0 = Master                +-- UNUSED          |
     |        |          0 = Receive EXTBG        +-- in unmodified    |
     |        |          1 = Slave              --+                   |
     |        |          1 = Send EXTBG          --+   Control Deck    |
     |        |    D5: Sprite Size                                      |
     |        |    D5: Sprite Size                                      |
     |        |          0 = 8x8                                        |
     |        |          0 = 8x8                                        |
Line 950: Line 794:
     |  $2001  | PPU Control Register #2 (W)                              |
     |  $2001  | PPU Control Register #2 (W)                              |
     |        |                                                          |
     |        |                                                          |
     |        | D7-D5: Full Background Colour (when D0 == 1)            |
     |        | D7-D5: Colour Intensity                                  |
     |        |        000 = None +------------+                       |
     |        |        000 = None           +--+ NOTE: Some TVs don't  |
    |        |        001 = Green              | NOTE: Do not use more |
     |        |        001 = Intensify red      sync well if more   |
     |        |        010 = Blue              |       than one type   |
     |        |        010 = Intensify green    |   than one type used; |
    |        |        100 = Red   +------------+                      |
     |        |        100 = Intensify blue  +--+   PAL swaps D6/D5    |
     |        | D7-D5: Colour Intensity (when D0 == 0)                  |
    |        |        000 = None            +--+                      |
    |        |        001 = Intensify green    | NOTE: Do not use more |
    |        |        010 = Intensify blue    |      than one type   |
     |        |        100 = Intensify red  +--+                       |
     |        |    D4: Sprite Visibility                                |
     |        |    D4: Sprite Visibility                                |
     |        |          0 = Sprites not displayed                      |
     |        |          0 = Sprites not displayed                      |
Line 974: Line 813:
     |        |    D0: Display Type                                      |
     |        |    D0: Display Type                                      |
     |        |          0 = Colour display                            |
     |        |          0 = Colour display                            |
     |        |          1 = Monochrome display                         |
     |        |          1 = Monochrome display (all palette values    |
    |        |              ANDed with $30)                            |
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
     |  $2002  | PPU Status Register (R)                                  |
     |  $2002  | PPU Status Register (R)                                  |
Line 981: Line 821:
     |        |          0 = Not occuring                                |
     |        |          0 = Not occuring                                |
     |        |          1 = In VBlank                                  |
     |        |          1 = In VBlank                                  |
     |        |    D6: Sprite #0 Occurance                              |
     |        |    D6: Sprite #0 Hit                                    |
     |        |          0 = Sprite #0 not found                        |
     |        |          0 = Sprite #0 not found                        |
     |        |          1 = PPU has hit Sprite #0                       |
     |        |          1 = PPU has hit Sprite #0 since end of VBlank  |
     |        |    D5: Scanline Sprite Count                            |
     |        |    D5: Scanline Sprite Count                            |
     |        |          0 = Eight (8) sprites or less on current scan-  |
     |        |          0 = No scanline with more than eight (8)       |
     |        |              line                                        |
     |        |              sprites                                    |
     |        |          1 = More than 8 sprites on current scanline    |
     |        |          1 = At least one line with more than 8 sprites |
     |        |   D4: VRAM Write Flag                                  |
     |        |             since end of VBlank                        |
    |        |          0 = Writes to VRAM are respected                |
    |        |          1 = Writes to VRAM are ignored                  |
     |        |                                                          |
     |        |                                                          |
     |        | NOTE: D7 is set to 0 after read occurs.                  |
     |        | NOTE: D7 is set to 0 after read occurs.                  |
Line 997: Line 835:
     |        | NOTE: After a read occurs, $2006 is reset, hence the    |
     |        | NOTE: After a read occurs, $2006 is reset, hence the    |
     |        |      next write to $2006 will be the high byte portion. |
     |        |      next write to $2006 will be the high byte portion. |
    |        | NOTE: D4-D0 return the last value written to any PPU    |
    |        |      register.                                          |
     |        |                                                          |
     |        |                                                          |
     |        | For detailed information regarding D6, see Section 4,    |
     |        | For detailed information regarding D6, see Section 4,    |
Line 1,004: Line 844:
     |        |                                                          |
     |        |                                                          |
     |        | D7-D0: 8-bit address in SPR-RAM to access via $2004.    |
     |        | D7-D0: 8-bit address in SPR-RAM to access via $2004.    |
    |        |                                                          |
    |        | NOTE: The SPR-RAM DRAM controller is very touchy.        |
    |        |      Write $00 here.                                    |
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
     |  $2004  | SPR-RAM I/O Register (W)                                |
     |  $2004  | SPR-RAM I/O Register (W)                                |
     |        |                                                          |
     |        |                                                          |
     |        | D7-D0: 8-bit data written to SPR-RAM.                    |
     |        | D7-D0: 8-bit data written to SPR-RAM.                    |
    |        |                                                          |
    |        | NOTE: It is strongly recommended to use $4014 instead.  |
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
     |  $2005  | VRAM Address Register #1 (W2)                            |
     |  $2005  | VRAM Address Register #1 (W2)                            |
Line 1,034: Line 879:
     |  $4001  | pAPU Pulse #1 Ramp Control Register (W)                  |
     |  $4001  | pAPU Pulse #1 Ramp Control Register (W)                  |
     |  $4002  | pAPU Pulse #1 Fine Tune (FT) Register (W)                |
     |  $4002  | pAPU Pulse #1 Fine Tune (FT) Register (W)                |
     |  $4003  | pAPU Pulse #1 Coarse Tune (CT) Register (W)             |
     |  $4003  | pAPU Pulse #1 Coarse Tune (CT)/Length Register (W)       |
     |  $4004  | pAPU Pulse #2 Control Register (W)                      |
     |  $4004  | pAPU Pulse #2 Control Register (W)                      |
     |  $4005  | pAPU Pulse #2 Ramp Control Register (W)                  |
     |  $4005  | pAPU Pulse #2 Ramp Control Register (W)                  |
     |  $4006  | pAPU Pulse #2 Fine Tune Register (W)                    |
     |  $4006  | pAPU Pulse #2 Fine Tune Register (W)                    |
     |  $4007  | pAPU Pulse #2 Coarse Tune Register (W)                   |
     |  $4007  | pAPU Pulse #2 Coarse Tune/Length Register (W)           |
     |  $4008  | pAPU Triangle Control Register #1 (W)                   |
     |  $4008  | pAPU Triangle Linear Counter Register #1 (W)             |
     |  $4009  | pAPU Triangle Control Register #2 (?)                    |
     |  $4009  | Unused                                                  |
     |  $400A  | pAPU Triangle Frequency Register #1 (W)                 |
     |  $400A  | pAPU Triangle Fine Tune Register Register #1 (W)         |
     |  $400B  | pAPU Triangle Frequency Register #2 (W)                 |
     |  $400B  | pAPU Triangle Coarse Tune/Length Register #2 (W)         |
     |  $400C  | pAPU Noise Control Register #1 (W)                      |
     |  $400C  | pAPU Noise Control Register #1 (W)                      |
     |  $400D  | Unused (???)                                            |
     |  $400D  | Unused                                                   |
     |  $400E  | pAPU Noise Frequency Register #1 (W)                     |
     |  $400E  | pAPU Noise Frequency Register (W)                       |
     |  $400F  | pAPU Noise Frequency Register #2 (W)                     |
     |  $400F  | pAPU Noise Length Register (W)                           |
     |  $4010  | pAPU Delta Modulation Control Register (W)              |
     |  $4010  | pAPU Delta Modulation Control Register (W)              |
     |  $4011  | pAPU Delta Modulation D/A Register (W)                  |
     |  $4011  | pAPU Delta Modulation D/A Register (W)                  |
Line 1,057: Line 902:
     |        |  read from is $100*N, where N is the value written.      |
     |        |  read from is $100*N, where N is the value written.      |
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
     |  $4015  | pAPU Sound/Vertical Clock Signal Register (R)           |
     |  $4015  | pAPU Sound/APU Frame Counter Register (R)               |
     |        |                                                          |
     |        |                                                          |
     |        |    D6: Vertical Clock Signal IRQ Availability           |
     |        |    D6: APU Frame IRQ Availability                       |
     |        |          0 = One (1) frame occuring, hence IRQ cannot  |
     |        |          0 = One (1) frame occuring, hence IRQ cannot  |
     |        |              occur                                      |
     |        |              occur                                      |
Line 1,085: Line 930:
     |        | READING:                                                |
     |        | READING:                                                |
     |        |    D4: Zapper Trigger                                    |
     |        |    D4: Zapper Trigger                                    |
     |        |          0 = Pulled                                     |
     |        |          0 = Pulled or released                        |
     |        |          1 = Released (not held)                        |
     |        |          1 = Half pulled                                |
     |        |    D3: Zapper Sprite Detection                           |
     |        |    D3: Zapper Light Detection                           |
     |        |          0 = Sprite not in position                    |
     |        |          0 = Light in front of barrel                  |
     |        |          1 = Sprite in front of cross-hair              |
     |        |          1 = Dark in front of barrel                    |
    |        |    D1: Famicom Expansion Joypad Data                    |
     |        |    D0: Joypad Data                                      |
     |        |    D0: Joypad Data                                      |
     |        +----------------------------------------------------------+
     |        +----------------------------------------------------------+
Line 1,096: Line 942:
     |        |                                                          |
     |        |                                                          |
     |        |    D0: Joypad Strobe                                    |
     |        |    D0: Joypad Strobe                                    |
     |        |          0 = Clear joypad strobe                        |
     |        |          0 = Finish polling both joypads                |
     |        |          1 = Reset joypad strobe                        |
     |        |          1 = Poll both joypads                          |
    |        +----------------------------------------------------------+
    |        | WRITING:                                                |
    |        | Expansion Port Latch (W)                                |
    |        |                                                          |
    |        |    D0: Expansion Port Method                            |
    |        |          0 = Write                                      |
    |        |          1 = Read                                      |
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
     |  $4017  | Joypad #2/SOFTCLK (RW)                                  |
     |  $4017  | Joypad #2/SOFTCLK (RW)                                  |
     |        |                                                          |
     |        |                                                          |
     |        | READING:                                                |
     |        | READING:                                                |
    |        |    D7: Vertical Clock Signal (External)                  |
    |        |          0 = Not occuring                              |
    |        |          1 = Occuring                                  |
    |        |    D6: Vertical Clock Signal (Internal)                  |
    |        |          0 = Occuring    (D6 of $4016 affected)        |
    |        |          1 = Not occuring (D6 of $4016 untouchable)    |
     |        |    D4: Zapper Trigger                                    |
     |        |    D4: Zapper Trigger                                    |
     |        |          0 = Pulled                                     |
     |        |          0 = Pulled or released                        |
     |        |          1 = Released (not held)                        |
     |        |          1 = Half pulled                                |
     |        |    D3: Zapper Sprite Detection                           |
     |        |    D3: Zapper Light Detection                           |
     |        |          0 = Sprite not in position                    |
     |        |          0 = Light in front of barrel                  |
     |        |          1 = Sprite in front of cross-hair              |
     |        |          1 = Dark in front of barrel                    |
    |        |    D1: Famicom Expansion Joypad Data                    |
     |        |    D0: Joypad Data                                      |
     |        |    D0: Joypad Data                                      |
    |        +----------------------------------------------------------+
    |        | WRITING:                                                |
    |        | Expansion Port Latch (W)                                |
    |        |                                                          |
    |        |    D0: Expansion Port Method                            |
    |        |          0 = ???                                        |
    |        |          1 = Read                                      |
     +---------+----------------------------------------------------------+
     +---------+----------------------------------------------------------+
</pre>


== File Formats ==


 
=== iNES Format (.NES) ===
+-----------------+
Most common ROMs will be found in this format:
| 9. File Formats |
<pre>
+-----------------+
 
  A. iNES Format (.NES)
  ---------------------
     +--------+------+------------------------------------------+
     +--------+------+------------------------------------------+
     | Offset | Size | Content(s)                              |
     | Offset | Size | Content(s)                              |
Line 1,165: Line 990:
     | ..-EOF |      | CHR-ROM pages (in ascending order).      |
     | ..-EOF |      | CHR-ROM pages (in ascending order).      |
     +--------+------+------------------------------------------+
     +--------+------+------------------------------------------+
</pre>
See [[iNES]] for full details.


Some ROMs using more obscure mappers require an extension to the iNES format called "NES 2.0", first proposed by Kevin Horton.
See [[NES 2.0]] for full details.


== Programming the NES ==


+-------------------------+
=== General Information ===
| 10. Programming the NES |
None.
+-------------------------+


  A. General Information
=== CPU Notes ===
  ----------------------
None.
    None.
See "CPU Notes" in Section 11 "Emulation" for more possible information.


=== PPU Notes ===


  B. CPU Notes
Reading and writing to VRAM consists of a multi-step process:
  ------------
<pre>
    None. See Section 11, Subsection B for more possible information.
 
 
  C. PPU Notes
  ------------
    Reading and writing to VRAM consists of a multi-step process:
 
       Writing to VRAM                    Reading from VRAM
       Writing to VRAM                    Reading from VRAM
       ---------------                    -----------------
       ---------------                    -----------------
Line 1,193: Line 1,016:
       3) Write lower VRAM address        3) Write lower VRAM address
       3) Write lower VRAM address        3) Write lower VRAM address
         byte into $2006                    byte into $2006
         byte into $2006                    byte into $2006
       4) Write data to $2007            4) Read $2007 (invalid data once)
       4) Write one or more bytes        4) Read $2007 (invalid data once)
                                        5) Read data from $2007
        to $2007                        5) Read one or more bytes
 
                                            from $2007
    NOTE: Step #4 when reading VRAM is only necessary when reading
</pre>
          VRAM data not in the $3F00-3FFF range.
NOTE: Step #4 when reading VRAM is only necessary when reading VRAM data not in the $3F00-3FFF range.
 
    NOTE: Accessing VRAM should only be performed during VBlank. Attempts
          to access VRAM outside of VBlank will usually result in garbage
          showing up on the screen. See Section 4, Subsection N for more
          information regarding why this occurs.
 
    Waiting for VBlank is quite simple:
 
      8000: LDA $2002
            BPL $8000


    Reading $2002 will result in all bits being returned; however, D7
NOTE: If VBlank has not yet ended, steps #2-5 may be repeated in order to read or write at a different address.  VBlank lasts at least 2,200 CPU cycles.
    will be reset to 0 after the read is performed.


    The actual on-screen palette used by the NES, as stated prior, is not
NOTE: Accessing VRAM should only be performed during VBlank, or with rendering turned off ($2001 D4-D3 cleared to 0).
    RGB. However, a near-exact replica can be found in common NES emulators
Attempts to access VRAM outside of VBlank will usually result in garbage showing up on the screen.
    today. Contact the appropriate authors of these emulators to obtain
See Section 4, Subsection N for more information regarding why this occurs.
    a valid RGB palette.


    Be sure to clear the internal VRAM address via $2006 semi-often. You
Waiting for VBlank is quite simple:
    will often encounter a situation where a palette fade or a VRAM update
    will cause the screen "to be trashed" (squares on the screen, or what
    seem to be graphical "glitches"). The reason for this is that your code
    took longer than a VBlank. When the VBlank goes to refresh the screen
    with the data in the PPU, it takes whatever value is in the internal
    VRAM address and uses that as the starting base for Name Table #0.
    The solution is to fix your code by re-assigning the VRAM address to
    $0000 (or $2000), so that the refresh may occur successfully. Such
    code would be:
 
      LDA #$00
      STA $2006
      STA $2006


    You will find code like this in commercial games quite often.
      FEE0: LDA $2002
            BPL $FEE0


Reading $2002 will result in all bits being returned; however, D7 will be reset to 0 after the read is performed.
To ensure the PPU is warmed up, this should be done twice before the first access to $2003-$2007.


Waiting for VBlank during a game should be done by waiting for the NMI handler to change a variable:


+---------------+
      8000: INC $FF
| 11. Emulation |
            RTI
+---------------+
     
      8100: LDA $FF
      8102: CMP $FF
            BEQ $8102


  A. General Information
The actual on-screen palette used by the NES, as stated prior, is not RGB.
  ----------------------
However, a near-exact replica can be found in common NES emulators today.
    If you're going to be programming an emulator in C or C++, please be
See [[PPU palettes]] to obtain a valid RGB palette.
    familiar with pointers. Being familiar with pointers will help you
    out severely when it comes to handling mirroring and VRAM addressing.
    For you assembly buffs out there, obviously pointers are nothing more
    than indirect addressing -- it's easier to change a 32-bit value than
    to swap in and out an entire 64K of data.


    When SRAM ($6000-7FFF) is disabled, writes to the memory area should
You will often encounter a situation where a palette fade or a VRAM update will cause the screen "to be trashed" (squares on the screen, or what seem to be graphical "glitches").
    be ignored. Reads will possibly return data previously left on the
The reason for this is that your code took longer than a VBlank.
    bus, and therefore when emulated should return 0 (or should be trap-
When the VBlank ends, the PPU begins to refresh the screen again, taking whatever value is in the internal VRAM address and uses that as the starting base for Name Table #0.
    ped).
The solution is to fix your code to take no more than 2273 cycles, which is 20 scanlines times 341 pixels per scanline divided by 3 pixels per cycle.


    RAM-based memory areas ($0000-07FF) should *NOT* be zeroed on RESET;
In addition, after you update video memory through $2006 and $2007, the scroll position becomes corrupt, and the PPU again begins at the internal VRAM address.
    they should be zeroed on power on/off. (Technically, the RAM is not
To solve this, make sure to reset the scroll position through $2005 and $2000 before the next frame begins.
    zeroed on power on/off either: the RAM will slowly dissapate over
Such code would be:
    time when the unit it off. However, for emulation purposes, please
    make sure that a cold boot and a warm boot do different things).


    See Section 12, Subsection E for Mailing List information.
      LDA #$00
      STA $2005
      STA $2005
      LDA #$88
      STA $2000


If your game scrolls, use different values for $2005 and for $2000 D1-D0.


  B. CPU Notes
== Emulation ==
  ------------
    The NES does not use a 65c02 (CMOS) CPU as rumored.


    Ignore opcodes which are bad (or support the option of trapping them).
=== General Information ===
    Some ROM images out there, such as "Adventures of Lolo" contain bad
    opcodes, due to dirty connectors on the cartridge during the extract-
    ion process (or other reasons).


    There are 154 valid opcodes (out of 256 total) on the NES.
If you're going to be programming an emulator in C or C++, please be familiar with pointers.
Being familiar with pointers will help you out severely when it comes to handling mirroring and VRAM addressing.
For you assembly buffs out there, obviously pointers are nothing more than indirect addressing -- it's easier to change a 32-bit value than to swap in and out an entire 64K of data.


When SRAM ($6000-7FFF) is disabled, writes to the memory area should be ignored.
Reads will possibly return data previously left on the bus, and therefore when emulated should return the previous bus value.
This will usually (but not always) be the high byte of the address.
See [[Open bus]] for more details.


  C. PPU Notes
RAM-based memory areas ($0000-07FF) should *NOT* be zeroed on RESET; they should be set to some value on power on.
  ------------
Please make sure that a cold boot and a warm boot do different things.
    The formulae to calculate the base address of a Name Table tile number
(Technically, the RAM is not zeroed on power on either: the RAM will slowly dissipate over time when the unit is off.)
    is:


      (TILENUM * 16) + PATTERNTABLE
=== CPU Notes ===
The NES uses the NMOS 6502, not a CMOS 6502 or any other variant.


    Where TILENUM is the tile number in the Name Table, and PATTERNTABLE
There are 154 valid opcodes (out of 256 total) on the NES.
    is the Pattern Table Address defined via register $2000.
Please support the option of trapping opcodes which are bad.
Sometimes a ROM contains bad opcodes, due to dirty connectors on the cartridge during the extraction process (or other reasons).
But other games out there, such as ''Puzznic'' and ''Super Cars'', contain bad opcodes even in a correct dump.


    It's recommended that DOS programmers use what is known as "MODE-Q,"
=== PPU Notes ===
    a 256x256x256 "tweaked" video mode, for writing their emulator. Try to
    avoid Mode-X modes, as they are non-chained, and result in painfully
    slow graphics. Chained modes (like MODE-13h) are linear, and work
    best for speedy graphics. Since the NES's resolution is 256x240, the
    aforementioned "MODE-Q" should meet all necessary requirements.


    Most emulators do not limit the number of sprites which can be displayed
The formulae to calculate the base address of a Name Table tile number is:
    per scanline, while the actual NES will show flicker as a result of more
    than eight (8). {Put some more garbage here; it's early...}


    Emulators should _NOT_ mask out unused bits within registers; doing so
(TILENUM * 16) + PATTERNTABLE
    may result in a cart not working.


Where TILENUM is the tile number in the Name Table, and PATTERNTABLE is the Pattern Table Address defined via register $2000.


  D. APU Notes
Most emulators do not limit the number of sprites which can be displayed per scanline, while the actual NES will show flicker as a result of more than eight (8).
  ------------
One supports 15 sprites per line by changing the order of sprite-related Pattern Table fetches during HBlank.
    To be written.


Emulators should _NOT_ mask out unused bits within registers; doing so may result in a cart not working.


== Reference Material ==
Many of these no longer exist:


+------------------------+
=== Mailing Lists ===
| 12. Reference Material |
There is a NES Development Mailing List in existence.
+------------------------+
Contact Mark Knibbs for more information.
This list is for anyone who wishes to discuss technical issues about the NES; it is not a list for picking up the latest and greatest information about NES emulators or what not.


  A. CPU Information
However, most users have since migrated to a phpBB forum at https://forums.nesdev.org/
  ------------------
    None.


=== WWW Sites ===
The following are a list of WWW sites which contain NES-oriented material.
If you encounter errors, bad links, or other anomalies while visiting these sites, contact the site authors/owners, NOT me. Thanks.


  B. PPU Information
  ------------------
    None.


; https://nesdev.org/
: Contains a verbose amount of documentation regarding anything NES-oriented, including hard-to-find mapper documentation. Seems to be a decent NES information depository.
; http://www.ameth.org/~veilleux/NES_info.html
: Currently only contains hardware-oriented material, such as overviews of cart and unit ASICs, mappers, and MMCs. Many pinout diagrams for mappers and NES units are available here. Also provides documentation on NES repair, modifying your NES to give fake stereo output, applying stereo mixing to your NES, and much much more.


  C. APU Information
=== Hardware Information ===
  ------------------
The following security bits may be purchased from MCM Electronics (http://www.mcmelectronics.com/):
    None.


* For NES, Game Boy, Super NES, and Nintendo 64 Game Paks: 22-1145 (3.8mm security bit)
* For NES, Super NES, and Nintendo 64 Control Deck: 22-1150 (4.5mm security bit)


  D. MMC Information
Other sellers may offer them under the "Line" or "GameBit".
  ------------------
    None.
 
 
  E. Mailing Lists
  ----------------
    There is a NES Development Mailing List in existence. Contact Mark Knibbs
    for more information. This list is for anyone who wishes to discuss tech-
    nical issues about the NES; it is not a list for picking up the latest
    and greatest information about NES emulators or what not.
 
 
  F. WWW Sites
  ------------
    The following are a list of WWW sites which contain NES-oriented
    material. If you encounter errors, bad links, or other anomolies
    while visiting these sites, contact the site authors/owners, NOT
    me. Thanks.
 
    http://nesdev.parodius.com/
 
      Contains a verbose amount of documentation regarding anything
      NES-oriented, including hard-to-find mapper documentation. Seems
      to be a decent NES information depository.
 
    http://www.ameth.org/~veilleux/NES_info.html
 
      Currently only contains hardware-oriented material, such as
      overviews of cart and unit ASICs, mappers, and MMCs. Many
      pinout diagrams for mappers and NES units are available here.
      Also provides documentation on NES repair, modifying your NES
      to give stereo output, applying stereo mixing to your NES, and
      much much more.
 
 
  G. Hardware Information
  -----------------------
    The following security bits may be purchased from MCM Electronics
    (http://www.mcmelectronics.com/):
 
      For NES carts: 22-1145 (3.8mm security bit)
      For NES units: 22-1150 (4.5mm security bit)
 
    The 4.5mm security screw is also used for the Super Nintendo Enter-
    tainment System (SNES), and Nintendo 64.
 
 
</pre>


An alternate method is to cut a notch in a standard flat head screwdriver that grips two of the six indentations on the screw.


== See also ==
== See also ==

Latest revision as of 15:46, 16 November 2021

This is an updated version of "Nintendo Entertainment System Documentation" by Jeremy Chadwick, aka "koitsu". It provides a brief overview of the NES hardware and may prove easier to understand, particularly for programmers new to the NES, than some of the other, more technical documentation on this wiki.

Introduction

Disclaimer

I am in no way held responsible for the results of this information. This is public-domain information. I am not trying to hinder anyone financially: if you wish to do development on Nintendo's current platforms, contact Nintendo via developer.nintendo.com.

All titles of cartridges and console systems are trademarks of their respective owners. (I just don't deem it necessary to list every single one by hand.)

Why?

At the time this document was created, there was only one piece of literature covering the internals to the NES: Marat Fayzullin's documentation, otherwise known as "NES.DOC".

While Fayzullin's documentation was lacking in many areas, it provided a strong base for the basics, and in itself truly stated how complex the little grey box was.

I took the opportunity to expand on "NES.DOC," basing other people's findings, as well as my own, on experience; experience which has helped make this document what it has become today. The beginning stages of this document looked almost like a replica of Fayzullin's documentation, with both minor and severe changes. Marat Fayzullin himself later picked up a copy of my documentation, and later began referring people to it.

Keep in mind, without Marat's "NES.DOC" document, I would have never had any incentive to write this one.

Mission

The goal of this document is simplistic: to continue providing accurate, understandable, and up-to-date information regarding the Nintendo Entertainment System and its Famicom counterpart.

Dedications

I'd like to dedicate this document to Alex Krasivsky. Alex has been a great friend, and in my eyes, truly started the ball of emulation rolling. During the good times, and the bad times, Alex was there. Spasibo, Alex; umnyj Russki...

"Thank You"s

I'd like to take the time and thank all the people who helped make this document what it is today. I couldn't have done it without all of you.

      Alex Krasivsky
      Andrew Davie
      Avatar Z
      Barubary
      Bluefoot
      CiXeL
      Chi-Wen Yang
      Chris Hickman
      D
      Dan Boris
      David de Regt
      Donald Moore
      Fredrik Olsson
      Icer Addis
      Jon Merkel
      Kevin Horton
      Loopy
      Marat Fayzullin
      Mark Knibbs
      Martin Nielsen
      Matt Conte
      Matthew Richey
      Memblers
      MiKael Iushin
      Mike Perry
      Morgan Johansson
      Neill Corlett
      Pat Mccomack
      Patrik Alexandersson
      Paul Robson
      Ryan Auge
      Stumble
      Tennessee Carmel-Veilleux
      Thomas Steen
      Tony Young
      Vince Indriolo
      \FireBug\

Special thanks goes out to Stumble, for providing a myriad of information over IRC, while avoiding sleep to do so.

Acronyms

Internals

CPU
Central Processing Unit: Self-explanatory. The NES uses a standard 6502 (NMOS).
PPU
Picture Processing Unit: Used to control graphics, sprites, and other video-oriented features.
pAPU
pseudo-Audio Processing Unit: Native to the CPU; generates waveforms via (5) audio channels:: four (4) analogue, and one (1) digital. There is no separate IC for audio processing nor generation inside the NES.
MMC
Multi-Memory Controller or Memory Management Controller: Integrated circuits used in NES games to access memory beyond the 6502 64Kbyte boundary. They can also be used to access extra CHR-ROM, and may be used for "special effects" such as forcing an IRQ, and other things.
VRAM
Video RAM: The RAM which is internal to the PPU. There is 16kbits of VRAM installed in the NES.
SPR-RAM
Sprite RAM: 256 bytes of RAM which is used for sprites. It is not part of VRAM nor ROM, though it's local to the PPU.
OAM
Object Attribute Memory: Synonymous with SPR-RAM.
PRG-ROM
Program ROM: The actual program-code area of memory. Also can be used to describe areas of code which are external to the actual code area and are swapped in via an MMC.
PRG-RAM
Program RAM: Synonymous with PRG-ROM, except that it's RAM.
CHR-ROM
Character ROM: The VRAM data which is kept external to the PPU, swapped in and out via an MMC, or "loaded" into VRAM during the power-on sequence.
VROM
Synonymous with CHR-ROM.
SRAM
Save RAM: RAM which is commonly used in RPGs such as Crystalis, the Final Fantasy series, and The Legend of Zelda.
WRAM
Work RAM: Synonymous with SRAM.
DMC
Delta Modulation Channel: The channel of the APU which handles digital data. Commonly referred to as the PCM (Pulse Code Modulation) channel.
EX-RAM
Expansion RAM: This is the memory used within Nintendo's MMC5, allowing games to extend the capabilities of VRAM.

Hardware

NES
Nintendo Entertainment System: Self-explanatory.
Famicom
Family Computer: Synonymous with the NES, except for also supporting external audio synthesizers in the cartridge.
FDS
Famicom Disk System: Unit which sits atop the Famicom, supporting the use of 3" double-sided floppy disks for games.
Dendy
Third-party clone of the Famicom for PAL TV systems, distributed in Russia and elsewhere in the East.

CPU

General Information

The NES uses a customized NMOS 6502 CPU, engineered and produced by Ricoh. Its primary customization adds audio.

Different regional variants of the NES run the CPU different clock speeds.

  • The Famicom and NTSC NES runs at 1.789773 MHz.
  • The PAL NES runs at 1.662607 MHz.
  • The Dendy and other PAL famiclones run at 1.773448 MHz.

Memory Map

    +---------+-------+-------+-----------------------+
    | 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   | $1FE0 |       | Expansion I/O         |
    | $6000   | $2000 |       | SRAM                  |
    | $8000   | $4000 |       | PRG-ROM               |
    | $C000   | $4000 |       | PRG-ROM               |
    +---------+-------+-------+-----------------------+
           Flag Legend: M = Mirror of $0000
                        R = Mirror of $2000-2008 every 8 bytes
                            (e.g. $2008=$2000, $2018=$2000, etc.)

Interrupts

The 6502 has three (3) interrupts: IRQ/BRK, NMI, and RESET.

Each interrupt has a vector. A vector is a 16-bit address which specifies a location to "jump to" when the interrupt is triggered.

IRQ/BRK is triggered under two circumstances, hence it's split name: when a software IRQ is executed (the BRK instruction), or when a hardware IRQ is executed (via the IRQ line).

RESET is triggered on power-up. The ROM is loaded into memory, and the 6502 jumps to the address specified in the RESET vector. No registers are modified, and no memory is cleared; these only occur during power-up.

NMI stands for Non-Maskable Interrupt, and is generated by each refresh (VBlank), which occurs at different intervals depending upon the system used (PAL/NTSC).

NMI is updated 60 times/sec. on NTSC consoles, and 50 times/sec on PAL. Interrupt latency on the 6502 is seven (7) cycles; this means it takes seven (7) cycles to move in and out of an interrupt.

Most interrupts should return using the RTI instruction. Some NES carts do not use this method, such as SquareSoft's Final Fantasy title. These carts return from interrupts in a very odd fashion: by manipulating the stack by hand, and then doing an RTS. This is technically valid, but morally shunned.

The aforementioned interrupts have the following vector addresses, mapped to areas of ROM:

  • $FFFA = NMI
  • $FFFC = RESET
  • $FFFE = IRQ/BRK

Interrupt priorities are as follows:

  • RESET (highest)
  • NMI
  • IRQ/BRK (lowest)

NES-specific Customizations

The NES's 6502 does not contain support for decimal mode. Both the CLD and SED opcodes function normally, but the 'd' bit of P is unused in both ADC and SBC. It is common practice for games to CLD prior to code execution, as the status of 'd' is unknown on power-on and on reset.

Audio registers are mapped internal to the CPU; all waveform generation is done internal to the CPU as well.

Notes

Please note the two separate 16K PRG-ROM segments; they may be linear, but they play separate roles depending upon the size of the cartridge. Some games only hold one (1) 16K bank of PRG-ROM, which should be loaded into both $C000 and $8000.

Most games load themselves into $8000, using 32K of PRG-ROM space. The first game to use this method is _Super Mario Bros._ However, almost all games with more than one (1) 16K bank of PRG-ROM load themselves into $8000 as well. These games use Memory Mappers to swap in and out PRG-ROM data, as well as CHR-ROM. A few Memory Mappers, especially on later games, allow swapping in half of a 16K segment.

When a BRK is encountered, the NES's 6502 pushes the CPU status flag onto the stack with the 'b' CPU bit set. On an IRQ or NMI, the CPU pushes the status flag onto the stack with the 'b' bit clear. This is done because of the fact that a hardware IRQ (IRQ) and a software IRQ (BRK) both share the same vector. For example, one could use the following code to distinguish the difference between the two:

      C134: PLA                 ; Copy CPU status flag
      C135: PHA                 ; Return status flag to stack
      C136: AND #$10            ; Check D4 ('b' CPU bit)
      C138: BNE is_BRK_opcode   ; If set then it is a software IRQ (BRK)

Executing BRK inside of an interrupt handler (IRQ or NMI) will result in the pushed 'b' bit being set.

The 6502 has a bug in opcode $6C (jump absolute indirect). The CPU does not correctly calculate the effective address if the low-byte is $FF. Example:

      C100: EF
      C1FF: 00
      C200: C3
        ..
      D000: 6C FF C1 - JMP ($C1FF)

Logically, this will jump to address $C300. However, due to the fact that the high-byte of the calculate address is *NOT* increased on a page-wrap, this will actually jump to $EF00.

It should be noted that page wrapping does *NOT* occur in indexed-indirect addressing modes. Due to limitations of zero-page, all indexed-indirect read/writes should apply a logical AND #$FF to the effective address after calculation. Example:

      C000: LDX #3        ; Reads indirect address from $0002+$0003,
      C002: LDA ($FF,X)   ;   not $0102+$0103.

PPU

General Information

Mirroring (also referred to as "shadowing") is the process of mapping particular addresses or address ranges to other addresses/ranges via hardware.

Memory Map

Included here are two (2) memory maps. The first is a "RAM Memory Map," which despite being less verbose describes the actual regions which point to physical memory in the NES Control Deck and most Game Paks. The second is a "Programmer Memory Map" which is quite verbose and describes the entire memory region of the NES and how it's used/manipulated.

        RAM Memory Map
      +---------+-------+----------------+
      | Address | Size  | Description    |
      +---------+-------+----------------+
      | $0000   | $2000 | Pattern Tables |
      | $2000   | $800  | Name Tables    |
      | $3F00   | $20   | Palettes       |
      +---------+-------+----------------+

        Programmer Memory Map
      +---------+-------+-------+--------------------+
      | 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 = Either CHR-ROM or CHR-RAM
                          N = Mirrored (see Subsection G)
                          P = Mirrored (see Subsection H)
                          R = Mirror of $2000-2EFF (VRAM)
                          F = Mirror of $0000-3FFF (VRAM)

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).

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 glyph for the letter 'A', as shown in the "Colour Result" section in the upper right.

Attribute Tables

Each byte in an Attribute Table represents a 4x4 group of tiles on the screen. There are 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 corres 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)

Palettes

The NES has two 16-colour "palettes": the Image Palette and the Sprite Palette. These palettes are more of a "lookup table" than an actual palette, since they do not hold physical RGB values. They're actually closer to HSV, with lightness in D5-D4 and hue in D3-D0.

D7-D6 of bytes written to $3F00-3FFF are ignored.

For details see PPU palettes and NTSC video.

Name Table Mirroring

One should keep in mind that there are many forms of mirroring when understanding the NES. Some methods even use CHR-ROM-mapped Name Tables (mapper-specific).

The NES itself only contains 2048 ($800) bytes of RAM used for Name Tables. However, as shown in Subsection B, the NES has the capability of addressing up to four (4) Name Tables.

By default, many carts come with "horizontal" and "vertical" mirroring, allowing you to change where the Name Tables point into the NES's PPU RAM. This form of mirroring affects two (2) Name Tables simultaneously; you cannot switch Name Tables independently.

The following chart should assist in understanding all the types of mirroring encountered on the NES. Please note that the addresses shown (12-bit in size) refer to VRAM. Mirroring determines how raw addresses in VRAM are translated into addresses that the PPU sees in the "$2xxx" region.

        Name                       NT#0   NT#1   NT#2   NT#3   Flags
      +--------------------------+------+------+------+------+-------+
      | Horizontal               | $000 | $000 | $400 | $400 |       | 
      | Vertical                 | $000 | $400 | $000 | $400 |       | 
      | Four-screen              | $000 | $400 | $800 | $C00 | F     | 
      | Single-screen            |      |      |      |      |  S    | 
      | CHR-ROM mirroring        |      |      |      |      |   C   |
      +--------------------------+------+------+------+------+-------+
        F = Four-screen mirroring relies on an extra 2048 ($800) of RAM
            (kept on the cart), resulting in four (4) physical independent
            Name Tables.
        S = Single-screen games have mappers which allow you to select
            which PPU RAM area you want to use ($000, $400, $800, or
            $C00); all the NTs point to the same PPU RAM address.
        C = Mapper #68 (Afterburner 2) allows you to map CHR-ROM to the
            Name Table region of the NES's PPU RAM area. Naturally this
            makes the Name Table ROM-based, and one cannot write to it.
            However, this feature can be controlled via the mapper itself,
            allowing you to enable or disable this feature.

Palette Mirroring

Mirroring occurs between the Background Palette and the Sprite Palette on addresses that are multiples of 4. Any data which is written to $3F00 is mirrored to $3F10. Any data written to $3F04 is mirrored to $3F14, etc. etc...

Colour #0 in the upper three (3) palettes of both the Image and Sprite palette defines transparency (the actual colour stored there is not drawn on-screen).

In most cases, the PPU uses the value in $3F00 to define background colour.

For a more verbose explanation, assume the following:

  • $0D has been written to $3F00 (mirrored to $3F10)
  • $03 has been written to $3F08 (mirrored to $3F18)
  • $1A has been written to $3F18
  • $3F08 is read into the accumulator

The PPU will use $0D as the background colour, despite $3F08 holding a value of $03 (since colour #0 in all the palette entries defines transparency, it is not drawn). Finally, the accumulator will hold a value of $1A, which is mirrored from $3F18. Again, the value of $1A is not drawn, since colour #0 defines transparency.

The entire Background and Sprite Palettes are both mirrored to other areas of VRAM as well; $3F20-3FFF are mirrors of both palettes, respectively.

Again, D7-D6 of bytes written to $3F00-3FFF are ignored.

Background Scrolling

The NES can scroll the background (pre-rendered Name Table + Pattern Table + Attribute Table) independently of the sprites which are overlaid on top of it. The background can be scrolled horizontally and vertically.

Scrolling works as follows:

      Horizontal Scrolling             Vertical Scrolling
        0          512
        +-----+-----+                      +-----+ 0
        |     |     |                      |     |
        |  A  |  B  |                      |  A  |
        |     |     |                      |     |
        +-----+-----+                      +-----+
                                           |     |
                                           |  B  |
                                           |     |
                                           +-----+ 480

Name Table "A" is specified via Bits D1-D0 in register $2000, and "B" is the Name Table after (due to mirroring, this is dynamic). Games which use Horizontal & Vertical scrolling simultaneously need special attention paid to mirroring.

The background will span across multiple Name Tables, as shown here:

      +---------------+---------------+
      | Name Table #0 | Name Table #1 |
      |    ($2000)    |    ($2400)    |
      +---------------+---------------+
      | Name Table #2 | Name Table #3 |
      |    ($2800)    |    ($2C00)    |
      +---------------+---------------+

But depending on mirroring, some of them will be repeated:

      Horizontal Mirroring
      +---------------+---------------+
      | Name Table #0 | Duplicate #0  |
      |    ($2000)    |    ($2400)    |
      +---------------+---------------+
      | Name Table #2 | Duplicate #2  |
      |    ($2800)    |    ($2C00)    |
      +---------------+---------------+


      Vertical Mirroring
      +---------------+---------------+
      | Name Table #0 | Name Table #1 |
      |    ($2000)    |    ($2400)    |
      +---------------+---------------+
      | Duplicate #0  | Duplicate #1  |
      |    ($2800)    |    ($2C00)    |
      +---------------+---------------+

Writes to the Horizontal Scroll value in $2005 range from 0 to 255. Writes to the Vertical Scroll value range from 0-239. Vertical Scroll values above 239 are considered negative (e.g. a write of 248 is really -8). This is because values above 239 cause the PPU to interpret Attribute Table data as Name Table data.

Screen and Sprite Layering

There is a particular order in which the NES draws its contents:

      FRONT                                BACK
      +----+-----------+----+-----------+-----+
      | CI | OBJs 0-63 | BG | OBJs 0-63 | EXT |
      +----+-----------+----+-----------+-----+
           | SPR-RAM   |    | SPR-RAM   |
           | BGPRI==0  |    | BGPRI==1  |
           +-----------+    +-----------+

CI stands for 'Colour Intensity', or 'Emphasis', or 'Tint', set in D7-D5 of $2001. BG is the BackGround. EXT is for the EXTension port video signal (not available in a stock NES).

'BGPRI' represents the 'Background Priority' bit in SPR-RAM, on a per-sprite basis (D5, Byte 2).

OBJ numbers represent actual Sprite numbers, not Tile Index values.

FRONT is considered what is seen atop all other layers (drawn last), and BACK is deemed what is below most other layers (drawn first).

If a sprite with BGPRI==1 has a lower index in SPR-RAM than a sprite with BGPRI==0, the front-to-back ordering is more complicated. See PPU sprite priority for full details.

Sprites and OAM

The NES supports 64 sprites, which can be either 8x8 or 8x16 pixels in size. The sprite data is kept within the Pattern Table region of VRAM.

Sprite attributes such as flipping and priority, are stored in SPR-RAM, which is a separate 256 byte area of memory, independent of ROM and VRAM. The format of SPR-RAM is as follows:

      +-----------+-----------+-----+------------+
      | Sprite #0 | Sprite #1 | ... | Sprite #63 |
      +-+------+--+-----------+-----+------------+
        |      |   
        +------+----------+--------------------------------------+
        + Byte | Bits     | Description                          |
        +------+----------+--------------------------------------+
        |  0   | YYYYYYYY | Y Coordinate - 1. Consider the coor- |
        |      |          | dinate the upper-left corner of the  |
        |      |          | sprite itself.                       |
        |  1   | IIIIIIII | Tile Index #                         |
        |  2   | vhp000cc | Attributes                           |
        |      |          |   v = Vertical Flip   (1=Flip)       |
        |      |          |   h = Horizontal Flip (1=Flip)       |
        |      |          |   p = Background Priority            |
        |      |          |         0 = In front                 |
        |      |          |         1 = Behind                   |
        |      |          |   c = Upper two (2) bits of colour   |
        |  3   | XXXXXXXX | X Coordinate (upper-left corner)     |
        +------+----------+--------------------------------------+

The Tile Index # is obtained the same way as Name Table data.

Sprites which are 8x16 in size function a little bit differently. An 8x16 sprite which has an even-numbered Tile Index # use the Pattern Table at $0000 in VRAM; odd-numbered Tile Index #s use $1000.

  • NOTE*: Register $2000 D3 has no effect on 8x16 sprites.

All 64 sprites contain an internal priority; sprite #0 is of a higher priority than sprites #63 (sprite #0 should be drawn last, etc.).

Only eight (8) sprites can be displayed per scan-line. Each entry in SPR-RAM is checked to see if it's in a horizontal range with the other sprites. Remember, this is done on a per scan-line basis, not on a per sprite basis (e.g. done 256 times, not 256/8 or 256/16 times).

NOTE: On a real NES unit, if both background and sprites are disabled (D4-D3 of $2001 is 00) for a long period of time, SPR-RAM will gradually degrade. Photographs of a decapped PPU have confirmed that SPR-RAM is actually DRAM, and rendering controls the DRAM refresh cycle.

Sprite #0 Hit Flag

The PPU is capable of figuring out where Sprite #0 is, and stores its findings in D6 of $2002. The way this works is as follows:

As the PPU draws each line, it scans for the first actual non-transparent "sprite pixel" and the first non-transparent "background pixel." A "background pixel" is a tile which is in use by the Name Table. Remember that colour #0 defines transparency.

The pixel which causes D6 to be set *IS* drawn.

The following example should help. The following are two tiles. Transparent colours (colour #0) are defined via the underscore ('_') character. An asterisk ('*') represents when D6 will be set.

       Sprite         BG         Result
       ------         --         ------
      __1111__     ________     __1111__
      _111111_     _______2     _1111112    
      11222211     ______21     11222211
      112__211  +  _____211  =  112__*11  '*' will be drawn as colour #2
      112__211     ____2111     112_2211
      11222211     ___21111     11222211
      _111111_     __211111     _1111111
      __1111__     _2111111     _2111111

This also applies to sprites that are underneath the BG (via the 'Background Priority' SPR-RAM bit), though the above example would be 'BG+Sprite'.

However, D6 does not get set if the overlap is at the far right of the screen (X==255).

Also, D6 is cleared (set to 0) at the end of each VBlank.

Horizontal and Vertical Blanking

The NES, like every console, has a refresh: where the display device relocates the electron gun to display visible data. The most common display device is a television set. The refresh occurs 60 times a second on an NTSC device, and 50 on a PAL device.

The gun itself draws pixels left to right: this process results in one (1) horizontal scanline being drawn. After the gun is done drawing the entire scanline, the gun must return to the left side of the display device, becoming ready to draw the next scanline. The process of the gun returning to the left side of the display is the Horizontal Blank period (HBlank).

When the gun has completed drawing all of the scanlines, it must return to the top of the display device. The time it takes for the gun to re-position itself atop the device is called the Vertical Blank period (VBlank).

As you can see from the below diagram, the gun more or less works in a zig-zag pattern until VBlank is reached, then the process repeats:

           +-----------+
      +--->|***********| <-- Scanline 0
      |    | ___---~~~ | <-- HBlank
      V    |***********| <-- Scanline 1
      B    | ___---~~~ | <-- HBlank
      l    |    ...    |      ...
      a    |    ...    |      ...
      n    |***********| <-- Scanline 239
      k    +-----+-----+
      |          |
      +--VBlank--+

The screen is 256 pixels wide, and the HBlank time that follows each line adds an additional 85 for a total of 341.

An NTSC NES has the following refresh and screen layout:

      0       256 340
      +--------+   |   0 --+
      |        |   |       |
      |        | H |       |
      | Screen | B |       +-- (0-239) 256x240 on-screen results
      |        | l |       |
      |        |   |       |
      +--------+   | 239 --+
      +--------+     240 --+-- (240) Post-render
      +--------+     241 --+
      |        |           |
      | VBlank |           +-- (241-260) VBlank
      |        |           |
      +--------+     260 --+
      +--------+     261 --+-- (261) Pre-render

The Vertical Blank (VBlank) flag is contained in D7 of $2002. It indicates whether PPU is in VBlank or not. A program can reset D7 by reading $2002. Reading $2002 at the very start of VBlank will reset $2002 even though D7 appears false.

$2005/$2006 Magic

Games can split the screen by changing the video memory address using both the $2005 and $2006 registers. This is often used to draw a status bar at the top or bottom of the screen. For detailed information pertaining to splits, refer to Loopy's $2005/2006 document. His document provides entirely accurate information regarding how these registers work. See PPU scrolling for more information

Reading VRAM

The first byte read from VRAM is invalid. Due to this aspect, the NES will returned pseudo-buffered values from VRAM rather than linear as expected. See the below example:

  • VRAM $2000 contains $AA $BB $CC $DD.
  • VRAM incrementation value is 1.
  • The result of execution is printed in the comment field.
      LDA #$20
      STA $2006
      LDA #$00
      STA $2006        ; VRAM address now set at $2000
      LDA $2007        ; A=??     VRAM Buffer=$AA
      LDA $2007        ; A=$AA    VRAM Buffer=$BB
      LDA $2007        ; A=$BB    VRAM Buffer=$CC
      LDA #$20
      STA $2006
      LDA #$00
      STA $2006        ; VRAM address now set at $2000
      LDA $2007        ; A=$CC    VRAM Buffer=$AA
      LDA $2007        ; A=$AA    VRAM Buffer=$BB

As shown, the PPU will post-increment it's internal address data after the first read is performed. This only applies to VRAM $0000-3EFF (e.g. Palette data and their respective mirrors do not suffer from this phenomenon).

Notes

The PPU will auto-increment the VRAM address by 1 or 32 (based on D2 of $2000) after accessing $2007.

While rendering is off ($2001 D4-D3 set to 00), and the current video memory address is at $3F00-$3FFF, the PPU outputs the palette entry at that address. To avoid streaks of rainbow colours, make sure to update the palette during VBlank.

pAPU

This section was not completed in time for Nestech.txt version 2.00. See APU for accurate information.

Joypads, paddles, expansion ports

General Information

The NES supports several different input devices, including joypads, Zapper (light guns), and four-player devices.

Joypad #1 and #2 are read via $4016 and $4017, respectively.

The joypads are reset via a strobing-method: writing 1, then 0, to $4016. This address controls the strobe on both joypads. See "Expansion ports" for information regarding "half-strobing."

After a full strobe, the joypad's button status will be returned in a single-bit stream (D0). Multiple reads need to be made to read all the information about the controller.

The standard controller can be read 8 times, once for each button:

      1 = A
      2 = B
      3 = SELECT
      4 = START
      5 = UP
      6 = DOWN
      7 = LEFT
      8 = RIGHT

Reads after the eighth return a 1 bit on most controllers. A few return 0 instead.

The Zapper

The Zapper (otherwise known as the "Light Gun") uses bits within $4016 and $4017, described in Section 8. D4 and D3 are connected to the trigger and light sensor respectively. The light sensor needs to be read throughout the frame, as it returns a light signal for only about 2000 cycles.

It is possible to have two Zapper units connected to both joypad ports simultaneously. The unlicensed games Chiller and Zap Ruder use this.

Four-player devices

Some NES games allow the use of a four-player adapter, extending the number of usable joypads from two (2) to four (4). Carts which use the NES Four Score or NES Satellite are Mindscape/Tengen's Gauntlet II and Nintendo/Rare's R.C. Pro-Am 2.

All four (4) controllers read their status-bits from D0 of $4016 or $4017, as Subsection A states.

For register $4016, reads #1-8 control joypad #1, reads #9-16 control joypad #3, and reads #17-24 return a signature. For $4017, it is respective for joypad #2 and #4.

The following is a list of read #s and their results.

      1 = A          9 = A         17 = +--+
      2 = B         10 = B         18 =    +-- Signature
      3 = SELECT    11 = SELECT    19 =    |
      4 = START     12 = START     20 = +--+
      5 = UP        13 = UP        21 = 0
      6 = DOWN      14 = DOWN      22 = 0
      7 = LEFT      15 = LEFT      23 = 0
      8 = RIGHT     16 = RIGHT     24 = 0

The Famicom has a different four-player adapter. On that system (not the NES), $4016 reads controllers 1 and 3 at the same time, with controller 1 in D0 and controller 3 in D1. Likewise, $4016 returns controller 2 in D0 and controller 4 in D1. In Famicom games that do not use four players, the player expects to be able to use controllers 3 and 4 as if they were controllers 1 and 2.

Paddles

Taito's Arkanoid uses a paddle as it's primary controller.

The paddle position on the Famicom version is read via D1 of $4017; the read data is inverted (0=1, 1=0). The first value read is the MSB, and the 8th value read is (obviously) the LSB. The valid value range is about 160 units wide. One unit was measured with a range 98 to 242, where 98 represents the paddle being turned completely counter-clockwise.

For example, if %01101011 is read, the value would be NOT'd, making %10010100 which is 146.

The paddle also contains one button, which is read via D1 of $4016. A value of 1 specifies that the button is being pressed.

On the NES version of the Arkanoid, D3 and D4 of $4017 are used instead. See Arkanoid controller for full information.

Signatures

A signature allows the programmer to detect if a device is connected to one of the four (4) ports or not, and if so, what type of device it is.

The NES Four Score and NES Satellite have a signature in bits 17-24:

  • %0001 0000 = Joypad ($4016 only)
  • %0010 0000 = Joypad ($4017 only)

Other controllers may or may not have a signature.

Expansion ports

The joypad strobing process requires dual writes: 1, then 0. Some specialised controllers, especially for the Famicom's front expansion port, use a non-standard order for the strobing process.

For example, reading a Super NES Mouse while it is half strobed changes its sensitivity. A program would execute the following code:

      LDA #%00000001      ; Begin half strobe
      STA $4016
      LDA $4017           ; Send one clock while half strobed
      LDA #%00000000      ; End half strobe
      STA $4016

Memory Mapping Hardware

Due to the hundreds of different mappers in use, both discrete logic and integrated MMCs, this document cannot describe them all. See Mapper for complete information.

Registers

Programmers communicate with the PPU and pAPU via registers, which are nothing more than pre-set memory locations which allow the coder to make changes to the NES. Without registers, programs would have no way to communicate with the outside world.

Each register is a 16-bit address. Each register has a statistics field in parentheses located immediately after its description. The legend:

   R = Readable                    W = Writable
   2 = Double-write register      16 = 16-bit register

Notes:

  • 16-bit registers actually consist of two linear 8-bit registers, which can (and will be) *INDEPENDENTLY* assigned. The reason for specifying them as 16-bit is for ease of documentation. For instance, "$4002+$4003" would mean that D15-D8 would be in $4003, and D7-D0 would be in $4002.
  • Bits not listed are to be considered unused.
    +---------+----------------------------------------------------------+
    | Address | Description                                              |
    +---------+----------------------------------------------------------+
    |  $2000  | PPU Control Register #1 (W)                              |
    |         |                                                          |
    |         |    D7: Execute NMI on VBlank                             |
    |         |           0 = Disabled                                   |
    |         |           1 = Enabled                                    |
    |         |    D6: PPU Master/Slave Selection --+   Always write 0   |
    |         |           0 = Receive EXTBG         +-- in unmodified    |
    |         |           1 = Send EXTBG          --+   Control Deck     |
    |         |    D5: Sprite Size                                       |
    |         |           0 = 8x8                                        |
    |         |           1 = 8x16                                       |
    |         |    D4: Background Pattern Table Address                  |
    |         |           0 = $0000 (VRAM)                               |
    |         |           1 = $1000 (VRAM)                               |
    |         |    D3: Sprite Pattern Table Address                      |
    |         |           0 = $0000 (VRAM)                               |
    |         |           1 = $1000 (VRAM)                               |
    |         |    D2: PPU Address Increment                             |
    |         |           0 = Increment by 1                             |
    |         |           1 = Increment by 32                            |
    |         | D1-D0: Name Table Address                                |
    |         |         00 = $2000 (VRAM)                                |
    |         |         01 = $2400 (VRAM)                                |
    |         |         10 = $2800 (VRAM)                                |
    |         |         11 = $2C00 (VRAM)                                |
    +---------+----------------------------------------------------------+
    |  $2001  | PPU Control Register #2 (W)                              |
    |         |                                                          |
    |         | D7-D5: Colour Intensity                                  |
    |         |         000 = None            +--+ NOTE: Some TVs don't  |
    |         |         001 = Intensify red      |   sync well if more   |
    |         |         010 = Intensify green    |   than one type used; |
    |         |         100 = Intensify blue  +--+   PAL swaps D6/D5     |
    |         |    D4: Sprite Visibility                                 |
    |         |           0 = Sprites not displayed                      |
    |         |           1 = Sprites visible                            |
    |         |    D3: Background Visibility                             |
    |         |           0 = Background not displayed                   |
    |         |           1 = Background visible                         |
    |         |    D2: Sprite Clipping                                   |
    |         |           0 = Sprites invisible in left 8-pixel column   |
    |         |           1 = No clipping                                |
    |         |    D1: Background Clipping                               |
    |         |           0 = BG invisible in left 8-pixel column        |
    |         |           1 = No clipping                                |
    |         |    D0: Display Type                                      |
    |         |           0 = Colour display                             |
    |         |           1 = Monochrome display (all palette values     |
    |         |               ANDed with $30)                            |
    +---------+----------------------------------------------------------+
    |  $2002  | PPU Status Register (R)                                  |
    |         |                                                          |
    |         |    D7: VBlank Occurance                                  |
    |         |          0 = Not occuring                                |
    |         |          1 = In VBlank                                   |
    |         |    D6: Sprite #0 Hit                                     |
    |         |          0 = Sprite #0 not found                         |
    |         |          1 = PPU has hit Sprite #0 since end of VBlank   |
    |         |    D5: Scanline Sprite Count                             |
    |         |          0 = No scanline with more than eight (8)        |
    |         |              sprites                                     |
    |         |          1 = At least one line with more than 8 sprites  |
    |         |              since end of VBlank                         |
    |         |                                                          |
    |         | NOTE: D7 is set to 0 after read occurs.                  |
    |         | NOTE: After a read occurs, $2005 is reset, hence the     |
    |         |       next write to $2005 will be Horizontal.            |
    |         | NOTE: After a read occurs, $2006 is reset, hence the     |
    |         |       next write to $2006 will be the high byte portion. |
    |         | NOTE: D4-D0 return the last value written to any PPU     |
    |         |       register.                                          |
    |         |                                                          |
    |         | For detailed information regarding D6, see Section 4,    |
    |         | Subsection L.                                            |
    +---------+----------------------------------------------------------+
    |  $2003  | SPR-RAM Address Register (W)                             |
    |         |                                                          |
    |         | D7-D0: 8-bit address in SPR-RAM to access via $2004.     |
    |         |                                                          |
    |         | NOTE: The SPR-RAM DRAM controller is very touchy.        |
    |         |       Write $00 here.                                    |
    +---------+----------------------------------------------------------+
    |  $2004  | SPR-RAM I/O Register (W)                                 |
    |         |                                                          |
    |         | D7-D0: 8-bit data written to SPR-RAM.                    |
    |         |                                                          |
    |         | NOTE: It is strongly recommended to use $4014 instead.   |
    +---------+----------------------------------------------------------+
    |  $2005  | VRAM Address Register #1 (W2)                            |
    |         |                                                          |
    |         |  Commonly used used to "pan/scroll" the screen (sprites  |
    |         |  excluded) horizontally and vertically. However, there   |
    |         |  is no actual panning hardware inside the NES. This      |
    |         |  register controls VRAM addressing lines.                |
    |         |                                                          |
    |         | Refer to Section 4, Subsection N, for more information.  |
    +---------+----------------------------------------------------------+
    |  $2006  | VRAM Address Register #2 (W2)                            |
    |         |                                                          |
    |         |  Commonly used to specify the 16-bit address in VRAM to  |
    |         |  access via $2007. However, this register controls VRAM  |
    |         |  addressing bits, and therefore should be used with      |
    |         |  knowledge of how it works, and when it works.           |
    |         |                                                          |
    |         | Refer to Section 4, Subsection N, for more information.  |
    +---------+----------------------------------------------------------+
    |  $2007  | VRAM I/O Register (RW)                                   |
    |         |                                                          |
    |         | D7-D0: 8-bit data read/written from/to VRAM.             |
    +---------+----------------------------------------------------------+
    |  $4000  | pAPU Pulse #1 Control Register (W)                       |
    |  $4001  | pAPU Pulse #1 Ramp Control Register (W)                  |
    |  $4002  | pAPU Pulse #1 Fine Tune (FT) Register (W)                |
    |  $4003  | pAPU Pulse #1 Coarse Tune (CT)/Length Register (W)       |
    |  $4004  | pAPU Pulse #2 Control Register (W)                       |
    |  $4005  | pAPU Pulse #2 Ramp Control Register (W)                  |
    |  $4006  | pAPU Pulse #2 Fine Tune Register (W)                     |
    |  $4007  | pAPU Pulse #2 Coarse Tune/Length Register (W)            |
    |  $4008  | pAPU Triangle Linear Counter Register #1 (W)             |
    |  $4009  | Unused                                                   |
    |  $400A  | pAPU Triangle Fine Tune Register Register #1 (W)         |
    |  $400B  | pAPU Triangle Coarse Tune/Length Register #2 (W)         |
    |  $400C  | pAPU Noise Control Register #1 (W)                       |
    |  $400D  | Unused                                                   |
    |  $400E  | pAPU Noise Frequency Register (W)                        |
    |  $400F  | pAPU Noise Length Register (W)                           |
    |  $4010  | pAPU Delta Modulation Control Register (W)               |
    |  $4011  | pAPU Delta Modulation D/A Register (W)                   |
    |  $4012  | pAPU Delta Modulation Address Register (W)               |
    |  $4013  | pAPU Delta Modulation Data Length Register (W)           |
    +---------+----------------------------------------------------------+
    |  $4014  | Sprite DMA Register (W)                                  |
    |         |                                                          |
    |         |  Transfers 256 bytes of memory into SPR-RAM. The address |
    |         |  read from is $100*N, where N is the value written.      |
    +---------+----------------------------------------------------------+
    |  $4015  | pAPU Sound/APU Frame Counter Register (R)                |
    |         |                                                          |
    |         |    D6: APU Frame IRQ Availability                        |
    |         |           0 = One (1) frame occuring, hence IRQ cannot   |
    |         |               occur                                      |
    |         |           1 = One (1) frame is being interrupted via IRQ |
    |         |    D4: Delta Modulation                                  |
    |         |    D3: Noise                                             |
    |         |    D2: Triangle                                          |
    |         |    D1: Pulse #2                                          |
    |         |    D0: Pulse #1                                          |
    |         |           0 = Not in use                                 |
    |         |           1 = In use                                     |
    |         +----------------------------------------------------------+
    |         | pAPU Channel Control (W)                                 |
    |         |                                                          |
    |         |    D4: Delta Modulation                                  |
    |         |    D3: Noise                                             |
    |         |    D2: Triangle                                          |
    |         |    D1: Pulse #2                                          |
    |         |    D0: Pulse #1                                          |
    |         |           0 = Channel disabled                           |
    |         |           1 = Channel enabled                            |
    +---------+----------------------------------------------------------+
    |  $4016  | Joypad #1 (RW)                                           |
    |         |                                                          |
    |         | READING:                                                 |
    |         |    D4: Zapper Trigger                                    |
    |         |           0 = Pulled or released                         |
    |         |           1 = Half pulled                                |
    |         |    D3: Zapper Light Detection                            |
    |         |           0 = Light in front of barrel                   |
    |         |           1 = Dark in front of barrel                    |
    |         |    D1: Famicom Expansion Joypad Data                     |
    |         |    D0: Joypad Data                                       |
    |         +----------------------------------------------------------+
    |         | WRITING:                                                 |
    |         | Joypad Strobe (W)                                        |
    |         |                                                          |
    |         |    D0: Joypad Strobe                                     |
    |         |           0 = Finish polling both joypads                |
    |         |           1 = Poll both joypads                          |
    +---------+----------------------------------------------------------+
    |  $4017  | Joypad #2/SOFTCLK (RW)                                   |
    |         |                                                          |
    |         | READING:                                                 |
    |         |    D4: Zapper Trigger                                    |
    |         |           0 = Pulled or released                         |
    |         |           1 = Half pulled                                |
    |         |    D3: Zapper Light Detection                            |
    |         |           0 = Light in front of barrel                   |
    |         |           1 = Dark in front of barrel                    |
    |         |    D1: Famicom Expansion Joypad Data                     |
    |         |    D0: Joypad Data                                       |
    +---------+----------------------------------------------------------+

File Formats

iNES Format (.NES)

Most common ROMs will be found in this format:

    +--------+------+------------------------------------------+
    | Offset | Size | Content(s)                               |
    +--------+------+------------------------------------------+
    |   0    |  3   | 'NES'                                    |
    |   3    |  1   | $1A                                      |
    |   4    |  1   | 16K PRG-ROM page count                   |
    |   5    |  1   | 8K CHR-ROM page count                    |
    |   6    |  1   | ROM Control Byte #1                      |
    |        |      |   %####vTsM                              |
    |        |      |    |  ||||+- 0=Horizontal mirroring      |
    |        |      |    |  ||||   1=Vertical mirroring        |
    |        |      |    |  |||+-- 1=SRAM enabled              |
    |        |      |    |  ||+--- 1=512-byte trainer present  |
    |        |      |    |  |+---- 1=Four-screen mirroring     |
    |        |      |    |  |                                  |
    |        |      |    +--+----- Mapper # (lower 4-bits)     |
    |   7    |  1   | ROM Control Byte #2                      |
    |        |      |   %####0000                              |
    |        |      |    |  |                                  |
    |        |      |    +--+----- Mapper # (upper 4-bits)     |
    |  8-15  |  8   | $00                                      |
    | 16-..  |      | Actual 16K PRG-ROM pages (in linear      |
    |  ...   |      | order). If a trainer exists, it precedes |
    |  ...   |      | the first PRG-ROM page.                  |
    | ..-EOF |      | CHR-ROM pages (in ascending order).      |
    +--------+------+------------------------------------------+

See iNES for full details.

Some ROMs using more obscure mappers require an extension to the iNES format called "NES 2.0", first proposed by Kevin Horton. See NES 2.0 for full details.

Programming the NES

General Information

None.

CPU Notes

None. See "CPU Notes" in Section 11 "Emulation" for more possible information.

PPU Notes

Reading and writing to VRAM consists of a multi-step process:

      Writing to VRAM                    Reading from VRAM
      ---------------                    -----------------
      1) Wait for VBlank                 1) Wait for VBlank
      2) Write upper VRAM address        2) Write upper VRAM address
         byte into $2006                    byte into $2006
      3) Write lower VRAM address        3) Write lower VRAM address
         byte into $2006                    byte into $2006
      4) Write one or more bytes         4) Read $2007 (invalid data once)
         to $2007                        5) Read one or more bytes
                                            from $2007

NOTE: Step #4 when reading VRAM is only necessary when reading VRAM data not in the $3F00-3FFF range.

NOTE: If VBlank has not yet ended, steps #2-5 may be repeated in order to read or write at a different address. VBlank lasts at least 2,200 CPU cycles.

NOTE: Accessing VRAM should only be performed during VBlank, or with rendering turned off ($2001 D4-D3 cleared to 0). Attempts to access VRAM outside of VBlank will usually result in garbage showing up on the screen. See Section 4, Subsection N for more information regarding why this occurs.

Waiting for VBlank is quite simple:

     FEE0: LDA $2002
           BPL $FEE0

Reading $2002 will result in all bits being returned; however, D7 will be reset to 0 after the read is performed. To ensure the PPU is warmed up, this should be done twice before the first access to $2003-$2007.

Waiting for VBlank during a game should be done by waiting for the NMI handler to change a variable:

     8000: INC $FF
           RTI
     
     8100: LDA $FF
     8102: CMP $FF
           BEQ $8102

The actual on-screen palette used by the NES, as stated prior, is not RGB. However, a near-exact replica can be found in common NES emulators today. See PPU palettes to obtain a valid RGB palette.

You will often encounter a situation where a palette fade or a VRAM update will cause the screen "to be trashed" (squares on the screen, or what seem to be graphical "glitches"). The reason for this is that your code took longer than a VBlank. When the VBlank ends, the PPU begins to refresh the screen again, taking whatever value is in the internal VRAM address and uses that as the starting base for Name Table #0. The solution is to fix your code to take no more than 2273 cycles, which is 20 scanlines times 341 pixels per scanline divided by 3 pixels per cycle.

In addition, after you update video memory through $2006 and $2007, the scroll position becomes corrupt, and the PPU again begins at the internal VRAM address. To solve this, make sure to reset the scroll position through $2005 and $2000 before the next frame begins. Such code would be:

     LDA #$00
     STA $2005
     STA $2005
     LDA #$88
     STA $2000

If your game scrolls, use different values for $2005 and for $2000 D1-D0.

Emulation

General Information

If you're going to be programming an emulator in C or C++, please be familiar with pointers. Being familiar with pointers will help you out severely when it comes to handling mirroring and VRAM addressing. For you assembly buffs out there, obviously pointers are nothing more than indirect addressing -- it's easier to change a 32-bit value than to swap in and out an entire 64K of data.

When SRAM ($6000-7FFF) is disabled, writes to the memory area should be ignored. Reads will possibly return data previously left on the bus, and therefore when emulated should return the previous bus value. This will usually (but not always) be the high byte of the address. See Open bus for more details.

RAM-based memory areas ($0000-07FF) should *NOT* be zeroed on RESET; they should be set to some value on power on. Please make sure that a cold boot and a warm boot do different things. (Technically, the RAM is not zeroed on power on either: the RAM will slowly dissipate over time when the unit is off.)

CPU Notes

The NES uses the NMOS 6502, not a CMOS 6502 or any other variant.

There are 154 valid opcodes (out of 256 total) on the NES. Please support the option of trapping opcodes which are bad. Sometimes a ROM contains bad opcodes, due to dirty connectors on the cartridge during the extraction process (or other reasons). But other games out there, such as Puzznic and Super Cars, contain bad opcodes even in a correct dump.

PPU Notes

The formulae to calculate the base address of a Name Table tile number is:

(TILENUM * 16) + PATTERNTABLE

Where TILENUM is the tile number in the Name Table, and PATTERNTABLE is the Pattern Table Address defined via register $2000.

Most emulators do not limit the number of sprites which can be displayed per scanline, while the actual NES will show flicker as a result of more than eight (8). One supports 15 sprites per line by changing the order of sprite-related Pattern Table fetches during HBlank.

Emulators should _NOT_ mask out unused bits within registers; doing so may result in a cart not working.

Reference Material

Many of these no longer exist:

Mailing Lists

There is a NES Development Mailing List in existence. Contact Mark Knibbs for more information. This list is for anyone who wishes to discuss technical issues about the NES; it is not a list for picking up the latest and greatest information about NES emulators or what not.

However, most users have since migrated to a phpBB forum at https://forums.nesdev.org/

WWW Sites

The following are a list of WWW sites which contain NES-oriented material. If you encounter errors, bad links, or other anomalies while visiting these sites, contact the site authors/owners, NOT me. Thanks.


https://nesdev.org/
Contains a verbose amount of documentation regarding anything NES-oriented, including hard-to-find mapper documentation. Seems to be a decent NES information depository.
http://www.ameth.org/~veilleux/NES_info.html
Currently only contains hardware-oriented material, such as overviews of cart and unit ASICs, mappers, and MMCs. Many pinout diagrams for mappers and NES units are available here. Also provides documentation on NES repair, modifying your NES to give fake stereo output, applying stereo mixing to your NES, and much much more.

Hardware Information

The following security bits may be purchased from MCM Electronics (http://www.mcmelectronics.com/):

  • For NES, Game Boy, Super NES, and Nintendo 64 Game Paks: 22-1145 (3.8mm security bit)
  • For NES, Super NES, and Nintendo 64 Control Deck: 22-1150 (4.5mm security bit)

Other sellers may offer them under the "Line" or "GameBit".

An alternate method is to cut a notch in a standard flat head screwdriver that grips two of the six indentations on the screw.

See also

External links