INES Mapper 001

From NESdev Wiki
Revision as of 22:20, 13 November 2011 by Zeromus (talk | contribs)
Jump to navigationJump to search

iNES Mapper 001 is used to designate the SxROM boardset, all of which use the Nintendo MMC1.

This has proven to be problematic for boards (such as SOROM, SUROM and SXROM) which use the upper CHR bank select lines to select additional PRG ROM or PRG RAM data; games which use SOROM or SXROM often must be handled individually based on the ROM checksum.

In the absence of data beyond basic iNES header data, the following procedure developed by User:Bregalad may work to guess a board type useful for emulation:

  1. CHR ROM present on cartridge : MMC1 registers acts "normal".
  2. CHR ROM not-present on cartridge : MMC1 CHR's registers bankswitches SRAM banks. If the battery bit is present, only banks which are accessed are saved to the disk when the game is quit. When loading a game with the battery bit set, if a 8KB .sav file is present, it is repeated equally across all banks. This will lead to data being saved when it wasn't supposed to for SOROM games, but 8KB of hard disk space isn't a problem.
  3. PRG ROM size equal to 512 KiB: Higher CHR line switches 256 KB banks.
  4. PRG ROM size equal to 256 KiB or less and CHR-ROM not present on the cartidge : Higher CHR line disables SRAM.
========================
=  Mapper 001          =
========================

aka
--------------------------
MMC1
SxROM


Example Games:
--------------------------
Final Fantasy
Mega Man 2
Blaster Master
Metroid
Kid Icarus
Zelda
Zelda 2
Castlevania 2


Notes:
---------------------------
MMC1 is unique in that not only must the registers be written to *one bit at a time*, but also you cannot
write to the registers directly.

Internal registers are 5 bits wide.  Meaning to complete a "full" write, games must write to a register 5
times (low bit first).  This is usually accomplished with something like the following:

   LDA value_to_write
   STA $9FFF    ; 1st bit written
   LSR A
   STA $9FFF    ; 2nd bit written
   LSR A
   STA $9FFF    ; 3rd bit written
   LSR A
   STA $9FFF    ; 4th bit written
   LSR A
   STA $9FFF    ; final 5th bit written -- full write is complete

Writing to anywhere in $8000-FFFF will do -- however the address you write to on the last of the 5 writes
will determine which internal register gets filled.  The address written to for the first 4 writes *does not
matter at all*... though games generally write to the same address anyway (like in the above example).

To illustrate this:

   LDA #$00  ; we want to write 0 to a reg
   STA $8000
   STA $8000
   STA $8000
   STA $8000  ; first 4 writes go to $8000
   STA $E000  ; 5th write goes to $E000

The above code will affects reg $E000 only!!!   Despite $8000 being written to several times, reg $8000
remains totally unchanged!

How this works is that when the game writes to $8000-FFFF, it goes to a hidden temporary register.  That
register records the bits being written.  Only after all 5 bits are written does the final 5-bit value move
to the desired *actual* register.

Only bits 7 and 0 are significant when writing to a register:

Temporary reg port ($8000-FFFF):
  [r... ...d]
     r = reset flag
     d = data bit

When 'r' is set:
  - 'd' is ignored
  - hidden temporary reg is reset (so that the next write is the "first" write)
  - bits 2,3 of reg $8000 are set (16k PRG mode, $8000 swappable)
  - other bits of $8000 (and other regs) are unchanged

When 'r' is clear:
  - 'd' proceeds as the next bit written in the 5-bit sequence
  - If this completes the 5-bit sequence:
      - temporary reg is copied to actual internal reg (which reg depends on the last address written to)
      - temporary reg is reset (so that next write is the "first" write)


Confusing?  Yeah it looks confusing, but isn't really.  For an example:

  LDA #$00
  STA $8000 ; 1st write ('r' bit is clear)
  STA $8000 ; 2nd write

  LDA #$80
  STA $8000 ; reset ('r' bit is set)

  LDA #$00
  STA $8000 ; 1st write (not 3rd!)



Variants:
--------------------------
There are also a slew of board variations which are assigned to mapper 001 as well.  See the sections at the
bottom for details.  Determining which variant a game uses is difficult -- likely you'll need to fall back
to a CRC or hask check.



Registers:
--------------------------

Note again, these registers are internal and are not accessed directly!  Read notes above.


  $8000-9FFF:  [...C PSMM]
    C = CHR Mode (0=8k mode, 1=4k mode)
    P = PRG Size (0=32k mode, 1=16k mode)
    S = Slot select:
        0 = $C000 swappable, $8000 fixed to page $00 (mode A)
        1 = $8000 swappable, $C000 fixed to page $0F (mode B)
        This bit is ignored when 'P' is clear (32k mode)
    M = Mirroring control:
        %00 = 1ScA
        %01 = 1ScB
        %10 = Vert
        %11 = Horz


  $A000-BFFF:  [...C CCCC]
    CHR Reg 0

  $C000-DFFF:  [...C CCCC]
    CHR Reg 1

  $E000-FFFF:  [...W PPPP]
    W = WRAM Disable (0=enabled, 1=disabled)
    P = PRG Reg


Disabled WRAM cannot be read or written.  Earlier MMC1 versions apparently do not have this bit implimented.
Later ones do.



CHR Setup:
--------------------------
There are 2 CHR regs and 2 CHR modes.

            $0000   $0400   $0800   $0C00   $1000   $1400   $1800   $1C00 
          +---------------------------------------------------------------+
C=0:      |                            <$A000>                            |
          +---------------------------------------------------------------+
C=1:      |             $A000             |             $C000             |
          +-------------------------------+-------------------------------+



PRG Setup:
--------------------------
There is 1 PRG reg and 3 PRG modes.

               $8000   $A000   $C000   $E000
             +-------------------------------+
P=0:         |            <$E000>            |
             +-------------------------------+
P=1, S=0:    |     { 0 }     |     $E000     |
             +---------------+---------------+
P=1, S=1:    |     $E000     |     {$0F}     |
             +---------------+---------------+


On Powerup:
----------------------------

This varies from version to version.  Earlier MMC1 versions have no determined startup state.  Later ones do.

 - bits 2,3 of $8000 are set (16k PRG mode, $8000 swappable)

WRAM Disable varies wildly from version to version.  Some versions don't have it at all, other versions have
it cleared initially, others have it set initially, and others have it random.  To be "safe", when
homebrewing, assume it's disabled (and have your game explicitly enable it before accessing WRAM), and when
emudeving, assume it's enabled at startup (or else some early MMC1 games will break in your emu).




Additional Notes:
----------------------------

Consecutive writes that are too close together are apparently ignored.  One game where this is significant
is Bill & Ted's Excellent Video Game Adventure.  That game does the following HORRIBLY SLOPPY code to reset
the mapper:

  INC $FFFF  (where $FFFF contains $FF when read)

For those of you who really know your 6502... you know that this will read $FFFF (getting $FF), write that
value ($FF) back to $FFFF, increment it by one, then write the new value ($00) to $FFFF.  This results in
two register writes:  $FF, then $00.

Normally, such writes would reset the mapper, then write a single data bit.  However if your emu does it
like that, the game will crash, as the game expects the next write to be the 1st in a 5-bit sequence (and
your emu will treat it like the 2nd).

However these writes are performed on consecutive CPU cycles -- which apparently are too close to each other.
As such, only the first write (of $FF) is acknowledged and performed, and the second write (of $00) is
ignored.  Emulating in this manner results in a fully functioning game.

So while it is unsure exactly how far apart the writes must be, you can assume that the distance between
them must be at least 2 CPU cycles.  Such that Read/Modify/Write instructions (like INC) will only
acknowledge the first write, but two consecutive write instructions (like 2 side-by-side STA's) will work
normally.


-----------------------------------------
-----------------------------------------


Special Variant -- SUROM:
--------------------------

Example Games:
  Dragon Warrior 4
  Dragon Quest 4


The MMC1 PRG reg is only 4 bits wide.  This means that normally, page $0F is the highest page number you can
access.  With 16k pages... this limits typical MMC1 to 256k PRG ($10 pages * $4000 per page).  SUROM
"hijacks" one of the bits from the CHR registers and uses it as an additional PRG bit.  This allows for
access to $1F pages, allowing 512k PRG.

  $A000-BFFF:  [...C CCCC]     CHR reg 0
               [...P ....]     hijacked PRG bit

  $C000-DFFF:  [...C CCCC]     CHR reg 1
               [...P ....]     hijacked PRG bit

When in 4k CHR mode, 'P' in both $A000 and $C000 *must* be set to the same value, or else pages will
constantly be swapped as graphics render!  In 8k CHR mode (which is what DQ4 uses), $C000 is irrelevent
since it is ignored, and $A000 is used exclusively.

The hijacked PRG bit selects which 256k block is used for *ALL* PRG... *including* fixed pages.  Meaning
fixed page $0F @ $C000 can swap between page $0F and $1F.



Special Variant -- SOROM:
--------------------------

Example Games:
  Nobunaga's Ambition
  Romance of the Three Kingdoms
  Genghis Khan


SOROM has 16k PRG-RAM (instead of the typical 8k), and hijacks unused bits from the CHR regs in order to
select which 8k PRG-RAM page is at $6000-7FFF.  The first 8k of PRG-RAM (page 0) is not battery backed --
but the second 8k is.

When in 4k CHR Mode:

  $A000-BFFF:  [...R ...C]
    R = PRG-RAM page select
    C = CHR reg 0

  $C000-DFFF:  [...R ...C]
    R = PRG-RAM page select
    C = CHR reg 1

  In 4k CHR mode, above 'R' bits MUST be set to the same value or else PRG-RAM will automatically swap as
the PPU fetches tiles to render!


When in 8k mode:

  $A000-BFFF:  [.... R...]   PRG-RAM page select
  $C000-DFFF:  [.... ....]   Unused



Special Variant -- SXROM:
--------------------------

Example Games:
  Final Fantasy 1 & 2  (the combo cart, not the individual games)
  Best Play Pro Yakyuu Special


SXROM is sort of like a combination of SUROM and SOROM.  It uses bits from CHR regs to have an additional
PRG bit, and also to have swappable PRG-RAM.  SXROM has a whopping 32k PRG-RAM (all of which can be battery
backed).


When in 8k CHR mode:

  $A000-BFFF:  [...P RR..]
    P = PRG-ROM 256k block select (just like on SUROM)
    R = PRG-RAM page select (selects 8k @ $6000-7FFF, just like SOROM)


I'm uncertain of behavior when in 4k CHR mode.  I suspect it is similar to SUROM, in that the registers must
be identical or else undesired swapping will occur as the PPU renders.