  A. General Information
  ----------------------
    The NES uses a customized NMOS 6502 CPU, engineered and produced by
    Ricoh. It's primary customization adds audio.

    The NTSC NES runs at 1.7897725MHz, and 1.773447MHz for PAL.


  B. 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   | $1FDF |       | Expansion ROM         |
    | $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.)


  C. 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 spec-
    ifies 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 1" title.
    These carts return from interrupts in a very odd fashion: by manipul-
    ating the stack by hand, and then doing an RTS. This is technically
    valid, but morally shunned.

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

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

    Interrupt priorities are as follows:

      Highest = RESET
                NMI
       Lowest = IRQ/BRK


  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. 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-
    ation is done internal to the CPU as well.


  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.

    Most games load themselves into $8000, using 32K of PRG-ROM space. The
    first game to use this method is Super Mario Brothers. However, all
    games wit 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.

    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 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: 4F
      C1FF: 00
      C200: 23
        ..
      D000: 6C FF C1 - JMP ($C1FF)

    Logically, this will jump to address $2300. 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 $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,
      C002: LDA ($FF,X)   ;   not $0102+$0103.
