                     **************************************
                     **                                  **
                     **        NES Memory Mapping        **
                     **           version 1.0            **
                     **                                  **
                     **             by Disch!            **
                     **************************************

===================================
Introduction
===================================

    There are a bunch of docs around which cover 6502 and asm hacking in NES
games.  They do a good job of showing how you can modify existing game code to
make it do something new.  Some even cover how to insert your own code and jump
to it, allowing you to add new stuff to your hack.  But one related area which
is crucial to really understanding how to do all this is either only briefly
touched on with little explanation, or is not touched on at all.  Leaving the
reader with many unanswered questions.

    I'm talking, of course, about mappers.  People hear terms like "mapper",
and "PRG swapping" thrown around...  but not everyone understands what they do
or how they work.  If you're one of these people, hopefully this doc will shed
some light on the subject.

    This doc primarily focuses on the PRG/CHR swapping aspect of mappers.
Other aspects of mappers (such as IRQ generation, mirroring control, sound,
etc) are not covered in this document.


===================================
What should you know?
===================================

    This doc does not cover 6502.  It doesn't assume you know any 6502, however
I doubt much of the information here will be very useful without it.

    This doc will assume you know nothing about NES architecture, and will
cover some basic ares that relate to NES<->Mapper interaction.

    However... despite it not relying on you having much previous experience,
the information gained will probably be useless unless you've been around the
block a few times.


===================================
ROM offsets vs. CPU Addresses
===================================

    ROM offsets and CPU Addresses are two distinctly different things.  ROM
offsets indicate a position the .nes file -- and CPU addresses indicate an
area in the NES CPU memory map.  Mappers are the key to translating between
the two.

    In this doc... ROM offsets will always be prefixed with '0x', and CPU
addresses will always be prefixed with '$'.

    Tangent note:  some docs and tutorials erroneously call CPU addresses "RAM
offsets" (and in fact, it says this in FCEUXD as well).  I want to punch these
authors, as that term is false and misleading (you're not always dealing with
RAM, and it doesn't really offset anything).  I urge you to refrain from using
these terms, and to just say "address" for CPU addresses and "offset" for ROM
offsets.  It may not seem like a big deal, but it may ultimately lead to
confusion when you really do need to differentiate between what's RAM and what
isn't (and when you actually do have to deal with real RAM offsets).

===================================
A look at the NES Memory Map
===================================

    The first step to understanding the mapper's primary function (memory
mapping) is to examine the basic NES memory Map.  You may have seen similar
charts in other NES docs, but they usually clump the cartridge and NES
together:

     NES CPU Memory Map:
     +-------------+----------------------------+
     | Address     |  Mapped to                 |
     +-------------+----------------------------+
     |$0000 - $1FFF|  System RAM                |
     |$2000 - $3FFF|  PPU Registers             |
     |$4000 - $401F|  CPU/pAPU/Joypad Registers |
     |$4020 - $FFFF|  Cartridge                 |
     +-------------+----------------------------+
        The NES cannot address anything higher than $FFFF

     Typical Cartridge memory map:
     +-------------+----------------------------------+
     | Address     |  Mapped to                       |
     +-------------+----------------------------------+
     |$4020 - $5FFF|  Unused                          |
     |$6000 - $7FFF|  PRG-RAM (aka SRAM)              |
     |$8000 - $FFFF|  PRG-ROM (ie:  the actual game)  |
     +-------------+----------------------------------+

    This is how the vast majority of NES games look.  The NES CPU Memory Map
as listed above is *always* the same.  However, the cartridge memory map can
vary wildly according to the cartridge layout and the mapper.

    What the hell does this mean?  Well this means that any time the game reads
or writes to an address below $4020, it's doing something local to the NES.
However when it reads/writes to an address above $4020, it's accessing
something on the cartridge and is subject to mapper intervention:

LDA $0300   ;  reading from NES system RAM
LDA $8123   ;  reading from cartridge (typically PRG-ROM)


===================================
A look at .nes ROM files
===================================

    The next step to understanding how mappers map cartridge information is
understand what we'll be mapping.  This is actually pretty straightforward...
the .nes file contains 3 main parts:


1)  iNES Header
2)  PRG-ROM
3)  CHR-ROM  (assuming the game has any)

    PRG and CHR ROM sizes are indicated by the header.

    The iNES header is $10 bytes in size, which means that PRG-ROM starts at
offset 0x00010 in the .nes file.



===================================
Why a mapper is needed
===================================

    For our first example... let's take a look at a small, simple game like
Super Mario Bros.  This ROM has 32K PRG.  You can see this in FCEUXD by loading
the ROM, then going to Help | Message Log (it will say "2 x 16KiB")

    32K is $8000 bytes.  This fits PERFECTLY into the typical cartridge memory
map.  For this paticular situation... a mapper isn't needed, because all of
the PRG can fit into the allotted space at address range $8000-$FFFF.  This
means that when the game is reading from address $8000, it's reading offset
0x00010 (the first byte of PRG-ROM).

    Note, however... that this is ALL of the space in the CPU memory map that
is designated for PRG-ROM.  So how on Earth are games able to fit in more PRG?
This is accomplished by a technique performed by mappers called PRG swapping.

    But before we get into PRG swapping... let's start with something a little
easier to visualize....


===================================
CHR Swapping
===================================

    CHR Swapping is the same concept as PRG swapping, only it deals with CHR
instead of PRG.  This makes it a bit easier to visualize.

    A good game to use as an example is Super Mario Bros. 2.  Load up this ROM
in FCEUXD, start the first level, and open up the PPU Viewer (Tools | PPU
Viewer).  At the same tile, load up the ROM in your favorite tile editor and
jump to offset 0x26010

    Notice how in FCEUXD, the tiles on the bottom of the right-hand pattern
table are animating.  By looking at how the tiles are layed out in your tile
editor, you should be able to see that the game is just cycling through a list
of tiles.

    This actually is a great demonstration of what swapping is and how it
works.  Instead of looking at the pattern tables and seeing a bunch of
tiles... try to look at it and see "slots":

   +----------------------------++----------------------------+
   |           Slot 0           ||           Slot 4           |
   |                            ||                            |
   +----------------------------++----------------------------+
   |           Slot 1           ||           Slot 5           |
   |                            ||                            |
   +----------------------------++----------------------------+
   |           Slot 2           ||           Slot 6           |
   |                            ||                            |
   +----------------------------++----------------------------+
   |           Slot 3           ||           Slot 7           |
   |                            ||                            |
   +----------------------------++----------------------------+

    Each slot holds 4 rows of tiles (64 tiles)... this represents 1k ($400
bytes) of CHR.  Now the NES cannot "see" more than 8k at a time (the above 8
slots).  However... games can have more graphics by putting different CHR
"pages" in those slots.  When it wants to change which page is in the slot, it
"swaps in" a new page.  The page that was previously visible is removed, and
the new page becomes visible.

    SMB2 is constantly switching which CHR page is put in slots 6 and 7.  By
constantly swapping in new pages, it appears as though the tiles are animating.
This is a common animation technique used by NES games.

    The pages themselves can be seen in a tile editor.  SMB2's CHR-ROM starts
at offset 0x20010.  Which means:

page $00 = 0x20010 - 0x2040F   (the first 64 tiles)
page $01 = 0x20410 - 0x2080F   (the next 64 tiles)
page $02 = 0x20810 - 0x20C0F
...
page $7F = 0x3FC10 - 0x4000F   (the last 64 tiles)
  (the above assumes 1k pages)



Note about CHR-RAM:
   Some games use CHR-RAM instead of CHR-ROM (these games don't have any
CHR-ROM, and all their graphics data is intermingled in the PRG.  Castlevania,
Final Fantasy are examples of these types of games).  For these games, the
above doesn't apply.  CHR-RAM is handled differently from CHR-ROM and is beyond
the scope of this document (it's more related to PPU registers than mapper
stuff)

===================================
PRG Swapping
===================================

    Some people can pick up the concept of CHR swapping pretty quick, but then
struggle with PRG swapping.  Which is a little strange, because it's the EXACT
same concept.  Rather than looking at the $8000-$FFFF area in CPU addressing
space as a big chunk of PRG... look at it as a series of slots.  For another
visual of a typical NES CPU memory map:


    $0000  +-----------------+      $8000  +-----------------+
           |                 |             |                 |
           |  System RAM     |             |  PRG Slot 0     |
           |                 |             |                 |
    $2000  +-----------------+      $A000  +-----------------+
           |                 |             |                 |
           |  PPU Registers  |             |  PRG Slot 1     |
           |                 |             |                 |
    $4000  +-----------------+      $C000  +-----------------+
           |  CPU/etc Regs   |             |                 |
    $5000  +-----------------+             |  PRG Slot 2     |
           |  Unused         |             |                 |
    $6000  +-----------------+      $E000  +-----------------+
           |                 |             |                 |
           |  SRAM           |             |  PRG Slot 3     |
           |                 |             |                 |
           +-----------------+             +-----------------+


    Just like how in CHR swapping, slots are filled with pages of tiles... with
PRG swapping, slots are filled by pages of PRG.

    So while a game can only "see" 32k of PRG at any one time... it can still
access much more than 32k by swapping out different pages.

    Just as CHR pages are stored in order in the .nes file, so are PRG pages:

page $00 = 0x00010 - 0x0200F
page $01 = 0x02010 - 0x0400F
page $02 = 0x04010 - 0x0600F
...
etc
   (the above assumes 8k pages)




===================================
Converting ROM Offsets and CPU Addresses
===================================

    6502 code and NES games all deal with CPU addresses.  None of it deals with
ROM offsets.  This is why NES pointers appear so funky to newcomers.  People
sometimes come across a pointer such as "63 91", and get confused when they
find that it actually points to offset 0x15173.  But when you consider
everything mentioned above.. it really does make perfect sense:


- "63 91" = $9163 (CPU address)
- $9163 is in "Slot 0" ($8000-9FFF)
- $9163 is $1163 bytes into the slot (slot starts at $8000)
- for this to point to 0x15173... page $0A (assuming 8k pages) must be swapped
     in slot 0:

$0A * $2000 = 0x14000      (page# * page_size = start_of_page)
0x14000 + $1163 = 0x15163  (start_of_page + bytes_into_slot = offset)
0x15163 + 0x10 =  0x15173  (adjust for iNES header)

    That same pointer, however, could point to 0x0D173 or 0x05173 or 0x11173.
It all depends on which page is swapped in.

    So how do you find out which page is swapped in?  Well it's quite easy in
FCEUXD.  Simply open up the hex editor (Tools | Hex Editor), go to View | NES
Memory, go to the desired CPU address, right click on it, and select "Go Here
In ROM File".  The hex editor will flip over to ROM offset mode and will give
you the offset to the desired PRG.

    Note, however, that games are CONSTANTLY swapping PRG pages.  It's not
uncommon for games to swap pages multiple times every frame.  Therefore it's
recommended you snap the debugger at the appropriate time before finding which
pages are swapped in.  And remember that just because a page is swapped in now,
doesn't mean it will be swapped in later.


===================================
Variable slot sizes, swappable slots, and hardwired slots
===================================

    Up until now, I've been using 8k pages as examples.  This is because the
most common mapper (MMC3, mapper 4) uses 8k PRG pages.  However, other mappers
use different sizes.  Some mappers even let the game PICK the size!

    Different size pages operate just like you may expect.  16k pages ($4000
bytes) would be stored in the ROM as:

page $00 = 0x00010 - 0x0400F
page $01 = 0x04010 - 0x0800F
... etc

    And 32k pages ($8000 bytes -- yes, some mappers use pages this big) would
be stored as:

page $00 = 0x00010 - 0x0800F
page $01 = 0x08010 - 0x1000F
... etc


   Generally slots are arranged like so:

            8k         16k         32k
$8000   +--------+  +--------+  +--------+
        |        |  |        |  |        |
$A000   +--------+  |        |  |        |
        |        |  |        |  |        |
$C000   +--------+  +--------+  |        |
        |        |  |        |  |        |
$E000   +--------+  |        |  |        |
        |        |  |        |  |        |
        +--------+  +--------+  +--------+


    Mappers don't always let the game select a page for every slot.  Some slots
are fixed so that they always contain a specific page.  These slots are often
called "hardwired" (even though that term is technically inaccurate... "fixed"
is more appropriate).  Usually, the last slot is fixed to the last page of PRG,
and cannot be swapped out.  This all depends on the mapper being used and
possibly the settings of that mapper.



===================================
Nitty Gritty specific mapper details
===================================

    Everything mentioned so far as been intentionally generic.  The concepts
are sound and apply to every mapper out there.  However each individual mapper
does vary slightly in slot arrangement, PRG/CHR swapping ability,
swappable/fixed slots, and even additional features not mentioned in this doc.
And while the info mentioned above is all sound... you're eventually going to
need to know the specifics.

    So here is a short list of some common mappers and their arrangement.  This
is by no means a complete list.  I have no intention of making a complete list.
There are sources for mapper details elsewhere -- if the mapper your game uses
is not listed here, you'll have to find a different resource.

    This list also does not go into details of mapper registers.  If you want
to know how to manually swap out pages or do other things with the mapper,
you'd be best suited to find a technical doc on said mapper.


    Finding out which mapper your game uses is pretty easy.  Many emulators
will tell you this information after the ROM is loaded.  In FCEUXD, once you
load the ROM, go to Help | Message Log, and it will tell you the mapper number.


************************
*  Mapper 0  --  NROM  *
************************

    Mapper 0 is no mapper.  There is no PRG/CHR swapping ability.


************************
*  Mapper 1  --  MMC1  *
************************

    Mapper 1 lets the game choose between 3 different PRG swapping schemes.
99% of games using this mapper use the first scheme listed:

PRG:
16k Slot @ $8000 = Swappable
16k Slot @ $C000 = Fixed to last PRG page
---------OR--------
16k Slot @ $8000 = Fixed to first PRG page (page 0)
16k Slot @ $C000 = Swappable
---------OR--------
32k Slot @ $8000 = Swappable

    Mapper 1 also let's game switch between 2 different CHR swapping schemes.
However, many games using this mapper use CHR-RAM.  For those that don't:

CHR:
4k Slot @ ppu$0000 = Swappable
4k Slot @ ppu$1000 = Swappable
---------OR--------
8k Slot @ ppu$0000 = Swappable


    There are a handful of rare exceptions which rewire MMC1 in funky ways.
Dragon Warrior 4, for instance, in a way breaks the above PRG swapping rules.
For these games, refer to an MMC1 technical doc.


*************************
*  Mapper 2  --  UxROM  *
*************************

    Mapper 2 is very simple.  Only 1 swapping scheme.  All games using this
mapper have CHR-RAM, and thus do not swap CHR.

PRG:
16k Slot @ $8000 = Swappable
16k Slot @ $C000 = Fixed to last PRG page


*************************
*  Mapper 4  --  MMC3   *
*************************

    MMC3 is hands down the most common mapper around.  Odds are whatever game
you're hacking (if it's a US release) is MMC3.  Most games using this mapper
use CHR-ROM and swap as indicated below:

PRG:
8k Slot @ $8000 = Swappable
8k Slot @ $A000 = Swappable
8k Slot @ $C000 = Fixed to 2nd last PRG page
8k Slot @ $E000 = Fixed to last PRG page
----------OR----------
8k Slot @ $8000 = Fixed to 2nd last PRG page
8k Slot @ $A000 = Swappable
8k Slot @ $C000 = Swappable
8k Slot @ $E000 = Fixed to last PRG page


CHR:
2k Slot @ ppu$0000 = Swappable
2k Slot @ ppu$0800 = Swappable
1k Slot @ ppu$1000 = Swappable
1k Slot @ ppu$1400 = Swappable
1k Slot @ ppu$1800 = Swappable
1k Slot @ ppu$1C00 = Swappable
----------OR----------
1k Slot @ ppu$0000 = Swappable
1k Slot @ ppu$0400 = Swappable
1k Slot @ ppu$0800 = Swappable
1k Slot @ ppu$0C00 = Swappable
2k Slot @ ppu$1000 = Swappable
2k Slot @ ppu$1800 = Swappable


===================================
One final note
===================================

    When it comes to mappers... anything and everything goes.  A "mapper"
is really a combination of cartridge layout, wiring, MMC, and anything
additional on the cart.  Theoretically, it is even possible for an
additional processor to be on the cartridge!

    So while there are general traits that are shared by many mappers...
there are no "rules".  The charts and explanations should be absorbed
with the understanding that they are not carved in stone... and that there
are mappers out there which deviate from the normal patterns.


===================================
That's it!
===================================

    That's about everything I can think of.  Hopefully this will clarify some
of the grey areas left by other docs.



===================================
Version History
===================================

June 25, 2007    -   version 1.0  -  Initial release