  A. General Information
  ----------------------
    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
      +---------+-------+--------------------+
      | Address | Size  | Description        |
      +---------+-------+--------------------+
      | $0000   | $1000 | Pattern Table #0   |
      | $1000   | $1000 | Pattern Table #1   |
      | $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 = Possibly CHR-ROM
                          N = Mirrored (see Subsection G)
                          P = Mirrored (see Subsection H)
                          R = Mirror of $2000-2EFF (VRAM)
                          F = Mirror of $0000-3FFF (VRAM)


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


  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:

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


  E. Attribute Tables
  -------------------
    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
      |   #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 corris-
    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)


  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.

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


  G. 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 the Name Table portion of the NES's
    PPU RAM; one may consider these synonymous with "$2xxx" in the VRAM
    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.


  H. Palette Mirroring
  --------------------
    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
    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:

      * $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 Image and Sprite Palettes are both mirrored to other areas
    of VRAM as well; $3F20-3FFF are mirrors of both palettes, respectively.

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


  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:

      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). This doesn't
    work for game which use Horizontal & Vertical scrolling simultaneously.

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

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

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


  J. Screen and Sprite Layering
  -----------------------------
    There is a particular order in which the NES draws it's 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', which is synonmous with D7-D5 of
    $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
    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).


  K. Sprites and SPR-RAM
  ----------------------
    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. A
    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
    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 sprites are disabled (D4 of $2001 is 0)
    for a long period of time, SPR-RAM will gradually degrade. A proposed
    concept is that SPR-RAM is actually DRAM, and D4 controls the DRAM
    refresh cycle).


  L. Sprite #0 Hit Flag
  ---------------------
    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.
    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 underneathe the BG (via the
    'Background Priority' SPR-RAM bit), though the above example would
    be 'BG+Sprite'.

    Also, D6 is cleared (set to 0) after each VBlank.


  M. 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--+

    An NTSC NES has the following refresh and screen layout:

      +--------+ 0 ----+
      |        |       |
      |        |       |
      | Screen |       +-- (0-239) 256x240 on-screen results
      |        |       |
      |        |       |
      +--------+ 240 --+
      |   ??   |       +-- (240-242) Unknown
      +--------+ 243 --+
      |        |       |
      | VBlank |       +-- (243-262) VBlank
      |        |       |
      +--------+ 262 --+

    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.


  N. $2005/2006 Magic
  -------------------
     For detailed information pertaining to the $2005 and $2006 registers,
     refer to Loopy's $2005/2006 document. His document provides entirely
     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
      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).


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

  C. 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 data to $2007             4) Read $2007 (invalid data once)
                                         5) Read data from $2007

    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
    will be reset to 0 after the read is performed.

    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. Contact the appropriate authors of these emulators to obtain
    a valid RGB palette.

    Be sure to clear the internal VRAM address via $2006 semi-often. 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 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.
