Mapper000 Mapper001 Mapper002 Mapper003
Mapper004 Mapper005 Mapper007 Mapper009
Mapper010 Mapper011 Mapper013 Mapper015
Mapper016 Mapper018 Mapper019 Mapper021
Mapper022 Mapper023 Mapper024 Mapper025
Mapper026 Mapper032 Mapper033 Mapper034
Mapper044 Mapper045 Mapper046 Mapper047
Mapper048 Mapper049 Mapper050 Mapper052
Mapper057 Mapper058 Mapper060 Mapper061
Mapper062 Mapper064 Mapper065 Mapper066
Mapper067 Mapper068 Mapper069 Mapper070
Mapper071 Mapper072 Mapper073 Mapper074
Mapper075 Mapper076 Mapper077 Mapper078
Mapper079 Mapper080 Mapper082 Mapper085
Mapper086 Mapper087 Mapper088 Mapper089
Mapper090 Mapper091 Mapper092 Mapper093
Mapper094 Mapper095 Mapper096 Mapper097
Mapper105 Mapper107 Mapper112 Mapper113
Mapper115 Mapper118 Mapper119 Mapper140
Mapper152 Mapper154 Mapper159 Mapper164
Mapper165 Mapper180 Mapper182 Mapper184
Mapper185 Mapper189 Mapper191 Mapper192
Mapper193 Mapper194 Mapper200 Mapper201
Mapper203 Mapper205 Mapper207 Mapper209
Mapper210 Mapper225 Mapper226 Mapper227
Mapper228 Mapper230 Mapper231 Mapper232
Mapper233 Mapper234 Mapper240 Mapper242
Mapper243 Mapper245 Mapper246
女孩不哭(QQ:191035066)@2012-07-19 00:15:52 @ http://www.cnblogs.com/nbsofer
******************************************
* iNES Mappers by Mapper Number *
* v0.6.1 *
* by Disch *
******************************************
Read this doc
--------------------------
The mapper pages use charts and symbols and abbreviations and stuff which aren't clarified in each
individual doc, but are covered here. You could probably get away with just skimming this doc and/or only
coming back to it if something in a specific mapper doc seems unclear.
RAM Names
--------------------------
"WRAM", "SRAM", and "PRG-RAM" are used synonymously and inconsistently in these docs. Kind of sloppy of
me, I know. All three terms refer to on-cartridge RAM.
Mirroring
--------------------------
The NES only has two physical nametables. These nametables are referred to as "NTA" and "NTB". There are
4 "slots" for nametables to be accessed: $2000 (upper-left), $2400 (upper-right), $2800 (lower-left), and
$2C00 (lower-right)
Mappers which can customize the nametable layout may have a chart like the below to illustrate which
nametable goes to which slot:
[ $2000 ][ $2400 ]
[ $2800 ][ $2C00 ]
Most mappers which control mirroring usually pick from 2 to 4 standard mirroring configurations:
Horizontal ("Horz"), Vertical ("Vert"), 1-Screen A ("1ScA"), and 1-Screen B ("1ScB"). These arrange the
nametables like so:
Vert Horz
-------------- --------------
[ NTA ][ NTB ] [ NTA ][ NTA ]
[ NTA ][ NTB ] [ NTB ][ NTB ]
1ScA 1ScB
-------------- --------------
[ NTA ][ NTA ] [ NTB ][ NTB ]
[ NTA ][ NTA ] [ NTB ][ NTB ]
A few mappers also support 4-screen mirroring, which uses 4 full nametables so that each slot has its own
unique nametable. Since the NES only has 2k for nametables, for a game to have 4-screen mirroring,
additional VRAM must be present on the cartridge. I only know of a grand total of three games which use
4-screen mirroring, and they will be mentioned in their respective docs.
Swap Charts
----------------------------
PRG/CHR swapping schemes are generally outlined in a chart. A PRG chart might look like so:
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $7EFA | $7EFC | $7EFE | { -1} |
+-------+-------+-------+-------+
This indicates which register is used to select a PRG page for which region. In this example, the register
at $7EFA selects an 8k page for $8000-9FFF.
Numbers surrounded by {curly braces} mean the page is fixed. Here, $E000-FFFF is fixed to page -1.
Negative pages indicate the last pages are used. IE: "-1" means to use the last page of PRG, "-2" would be
the second last, etc.
CHR charts work similarly:
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| <$7EF0> | <$7EF1> | $7EF2 | $7EF3 | $7EF4 | $7EF5 |
+---------------+---------------+-------+-------+-------+-------+
Here, the register at $7EF3 selects a 1k CHR page for $1400-17FF, while $7EF0 selects a 2k CHR page for
$0000-07FF.
Numbers surrounded by <> symbols indicate the low bits of the given page number are ignored. This is
typical where a mapper deals with several different page sizes. For example, $7EF0 selects a 2k page, but
its low bit is ignored (effectively, you must right-shift its value by 1 for the actual page number).
Example: if $7EF0=$05, 2k page $02 would be selected ($05 right shift 1 = $02)
Double <>'s (example: "<<$7EF0>>") would mean the low 2 bits are ignored (right shift the value by 2).
Numbers without <> symbols are referred to as "actual" page numbers.
Charts may have multiple rows if there are multiple swapping modes.
Erroneous noob swapping
----------------------------
Some newbies tend to make an understandable, but incorrect assumption about how swapping works. Given the
following CHR chart:
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
CHR Mode 0: | | | R:2 | R:3 | R:4 | R:5 |
+---------------+---------------+---------------+---------------+
CHR Mode 1: | R:2 | R:3 | R:4 | R:5 | | |
+-------+-------+-------+-------+---------------+---------------+
A newbie might think that they can cleverly manipulate modes to select 1k pages across the board, rather
than having those two 2k chunks in there. IE: They think that they can set R:2-R:5 in mode 0, then switch
to mode 1, set R:2-R:5 again... and that would select each 1k page individually.
This, of course, is not now it works. "Swapping" isn't actually swapping. What's actually happening is
when the NES reads from a certain address the high bits of the address are being replaced by the contents
of a mapper register. Because of this, mapper registers (and swapping modes) are accessed constantly at
runtime... not just when the value is written.
For example... setting R:2 in mode 0, then switching to mode 1 will have the exact same effect as switching
to mode 1 first, then setting R:2. Both methods end up in mode 1, and both set only R:2... meaning the end
result is selecting a 1k page at $0000.
You might say a second "swap" occurs when the mode is changed. That is... if a game were to change modes,
they would see the pattern tables "flip", even though they didn't swap anything.
Register bit layouts
----------------------------
Registers often have different bits of the written value do different things. Or sometimes only some bits
are significant and others are ignored. In these situations, bitfields are indicated by a pair of brackets.
Example:
$8000: [CP.. .AAA]
The above shows 3 seperate things ('A', 'P', and 'C') that the register controls, and which bits are
assigned to those things. Bits marked as '.' are irrelevent and unused. These bits are listed high bit
first (here, 'C' would be bit 7)
Some mappers (usually multicarts) also take bits from the address written to -- not just the value
written. These instances will be marked with brackets with "A~" before them. A good example of this:
$8000-FFFF: [.... ..CC]
A~[..MH HPPP PPO. CCCC]
The first bracket represents the value written, and the second bracket (with the A~) represents the address
written to.
Address/Data ports
----------------------------
Many mappers have several registers which are accessed by writing an address to one area, then writing the
data you want to write to the reg to another area. The most common example of this is MMC3 (mapper 004).
$8000 is the address port, and $8001 is the data port.
Since $8001 actually accesses 8 different registers, $8001 can't appear in charts and descriptions and
stuff. So for address/data ports like this, the accessed registers are referred to as "R:#" (where # is the
hex address by which they're accessed). For example MMC3's 8 regs would be "R:0" through "R:7".
For example, if a game wanted to change R:4, it would do the following:
LDA #$04
STA $8000 ; set address to $04
LDA whatever
STA $8001 ; since address is $04, this sets R:4
Timing / Dots
----------------------------
When discussing the timing of PPU triggered IRQs, I refer to 'dots'. IE: "The IRQ will fire on dot 260 of
the scanline". 'Dots' are otherwise known as PPU Cycles. Each scanline consists of 341 dots -- and on NTSC,
there are 3 dots to every 1 CPU cycle.
Bus Conflicts
-----------------------------
Some simple mappers suffer from bus conflicts. This means that when registers share CPU space with PRG,
the value you write to the address must match what is read from that address or bad things will happen
Many games do this by having a LUT of common values somewhere and indexing it:
Swap_LUT:
.db $00, $01, $02, $03, $04, $05, $06, $07
PRG_Swap:
; assume A is the desired page to swap to (00-07)
TAX
STA Swap_LUT,X
RTS
This ABSOLUTELY NEEDS TO BE DONE for these mappers You will break your ROM
I'm sure I missed some mappers that have bus conflicts -- but I tried to mark all the ones I know do, and
suspect might.
When a bus conflicting write occurs, the result is usually an AND of the two potential values -- but such
behavior should not be relied on.
Register Masking / Ranges
------------------------------
Many times, a single register can be accessed by several addresses. For example when you see something
like:
$8000-FFFF: PRG Reg
That means a write to anywhere between $8000-FFFF will access the PRG Reg.
In that same vein, sometimes not all address lines are used when decoding which register is to be accessed.
That is, some bits of the address don't matter. This creates a masking effect where registers are mirrored
in a semi-weird fashion accross an address range. This would be marked in docs with something like:
Range,Mask: $8000-FFFF, $E001
This would mean that within the range $8000-FFFF, you'd use $E001 as a mask for determining which register to
use. IE: $D3F7 would mirror $C001, because $D3F7 AND $E001 = $C001.
PRG/CHR Masking
------------------------------
When a game selects a page higher than there is ROM for, the page number would be masked to select an
appropriate page. For example... if a game only has $08 pages of CHR, and it selects page $0A, then it would
actually select page $02 (because $0A AND ($08-1) = $02).
In that same vein... fixed "last pages" {-1}, {-2}, etc are really pages $FFFF, $FFFE, etc -- and the mask
happens to make that select the last or second last page.
This is why PRG/CHR sizes must always be a power of 2, except in extremely rare cases where there's an odd
number of chips (and those cases are handled specially by the mapper).
Powerup/Reset
-----------------------------
Do not assume the state of anything at startup. Mapper registers, like RAM, contain pseudo-random garbage
on system powerup, except in special cases, which will be noted in the appropriate docs.
If no such note is made, you cannot assume anything.
PRG-AND, PRG-OR, Blocks, etc
-----------------------------
Multicarts (and even some single game carts) employ a type of block system which lets the game choose a
block, and then will only swap to pages within that block. In these docs I often illustrate this with PRG-OR
and PRG-AND values.
For an example, let's say you have a game with the following PRG pages selected:
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $02 | $16 | { -2} | { -1} |
+-------+-------+-------+-------+
And let's say the PRG-AND is $0F, and the PRG-OR is $20. This would result in the following pages being
selected:
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $22 | $26 | $2E | $2F |
+-------+-------+-------+-------+
simply, it's "(desiredpage AND PRGAND) OR PRGOR". Note that even the fixed pages are affected by this.
CHR-AND and CHR-OR operate the same way, but with CHR pages.
Always apply these values *before* any downshifting caused by <> symbols.
========================
= Mapper 000 =
========================
aka
--------------------------
NROM
"no mapper"
Example Games:
--------------------------
Ice Climber
Excitebike
Balloon Fight
Super Mario Bros.
Notes:
--------------------------
No swapping of any kind. All slots fixed, mirroring is hardwired, etc.
========================
= 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.
========================
= Mapper 002 =
========================
aka
--------------------------
UxROM (and compatible)
Example Games:
--------------------------
Mega Man
Castlevania
Contra
Duck Tales
Metal Gear
Notes:
---------------------------
UxROM has bus conflicts, however mapper 002 is meant to be UxROM and compatible. So some mappers which were
similar in function, but did not have bus conflicts are included.
Additionally, UxROM does not have an 8 bit reg. UNROM is capped at 128k PRG, and UOROM is capped at 256k.
So to be "safe":
- for homebrewing: assume bus conflicts, do not exceed 256k
- for emudev: assume no bus conflicts, use all 8 PRG reg bits
There is no CHR swapping. Every mapper 002 game I've ever seen has CHR-RAM.
Registers (**BUS CONFLICTS** sometimes):
--------------------------
$8000-FFFF: [PPPP PPPP]
PRG Reg
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 003 =
========================
aka
--------------------------
CNROM (and compatible)
Example Games:
--------------------------
Solomon's Key
Arkanoid
Arkista's Ring
Bump 'n' Jump
Cybernoid
Registers (**BUS CONFLICTS** sometimes):
--------------------------
$8000-FFFF: [CCCC CCCC]
CHR Reg (selects 8k @ $0000)
Notes:
---------------------------
CNROM has bus conflicts, however mapper 003 is meant to be CNROM and compatible. So some mappers which were
similar in function, but did not have bus conflicts are included.
Additionally, CNROM's reg is only 2 bits wide... therefore it is capped at 32k CHR.
So to be "safe":
- for homebrewing: assume bus conflicts, do not exceed 32k CHR
- for emudev: assume no bus conflicts, use all 8 reg bits
There is no PRG swapping.
The game Cybernoid seems to behave very strangely. It uses unprepped system RAM... and it is as if it
actually relies on bus conflicts (AND written value with value read from address)
========================
= Mapper 004 =
========================
aka
--------------------------
MMC3
TxROM
(MMC6)
(HxROM)
Example Games:
--------------------------
Mega Man 3, 4, 5, 6
Kirby's Adventure
Gauntlet
Rad Racer 2
Startropics 1, 2 (MMC6)
Super Mario Bros. 2, 3
... a zillion other games (most common mapper)
4-Screen Notes:
---------------------------
TR1ROM and TVROM are two of the *very few* boards to use 4-screen mirroring. The only mapper 004 games which
use 4-screen mirroring I know of are Rad Racer 2 and Gauntlet. Several other games are incorrectly labelled
as being 4-screen when they are in fact, not (ex: Gauntlet 2).
TR1ROM and TVROM are both configured in a way which uses on-cart WRAM as VRAM for the nametables. However
this means the WRAM is not tied to the CPU, therefore they do not have any SRAM/WRAM
So to be "safe":
- when homebrewing: choose either 4-screen or WRAM. You can't have both
- when emudeving: permanently disable WRAM when 4-screen. This does not break any games.
4-screen mirroring for these boards is hardwired When in 4-screen mode, your emu must ignore writes to the
mirroring reg.
Also note that many Rad Racer 2 dumps are floating around which do not indicate it is 4-screen. So if you
try that game in your emu and the graphics are screwed, that's the first thing to check.
IRQ Notes:
---------------------------
IRQ Operation on this mapper is simple at first glance, however its precise operation gets very complex.
This mapper is infamously one of the hardest (if not the very hardest) mapper to emulate accurately -- a
double-whammy since it's also hands down the most common mapper around.
Be sure to read 'Basic IRQ operation' below, and I recommend you seriously consider skimming 'Detailed IRQ
operation' as well -- especially if you're emudeving.
Other notes:
---------------------------
Low G Man will actually confirm that WRAM disabling works properly, and will break if it isn't. So if your
emu ignores WRAM disabling and always has it enabled, Low G Man will break (specifically, during the
level 1 boss fight)
Registers:
---------------------------
Range,Mask: $8000-FFFF, $E001
$8000: [CP.. .AAA]
C = CHR mode select (see CHR setup)
P = PRG mode select (see PRG setup)
A = Address for use with $8001
$8001: [DDDD DDDD] -- data port
R:0 -> CHR reg 0
R:1 -> CHR reg 1
R:2 -> CHR reg 2
R:3 -> CHR reg 3
R:4 -> CHR reg 4
R:5 -> CHR reg 5
R:6 -> PRG reg 0
R:7 -> PRG reg 1
$A000: [.... ...M]
Mirroring: 0=Vert
1=Horz
Ignore when 4-screen
$A001: [EW.. ....]
E = Enable WRAM (0=disabled, 1=enabled)
W = WRAM write protect (0=writable, 1=not writable)
$C000: [IIII IIII] IRQ Reload value
$C001: [.... ....] IRQ Clear
$E000: [.... ....] IRQ Acknowledge / Disable
$E001: [.... ....] IRQ Enable
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
CHR Mode 0: | | | R:2 | R:3 | R:4 | R:5 |
+---------------+---------------+---------------+---------------+
CHR Mode 1: | R:2 | R:3 | R:4 | R:5 | | |
+-------+-------+-------+-------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
PRG Mode 0: | R:6 | R:7 | { -2} | { -1} |
+-------+-------+-------+-------+
PRG Mode 1: | { -2} | R:7 | R:6 | { -1} |
+-------+-------+-------+-------+
Basic IRQ Operation
---------------------------
MMC3 IRQs utilize a scanline counter. The basic steps to making it work are as follows:
1) Set the desired number of scanlines you want to wait by writing N to $C000
2) Reset the internal IRQ counter by writing any value to $C001
3) Enable IRQs by writing any value to $E001
An IRQ will then fire after N+1 rendered scanlines, at which point, you would write any value to $E000 to
acknowledge the IRQ, and disable further IRQs (and possibly repeat the above 3 steps if you want to fire
another IRQ this frame).
The MMC3 counts scanlines by watching the CHR accesses the NES makes. Therefore in order for this IRQ
counter to work properly, the NES must be making the accesses that the MMC3 is expecting. If you have
abnormal settings, you will confuse the MMC3 and IRQs will not work properly. Therefore, you must follow
these rules:
1) The IRQ counter will only count when the PPU is on (sprites and/or BG enabled).
2) Do not manipulate $2006 or $2007 while using IRQ counter
3) Do not set $C000 to $00
4) BG and Sprites must use opposing pattern tables for CHR. EG:
a) if 8x16 sprites, BG must use $0xxx, *ALL* sprites must use $1xxx
b) if 8x8 sprites, if BG is using $0xxx, sprites must use $1xxx
c) if 8x8 sprites, if BG is using $1xxx, sprites must use $0xxx (slightly abnormal)
With settings 'a' and 'b', the IRQ will occur after dot 260. With setting 'c', it will occur after dot 324
of the *previous* scanline.
The IRQ Counter consists of several parts:
1) Actual 8-bit IRQ counter (not directly accessable)
2) 8-bit latch, or reload value (reg $C000)
3) IRQ Enable flag
4) IRQ Pending flag
IRQ Registers interact with the above parts as follows:
reg $C000 - sets IRQ Reload value
reg $C001 - sets the actual IRQ counter to 0 (regardless of what value is written)
reg $E000 - clears both IRQ Enable flag and IRQ Pending flag
reg $E001 - sets IRQ Enable flag
Every time the MMC3 detects a scanline, the following IRQ Counter logic is executed. Note this occurs EVEN
IF IRQs are disabled (the IRQ counter is always counting):
- If IRQ Counter is 0...
a) reload IRQ counter with IRQ Reload value
- Otherwise...
a) Decrement IRQ counter by 1
b) If IRQ counter is now 0 and IRQs are enabled, trigger IRQ
Note that 241 scanlines are counted per frame (the 240 rendered scanlines, and the "prerender" scanline).
Detailed IRQ Operation
---------------------------
MMC3 detects scanlines by watching A12 ($1000) on the PPU bus. Every time a rising edge occurs (transitions
from 0->1), and it hasn't been too close to the previous rising edge, the IRQ counter gets clocked.
Under *normal* conditions (BG using $0xxx, sprites using $1xxx), A12 will rise exactly 8 times every scanline
(once for each sprite CHR fetch). However the 8 rises are so close together that only the first is 'seen'.
During rendering and pre-render scanlines the PPU is fetching NT and CHR data from the cart through a series
of reads. Each read updates the PPU Address lines (including A12), and each read takes 2 PPU cycles (2
dots). There are 4 reads per tile, and 42 tiles per scanline:
- 32 BG tiles
- 8 Sprite tiles (for the next scanline)
- 2 BG tiles (for the next scanline)
Each tile requires 4 reads, each read is 2 dots:
dot 0: Name table fetch ($2xxx -- A12 is low)
dot 2: Attribute fetch ($2xxx -- A12 is low)
dot 4: Low CHR fetch ($0xxx or $1xxx -- A12 is low or high)
dot 6: High CHR fetch ($0xxx or $1xxx -- A12 is low or high)
If the tile being fetched is using the right-hand pattern table ($1xxx), then A12 goes high on dot 4 of that
8-dot sequence. Otherwise, A12 stays low throughout.
This 8-dot sequence is repeated for each tile.. meaning there are 42 opportunities for A12 to rise. These
opportunities occur on the following dots:
4, 12, 20, ..., 244, 252 (32 BG tiles)
260, 268, 276, 284, 292, 300, 308, 316 (8 Spr tiles)
324, 332 (2 BG tiles)
(You might be able to see now how I came up with those 260, 324 numbers I threw at you earlier)
MMC3 seems to ignore rises that are too close together. This is why the 8 sprite fetches will only clock
the counter once. Exactly how far apart the rising edges have to be is unknown, but it is somewhere between
14 and 16 dots. So any two consecutive opportunities are too close together (including the most distant
332->4), but any two non-consecutive opportunities will both be acknowledged.
Figuring whether the tile is being fetched from $0xxx or $1xxx is usually easy. BG and 8x8 sprites are
always fetched from an assigned pattern table (configurable by PPU reg $2000). However, 8x16 sprites can
come from either pattern table. So which tile is begin fetched depends on which sprite is being fetched....
which depends on what scanline you're on, and what sprites are found to be in-range on that scanline. For
scanlines which contain less than 8 sprites, tile $FF is fetched as a dummy (in 8x16 sprites, this would be
from the $1xxx pattern table).
This is why, when you have 8x16 sprites, ALL sprites must use the right-hand pattern table. If you have
sprites using the left and the right, you'll probably end up having some scanlines where the IRQ counter
counts the same scanline multiple times All depending on which sprites are in-range and when. For example,
if there are 4 sprites on the scanline using $0xxx, and 4 using $1xxx, the IRQ counter might count the
scanline anywhere from 1 to 4 times
0,0,0,0,1,1,1,1 0,1,0,1,0,1,0,1 This is also why the IRQ counter isn't clocked when both BG and sprites use the left pattern table (since
there is never any rising edge, the MMC3 never detects any scanlines).
$2006 and $2007
---------------------------
A game can manually clock the IRQ counter (either on accident, or by design) by manipulating $2006 and $2007.
A12 is updated (potentially triggering a rising edge) when the PPU address is updated by these registers.
On $2007 reads/writes, and on the second $2006 write. This is why messing with $2006 and $2007 after you
prep your IRQ stuff may screw up your IRQs unless you're careful.
IRQ Counter priming
---------------------------
Some games seem to prime the IRQ counter by repeatedly writing $0000 and $1010 to $2006. This toggles A12,
clocking the IRQ counter. It is unknown whether or not this is actually required.
Reload value of $00
---------------------------
Different MMC3 versions behave differently when you set $C000 to $00. There are at least two (possibly more)
behaviors. These behaviors are mentioned in the readme accompanied with blargg's MMC3 test ROMs, which, if
you're emudeving, I highly recommend you pick up. Otherwise, the behavior of having a reload value of $00
is unreliable and/or undesirable, and should be avoided at all costs when homebrewing/hacking.
Special Variant -- MMC6:
--------------------------
Startropics 1 and 2 are both MMC6 games (not MMC3). However, they are unfortunately assigned the same mapper
number, despite being slightly incompatible. There is no simple way to determine MMC3 from MMC6. You'll
probably have to use a CRC or hash check or something.
For the most part they are the same -- but the big difference is the WRAM. MMC6 has only 1k of WRAM,
whereas MMC3 games have 8k. It is also mapped a bit differently, and is enabled/disabled differently from
MMC3.
MMC6 registers are as follows. All other registers behave just as they do on MMC3:
$8000: [CPW. .AAA]
C,P,A = Same as on MMC3
W = WRAM Enable (0=disabled, 1=enabled)
$A001: [HhLl ....]
H,L = Enable WRAM block (0=disabled, 1=enabled)
h,l = WRAM block write protect (0=writes disabled, 1=writes enabled)
The 1k of WRAM is split into 2 512 byte blocks... one at $7000-71FF and another at $7200-73FF. Each block
can be controlled independently through $A001. H,h bits deal with the high block ($7200), and L,l bits deal
with the low block ($7000).
If only one block is enabled, the disabled block will read back as $00. However if BOTH blocks are disabled,
reading either will return open bus.
$7000-73FF is mirrored throughout $7400-7FFF. However, $6000-6FFF is always open bus (unmapped).
$8000.5, when clear (to disable WRAM), simply sets $A001 to $00 and keeps it there. Writing to $A001 when
$8000.5 is clear will have no effect.
========================
= Mapper 005 =
========================
aka
--------------------------
MMC5
ExROM
Example Games:
--------------------------
Castlevania 3
Just Breed
Uncharted Waters
Romance of the 3 Kingdoms 2
Laser Invasion
Metal Slader Glory
Uchuu Keibitai SDF
Shin 4 Nin Uchi Mahjong - Yakuman Tengoku
Test ROM Notes:
---------------------------
- Uchuu Keibitai SDF is the only known game to use split screen mode (during the intro, where it shows ship
stats)
- Shin 4 Nin Uchi Mahjong uses the extra PCM channel ($5011) as well as the other extra sound
- Uncharted Waters does PRG-RAM swapping
- Just Breed uses ExAttribute mode everywhere, as well as the extra sound.
General Notes:
---------------------------
MMC5 is the infamous juggernaut mapper. It does a whole slew of neat tricks, making it far more powerful
than any other mapper around. Though despite it's apparent complexity, it's suprisingly straightforward to
emulate (that doesn't mean it's easy, though).
It's a shame that the only real games to use this mapper were a ton of really, really terrible Koei strategy
games. Such a waste.
RAM Notes:
----------------------------
MMC5 can address up to 64k PRG-RAM This is significantly more than the usual 8k. When emulating, it's
easiest just to give MMC5 games a full 64k, since the header doesn't really provide a decent way to indicate
how much PRG-RAM actually exists.
In addition to PRG-RAM, the MMC5 itself has a full 1k of 'ExRAM' which can be accessed by both the CPU and
PPU. This ExRAM can be used for many things... from plain vanilla WRAM, to an extra nametable, to a seperate
split screen, to extending normal attribute tables.
This document's organization:
---------------------------
Since there are so many registers for this mapper, and it has so many features, registers will be listed and
outlined as the features are explained... and the overall registers section will be extremely brief --
serving primarily as a very quick reference or checklist.
Misc Modes and Setup:
---------------------------
$5102: [.... ..AA] PRG-RAM Protect A
$5103: [.... ..BB] PRG-RAM Protect B
To allow writing to PRG-RAM you must set these regs to the following values:
A=%10
B=%01
Any other values will prevent PRG-RAM writing.
$5104: [.... ..XX] ExRAM mode
%00 = Extra Nametable mode ("Ex0")
%01 = Extended Attribute mode ("Ex1")
%10 = CPU access mode ("Ex2")
%11 = CPU read-only mode ("Ex3")
CHR Setup:
---------------------------
The MMC5 has two sets of CHR regs. One set is used for sprites, the other is used for BG. The MMC5
carefully watches what tiles are being fetched and when (or has some other way of syncing with the NES
somehow), which allows it to tell when the NES is fetching BG tiles, and when it's fetching sprite tiles.
As such, it can use different regs accordingly, allowing games to basically have 12k of CHR "active" at once
instead of the usual 8k This means you can have a full 512 tiles exclusively for sprites, and have an
additional 256 tiles for the BG
CHR Mode Select Reg:
$5101: [.... ..CC]
%00 = 8k Mode
%01 = 4k Mode
%10 = 2k Mode
%11 = 1k Mode
'High' CHR Reg:
$5130 [.... ..HH] (see below)
'A' Regs:
$5120 - $5127
'B' Regs:
$5128 - $512B
When in 8x16 sprite mode, both sets of registers are used. The 'A' set is used for sprite tiles, and the
'B' set is used for BG. This makes it so that sprites can have a full 8k of CHR available, without having
to share any of the tiles with the BG (since the BG uses it's own 4k of CHR, designated by the 'B' set). It
is unsure what you will get when reading CHR via $2007.
When in 8x8 sprite mode, only one set is used for both BG and sprites. Either 'A' or 'B', depending on which
set is written to last. If 'B' is used, $1000-1FFF always mirrors $0000-0FFF (making the 'B' set pretty
worthless with 8x8 sprites)
'A' Set (sprites):
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
C=%00: | $5127 |
+---------------------------------------------------------------+
C=%01: | $5123 | $5127 |
+-------------------------------+-------------------------------+
C=%10: | $5121 | $5123 | $5125 | $5127 |
+---------------+---------------+---------------+---------------+
C=%11: | $5120 | $5121 | $5122 | $5123 | $5124 | $5125 | $5126 | $5127 |
+-------+-------+-------+-------+-------+-------+-------+-------+
'B' Set (BG):
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+
C=%00: | $512B* |
+-------------------------------+
C=%01: | $512B |
+-------------------------------+ $1xxx always mirrors $0xxx
C=%10: | $5129 | $512B |
+---------------+---------------+
C=%11: | $5128 | $5129 | $512A | $512B |
+-------+-------+-------+-------+
* $512B in 8k mode is an 8k page number, but only the first half of the 8k page is used.
Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers
contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.
CHR Regs are actually 10 bits wide, not just 8. When you write to the regs, the value written is the low 8
bits, and the high 2 bits are copied from $5130. Example:
LDA #$00
STA $5130 ; high bits = 0
LDA #$20
STA $5127 ; $5127 now = $020
LDA #$02
STA $5130
LDA #$41
STA $5123 ; $5123 now = $241
; and $5127 still = $020 (not $220)
$5130 has an additional role in ExAttribute mode.
PRG/RAM Setup:
---------------------------
$5100: [.... ..PP] PRG Mode Select:
%00 = 32k
%01 = 16k
%10 = 16k+8k
%11 = 8k
$5113: [.... .PPP] (simplified, but technically inaccurate -- see below)
8k PRG-RAM page @ $6000
$5114-5117: [RPPP PPPP]
R = ROM select (0=select RAM, 1=select ROM) **unused in $5117**
P = PRG page
The high bit allows the game to select between ROM and RAM. This allows the game to put PRG-RAM anywhere
between $6000-DFFF (but no higher, since $5117 always selects ROM)
Only RAM can be swapped to $6000-7FFF.
$5117 always selects ROM, never RAM (ROM always at $E000-FFFF).
$6000 $8000 $A000 $C000 $E000
+-------+-------------------------------+
P=%00: | $5113 | <<$5117>> |
+-------+-------------------------------+
P=%01: | $5113 | <$5115> | <$5117> |
+-------+---------------+-------+-------+
P=%10: | $5113 | <$5115> | $5116 | $5117 |
+-------+---------------+-------+-------+
P=%11: | $5113 | $5114 | $5115 | $5116 | $5117 |
+-------+-------+-------+-------+-------+
Technically, $5113 should look something like:
[.... .CPP]
C = Chip select
P = 8k PRG-RAM page on selected chip
MMC5 can address two seperate RAM chips, each up to 32k in size.
This detail can impact how RAM is mirrored across pages if the chip sizes are less than 32k. For example,
Uncharted Waters has two 8k chips (only 16k total -- but on two seperate chips), so it uses selects pages
$00 and $04, rather than $00 and $01 like you may expect. This is because bit 2 is the chip select, and
the 8k on each chip is mirrored to every page on that chip... that is... $00-$03 would all select the first
8k.
Note that no commercial games rely on this mirroring -- therefore you can take the easy way out and simply give
all MMC5 games 64k PRG-RAM.
Mirroring:
---------------------------
$5105: [DDCC BBAA]
MMC5 allows each NT slot to be configured:
[ A ][ B ]
[ C ][ D ]
Values can be the following:
%00 = NES internal NTA
%01 = NES internal NTB
%10 = use ExRAM as NT
%11 = Fill Mode
For example... some typical mirroring setups would be:
( D C B A)
Horz: $50 (%01 01 00 00)
Vert: $44 (%01 00 01 00)
1ScA: $00 (%00 00 00 00)
1ScB: $55 (%01 01 01 01)
ExRAM can act as a 3rd nametable here... but only in Ex0 or Ex1 (see $5104 above). If in Ex2 or Ex3, the PPU
will get $00 when it attempts to read from the nametable. Note that while ExRAM can be used as a nametable
in Ex1, it's probably a bad idea, since ExRAM is also used for Extended attributes in that mode. Therefore,
when using ExRAM as a nametable, you should stick to Ex0.
Fill Mode is a virtual nametable. It is not a full nametable, but rather, as the PPU attempts to read it,
the MMC5 will feed it a specific tile -- thus appearing as though there's a full nametable filled with a
single tile. The tile can be configured by the game with the following regs:
$5106: [TTTT TTTT] Fill Tile
$5107: [.... ..AA] Fill Attribute bits
Extended Attribute Mode:
---------------------------
When in Ex1 mode (see $5104 above), ordinary attribute tables and BG CHR regs are ignored, and instead, each
byte in ExRAM coresponds with an onscreen tile, and assigns that tile a 4k CHR page (allowing you to choose
from 16k tiles instead of 256) and its own attribute bits (allowing each 8x8 tile to have it's own palette,
rather than having the normal 16x16 blocks).
Bytes in ExRAM:
[AACC CCCC]
A = Attribute bits
C = 4k CHR Page
Additionally... $5130 is used directly as the high 2 bits of CHR for every on-screen BG tile when in this
mode. It effectively selects a 256k block for BG to use (in addition to its normal use with CHR swapping).
$5130's runtime value affects all BG tiles, therefore changing $5130 will immediately swap all on-screen BG
when in this mode. Therefore, if/when you change $5130 to swap CHR for sprites, you must write to $5130
again with the desired value for the BG.
Sprites are unaffected by this mode and still use the normal CHR regs.
Which tile uses which byte in ExRAM depends on its position in the nametable. Scrolling is irrelevent. The
tile at $2000 always uses the first byte in ExRAM, $2001 uses the second, etc. $2400, $2800, and $2C00 also
use the first byte of ExRAM.
CPU Accessing ExRAM:
---------------------------
ExRAM can be accessed by the CPU via $5C00-$5FFF. Whether or not you can read or write depends on the
current mode (see $5104):
Mode Readable Writable
-------------------------
Ex0 no *
Ex1 no *
Ex2 yes yes
Ex3 yes no
In Ex0 and Ex1, ExRAM can only be written DURING RENDERING (insane, I know). If a game attempts to write
outside of rendering, $00 is written instead of the desired value. Writes have absolutely no effect in Ex3.
Attempting to read when not readable will return open bus.
8 * 8 -> 16 Multiplier:
---------------------------
MMC5 has a nifty multiplier, similar to the SNES's.
on write:
$5205: multiplicand
$5206: multiplier
on read:
$5205: low 8 bits of product
$5206: high 8 bits of product
Basic functionality is, you write two values you want multiplied to $5205 and $5206, then read the product
back. Multiplication is unsigned. There is no noticable delay -- that is, the product can be read back
right after writing.
Split Screen:
---------------------------
A unique feature to MMC5 is its ability to split the screen vertically down the middle. However due to some
limitations that couldn't be avoided, it ended up not being that useful of a feature.
Note: Split screen mode is only allowed in Ex0 or Ex1. When in Ex2 and Ex3, it is always disabled. I do
not know whether or not the split is affected by Extended Attributes when in Ex1. Judging by the $5202, I
would assume it isn't, but that's a total guess.
$5200: [ER.T TTTT] Split control
E = Enable (0=split mode disabled, 1=split mode enabled)
R = Right side (0=split will be on left side, 1=split will be on right)
T = tile number to split at
$5201: [YYYY YYYY] Split Y scroll
$5202: [CCCC CCCC] 4k CHR Page for split
34 BG tiles are fetched per scanline. MMC5 performs the split by watching which BG tile is being fetched,
and if it is within the split region, replacing the normal NT data with the split screen data. Since it
operates on a per-tile basis... fine horizontal scrolling "carries into" the split region. Setting the
horizontal scroll to 1-7 will result in the split being moved to the left 1-7 pixels, however when you scroll
to 8, the split will "snap" back to its normal position.
Left Split:
Tiles 0 to T-1 are the split.
Tiles T and on are rendered normally.
Right Split:
Tiles 0 to T-1 are rendered normally.
Tiles T and on are the split.
There is no coarse horizontal scrolling of any kind for the split. Right-side splits will always show the
right-hand side of the nametable, and left-hand splits will always show the left-hand side of the nametable.
Coarse horizontal scrolling can still be used for the non-split region.
ExRAM is always used as the nametable in split screen mode.
Vertical scrolling for the split operates like normal vertical scrolling. 0-239 are valid scroll values,
whereas 240-255 will display Attribute table data as NT data for the first few scanlines. The split nametable
will wrap so that the top of the nametable will appear below as you scroll (just as if vertical mirroring
were employed).
$5202 selects (yet another) CHR page to use for the BG. This page is used for the split region only.
IRQ Operation:
---------------------------
MMC5 has a scanline counter for IRQs, however it is significantly more sophisticated than MMC3's, and doesn't
suffer from the same restrictions. It is also a bit easier to use.
Write:
$5203: [IIII IIII] IRQ Target
$5204: [E... ....] IRQ Enable (0=disabled, 1=enabled)
Read:
$5204: [PI.. ....]
P = IRQ currently pending
I = "In Frame" signal
Reading $5204 will clear the pending flag (acknowledging the IRQ).
Basic operation:
1) Write the desired scanline number to $5203
2) Enable IRQs by setting $5204.7
IRQ will then trip on the given scanline number (provided PPU rendering is enabled). The only thing to
note here is that this behavior changes drastically if you turn the PPU off mid-frame... and that an IRQ will
never occur when the target scanline number is 0 or greater than (?or equal to?) $F0.
The "In Frame" signal will read back as set when the PPU is rendering (during scanlines 0-239). Though
it's actual behavior and how it interacts with the IRQ counter is a bit more complex.
Detailed Operation:
The IRQ counter is an up counter, rather than a down counter (like MMC3). Every time the MMC5 detects a
scanline, it does the following:
- If In Frame Signal is clear...
a) Set In Frame signal
b) Reset IRQ counter to 0
c) Clear IRQ pending flag (automatically acknowledging IRQ)
- otherwise...
a) Increment IRQ counter
b) If IRQ counter now equals the trigger value, raise IRQ pending flag
Note that the IRQ pending flag is raised *regardless* of whether or not IRQs are enabled. However, this will
only trigger an IRQ on the 6502 if both this flag *and* the IRQ enable flag is set. Therefore IRQs must
still be enabled for this to have an effect, however the pending flag can still be read back as set via $5204
even when IRQs are disabled.
Also note that the IRQ counter is compared after it is incremented. This is why a trigger value of 0 will
never trigger an IRQ.
At any time when the MMC5 detects that the PPU is inactive, the In Frame signal is automatically cleared.
The MMC5 will detect this after rendering for the frame is complete, and as soon as the PPU is turned off via
$2001. This is why turning off the PPU mid-frame will disrupt IRQs -- since the In Frame signal being
cleared will reset the IRQ counter next scanline.
HOW the MMC5 detects scanlines is still unknown. One theory is that it looks for the two dummy nametable
fetches at the end of the scanline. Or perhaps it counts the number of fetches the PPU performs. Nobody
knows for sure.
The IRQ will trip at the *start* of the desired scanline. Or, more precisely, near the very end of the
previous scanline (closest I can figure is dot 336). That is... if the trigger line is set to 1, the IRQ
will trip on dot 336 of scanline 0.
I am unsure whether or not the last rendered scanline (239) is detected by the MMC5. I would assume it is,
which would mean a trigger value of $F0 would trip an IRQ at the end of rendering. Trigger values above $F0
will never be reached, since rendering stops before then, and the in-frame signal would automatically clear.
Sound:
---------------------------
The MMC5 also has 3 additional sound channels?). Unfortunately,
due to the NES being dumbed down, these can only be heard on a Famicom (or a modified NES).
There are 2 additional Pulse channels, and 1 additional PCM channel.
Registers for them are as follows:
Write:
$5000-5003: Regs for Pulse 1
$5004-5007: Regs for Pulse 2
$5010: PCM Unknown (no games use this part of the PCM)
$5011: PCM output
$5015: [.... ..BA] Enable flags for Pulse 1 (A), 2 (B) (0=disable, 1=enable)
Read:
$5015 [.... ..BA] Length status for Pulse 1 (A), 2 (B)
Pulse channels behave identically to the native NES pulse channels, only they lack a sweep unit. Rather than
going into details on their function, I recommend you pick up blargg's apu reference.
$5000-5007 operate just as $4000-4007 do
$5015 operates just as $4015 does (for reads and writes)
Nobody knows exactly how the PCM channel of the MMC5 works. The patent documentation is unclear, and no
games seem to use it apart from $5011. $5010 likely does *something*... but nobody knows what.
$5011 operates exactly like $4011, only it is 8 bits wide instead of 7. Games *do* use this register to
output sound.
Powerup:
---------------------------
Games seem to expect $5117 to be $FF on powerup (last PRG page swapped in). Additionally, Romance of the 3
Kingdoms 2 seems to expect it to be in 8k PRG mode ($5100 = $03).
Register Overview:
---------------------------
Due to the massive number of registers on this mapper, this section will be brief. Registers were all
covered in detail in the sections above -- this is just to recap them all:
Writable Regs:
$5000-5003: Sound, Pulse 1
$5004-5007: Sound, Pulse 2
$5010-5011: Sound, PCM
$5015: Sound, General
$5100: PRG Mode Select
$5101: CHR Mode Select
$5102-5103: PRG-RAM Write protect
$5104: ExRAM Mode
$5105: Mirroring Mode
$5106: Fill Tile
$5107: Fill Attribute
$5113: PRG-RAM reg
$5114-5117: PRG regs
$5120-5127: CHR regs 'A'
$5128-512B: CHR regs 'B'
$5130: CHR high bits
$5200: Split Screen control
$5201: Split Screen V Scroll
$5202: Split Screen CHR Page
$5203: IRQ Trigger
$5204: IRQ Control
$5205-5206: 8*8->16 Multiplier
$5C00-5FFF: ExRAM CPU Access
Readable Regs:
$5015: Sound Status
$5204: IRQ Status
$5205-5206: 8*8->16 Multiplier Product
$5C00-5FFF: ExRAM CPU Access
========================
= Mapper 007 =
========================
aka
--------------------------
AxROM
Example Games:
--------------------------
Battletoads
Time Lord
Marble Madness
Notes:
---------------------------
AMROM and AOROM have bus conflicts, ANROM does not
AMROM and ANROM are capped at 128k PRG
AOROM is capped at 256k PRG
There is no CHR swapping. Every mapper 007 game I've ever seen has CHR-RAM.
Registers (**BUS CONFLICTS** sometimes):
--------------------------
$8000-FFFF: [...M .PPP]
M = Mirroring:
0 = 1ScA
1 = 1ScB
P = PRG Reg (only 2 bits wide on AMROM/ANROM)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
| $8000 |
+-------------------------------+
========================
= Mapper 009 =
========================
aka
--------------------------
MMC2
PxROM
Example Game:
--------------------------
Mike Tyson's Punch Out
Registers:
---------------------------
Range,Mask: $A000-FFFF, $F000
$A000: PRG Reg
$B000: CHR Reg 0A
$C000: CHR Reg 0B
$D000: CHR Reg 1A
$E000: CHR Reg 1B
$F000: [.... ...M] Mirroring:
0 = Vert
1 = Horz
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $A000 | { -3} | { -2} | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
| $B000 or $C000 | $D000 or $E000 |
+-------------------------------+-------------------------------+
Which reg is used depends on the state of the respective latch. See below.
Latch:
---------------------------
There are two latches on the MMC2. One associated with the left pattern table ($0xxx) and another associated
with right ($1xxx). Each latch operates independently.
Whenever tile $FD is fetched, the appropriate latch is cleared, and whenever tile $FE is fetched, the
appropriate latch is set. This allows games to do mid-scanline swapping automatically by having $FD and $FE
be special marker tiles.
When the $0xxx latch is clear, $B000 is used. When set, $C000 is used.
When the $1xxx latch is clear, $D000 is used. When set, $E000 is used.
The swap occurs after the tile is fetched, not before. So if the latch is clear, and tile $FE is loaded,
tile $FE from the first reg will be drawn to the screen, but the next tile drawn will be from the second reg.
Latches can be manipulated by hand by reading from the appropriate PPU address ($0FDx, $0FEx, $1FDx, $1FEx)
via $2007.
========================
= Mapper 010 =
========================
aka
--------------------------
MMC4
Example Game:
--------------------------
Fire Emblem
Notes:
--------------------------
This mapper is identical to MMC2 (mapper 009) with the exception of the PRG setup. See Mapper 009 for
details.
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $A000 | { -1} |
+---------------+---------------+
========================
= Mapper 011 =
========================
Example Games:
--------------------------
Crystal Mines
Metal Fighter
Notes:
--------------------------
This mapper suffers from bus conflicts
Registers **BUS CONFLICTS**:
--------------------------
$8000-FFFF: [CCCC LLPP]
P = Select 32k PRG page @ $8000-FFFF
L = Lockout defeat usage
C = Select 8k CHR page @ $0000-1FFF
Lockout defeat:
--------------------------
I have no idea how this works. Kevtris page makes mention of it. From an emulation standpoint, it's not all
that important.
========================
= Mapper 013 =
========================
aka:
--------------------------
CPROM
Example Game:
--------------------------
Videomation
Notes:
--------------------------
This mapper uses 16k of CHR-RAM. CHR-RAM is swappable.
It also has bus conflicts
Registers (**BUS CONFLICTS**):
--------------------------
$8000-FFFF: [.... ..CC]
C = Select 4k CHR (RAM) page @ $1000-1FFF
CHR Setup:
--------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
| { 0 } | $8000 |
+-------------------------------+-------------------------------+
========================
= Mapper 015 =
========================
Example Game:
--------------------------
100-in-1 Contra Function 16
Notes:
---------------------------
Possible bus conflicts???
Registers:
---------------------------
$8000-FFFF: A~[.... .... .... ..OO]
[pMPP PPPP]
O = Mode
p = Low bit of PRG page (not always used)
P = High bits of PRG page
M = Mirroring (0=Vert, 1=Horz)
PRG Setup:
---------------------------
Depending on the Mode used, the 'p' bit may not be used. In the chart below, "P" will indicate that only the
'P' bits are used to form a 6-bit page number... whereas "Pp" will indicate the full 7-bit page number.
$8000 $A000 $C000 $E000
+---------------+---------------+
Mode 0: | P | P OR 1 |
+---------------+---------------+
Mode 1: | P | { -1} |
+---------------+---------------+
Mode 2: | Pp | Pp | Pp | Pp |
+---------------+---------------+
Mode 3: | P | P |
+---------------+---------------+
Powerup:
---------------------------
All regs reset to 0 on powerup.
========================
= Mapper 016 =
= + 159 =
========================
aka
--------------------------
Bandai (something or other)
Example Games:
--------------------------
Dragon Ball - Dai Maou Jukkatsu (016)
Dragon Ball Z Gaiden (016)
Dragon Ball Z 2 (016)
Rokudenashi Blues (016)
Akuma-kun - Makai no Wana (016)
Dragon Ball Z - Kyoushuu Saiya Jin (159)
SD Gundam Gaiden (159)
Magical Taruruuto Kun 1, 2 (159)
Two Mappers:
---------------------------
016 and 159 are mapped the exact same way. Registers are all the same and whatnot. And in fact, for a
while, both mappers were assigned the same mapper number (016). Therefore, you may come across mapper 159
games that are still marked as mapper 016.
The difference between the two is in the EPROM. These mappers don't have traditional SRAM (I couldn't tell
you why). Instead, they have EPROM that has to be written to one bit at a time, with very strange register
writes.
Mapper 016 has 256 bytes of EPROM, and is accessed high bit first
Mapper 159 has 128 bytes of EPROM, and is accessed low bit first
For further details, see the section at the bottom.
Apart from EPROM, the mappers are 100% identical in function.
Notes:
---------------------------
Since there's EPROM, there's no SRAM (EPROM is used to save games).
Registers:
---------------------------
Range,Mask: $6000-FFFF, $000F
Note: below regs are listed as $800x, but note they also exist at $6000-7FFF
$8000-8007: CHR Regs
$8008: PRG Reg (16k @ $8000)
$8009: [.... ..MM] Mirroring:
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
$800A: [.... ...E] IRQ Enable (0=disabled)
$800B: Low 8 bits of IRQ Counter
$800C: High 8 bits of IRQ Counter
$800D: EPROM I/O
another note: since PRG is mapped to $8000-FFFF, EPROM I/O reg can only be read via $6xxx or $7xxx. To my
knowledge no other registers are readable. It also appears that reading from *ANY* address in $6xxx-7xxx
will read the EPROM I/O reg. Rokudenashi Blues will poll $7F00 and will wait for bit 4 to be 0 before
continuing (so if you're giving open bus @ 7F00, the game will deadlock)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| $8000 | $8001 | $8002 | $8003 | $8004 | $8005 | $8006 | $8007 |
+-------+-------+-------+-------+-------+-------+-------+-------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8008 | { -1} |
+---------------+---------------+
IRQs:
---------------------------
IRQs are nice and simple.
When enabled, the 16-bit IRQ counter counts down every CPU cycle, wrapping from $0000->FFFF. When the
counter makes the transition from $0001->$0000, an IRQ is generated.
When disabled, the IRQ counter does not count.
Any write to $800A will acknowledge the IRQ
$800B and $800C change the IRQ counter directly -- not a reload value.
EPROM:
---------------------------
EPROM is a real nightmare. Nobody knows for sure exactly how it works -- but by examining the game code,
patterns surface. Games do a series of extremely cryptic writes to $800D, and occasionally read a single
bit from $800D. By examining some logs I made of the games I've noticed a small bit of patterns which I
list below, along with my guess as to what the game is attempting to do by performing that pattern:
write $00
write $40
write $60 Start I/O
write $20
write $00
write $00
write $20 Output '0' bit
write $00
write $00
write $40
write $60 Output '1' bit
write $40
write $00
write $00
write $20
write $A0 I have absolutly no clue
Read
write $00
write $60
write $E0 Read a single bit
Read
write $40
write $00
write $20
write $60 Stop I/O
write $40
write $C0
These likely aren't the only patterns that games perform. I recall seeing occasional writes of $80 and
other stuff thrown in there in some games. Also -- not all games follow this pattern, so looking for these
specific writes will not work for at least one other game.
It seems that only bits 5-7 of the written value are relevent (hereon, they will be referred to as D5 - D7).
Bit 4 ($10) is the only significant bit when read. Other bits are most likely open bus.
When writing bytes to EPROM, games will generally perform 8 "output" patterns (either output 0 or output 1,
depending on the bits it wants to write), followed by a 9th output pattern, which I would assume finalizes
the write and/or possibly moves the 8 bits from a latch to EPROM.
When reading bytes, games will generally perform 8 "read" patterns, followed by a single output pattern
(which I would assume finalizes the read).
Sometimes when the game is writing bits, it's writing data to be stored on EPROM, and other times it's
setting the desired EPROM address and/or read/write mode. Knowing which it's doing involves keeping track
of the state it's currently it and what it has done last, etc, etc.
But again -- nobody *really* knows how it works. The method I've employed in my emu is outlined below -- and
it appears to work for every game I've tried, but I *KNOW* it's not accurate. But, short of some hardware
guru acquiring a handful of these carts and doing a thorough RE job, that's about the best anyone can do.
Emulating EPROM:
-----------------------
SUPER FAT IMPORTANT NOTE: This is just the method of EPROM emulation I employ in my emu.
***THIS IS NOT HOW THE ACTUAL HARDWARE WORKS***
Do not use this as a final word or anything -- this is simply the product of lots of guesswork, speculation,
and trial and error.
D5 appears to be the "trigger" bit, and D6 appears to be the "signal" bit. I have no clue what D7 does, and
ignoring it completely has worked for me (though I'm sure it does have some purpose). "Commands" are sent
by toggling D5 (0->1->0). Two states of D6 are observed -- one when D5 rises (0->1), and one when it falls
(1->0). Using these two observed states, you get 4 possible commands. The command is sent when D5 falls.
Example:
byte D6 D5
write: $00 0 0
write: $40 1 0
write: $60 1 1 write: $40 1 0 write: $00 0 0
The above sequence would issue a "1,1" command.
Commands:
Name rise,fall example write sequence
------------------------------------------------
Write 0 0,0 $00, $20, $00
Write 1 1,1 $00, $40, $60, $40, $00
Open 1,0 $00, $40, $60, $20, $00
Close 0,1 $00, $20, $60, $40, $C0
The unit can be in one of several modes:
- Closed
- Select
- Address
- Write
- Read
I also use an 8-bit temporary value, an 8-bit address (or 7-bit address, if 128 byte EPROM) and 9-step bit
counter.
I would assume the unit is Closed on startup (and possibly reset).
Basic Concept overview:
"Write 0" and "Write 1" commands advance the 9-step bit counter. The first 8 writes fill the appropriate
bit in the temporary value. The 9th write will take the temp value and move it to either the address (if in
Address mode), or to the desired area in EPROM (if in Write mode), and the mode will update accordingly.
Basically the first 8 writes fill the temp value and the 9th moves it to where it needs to go.
Reads operate similarly... but the temp buffer isn't affected by the writes, and the 9th step doesn't copy
the temp value anywhere. Note however that games will perform a write between each bit read (presumably to
advance it to the next bit) -- so you should do nothing but return the appropriate bit when the game reads
the EPROM I/O Reg (do not advance it to the next bit on read).
"Select" mode exists on 256 byte EPROM only (mapper 016). It is used to select between read/write mode.
Bit 0 of the 8-bit value written when in Select mode determines read/write mode. On 128 byte EPROM (mapper
159), the high bit of the address selects read/write mode. In both cases, 1=read mode, 0=write mode.
Remember that on 128 byte, values are written low bit first... but on 256 byte, they're written high bit
first. Bits are read the same order they're written.
Doing anything but opening when the unit is closed has no effect.
Logic Flow Details (256-byte ... mapper 016)
--------------------------------------------
Opening from Closed Mode:
a) Enter Select Mode
Opening from non-Closed Mode:
a) if in Select Mode, increment address by 1
b) enter Select Mode.
c) Reset bit counter (next write is the first write in the 9-write sequence)
Writing in Select Mode:
a) If low bit of written value = 1
-) Enter Read Mode
b) otherwise...
-) Enter Address Mode
Writing in Address Mode:
a) written value becomes address
b) Enter Write mode
Writing in Write Mode:
a) written value moves to current address of EPROM
b) mode is not changed
Writing in Read Mode:
a) Enter Select Mode
Logic Flow Details (128-byte ... mapper 159)
--------------------------------------------
Opening from Closed Mode:
a) Enter Address Mode
Opening from non-Closed Mode:
a) increment address by 1 (wrap $7F->00)
b) do not change mode
c) Reset bit counter (next write is the first write in the 9-write sequence)
Writing in Address Mode:
a) written value becomes address (low 7 bits only)
b) if high bit of written value is set...
-) Enter Read Mode
c) otherwise...
-) Enter Write Mode
Writing in Write Mode:
a) written value moves to current address of EPROM
b) Enter Address mode
Writing in Read Mode:
a) Enter Address Mode
========================
= Mapper 018 =
========================
Example Games:
--------------------------
The Lord of King
Magic John
Pizza Pop
Registers:
---------------------------
Range,Mask: $8000-FFFF, $F003
$800x,$900x: [.... PPPP] PRG Regs
$A00x-$D00x: [.... CCCC] CHR Regs
$E00x: [.... IIII] IRQ Reload value
$F000: [.... ....] IRQ Reset
$F001: [.... SSSE] IRQ Control
S = Size of IRQ counter
E = Enable
$F002: [.... ..MM] Mirroring
%00 = Horz
%01 = Vert
%10 = 1ScA
%11 = 1ScB
CHR Setup:
---------------------------
Only low 4 bits of written value significant [.... CCCC]
2 regs combined to get an 8-bit page number
$x000 or $x002 are the low 4 bits
$x001 or $x003 are the high 4 bits
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
|$A000+1|$A002+3|$B000+1|$B002+3|$C000+1|$C002+3|$D000+1|$D002+3|
+-------+-------+-------+-------+-------+-------+-------+-------+
PRG Setup:
---------------------------
Same as CHR, $x000 low, $x001 high
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
|$8000+1|$8002+3|$9000+1| { -1} |
+-------+-------+-------+-------+
IRQ:
---------------------------
16-bit IRQ Reload value is set via regs $E00x. $E000 sets the low 4 bits, $E003 sets the high 4 bits.
When enabled, the IRQ counter counts down every CPU cycle. When it wraps, an IRQ is generated.
The 'S' bits in the control reg determine the size of the IRQ counter. It can be 4, 8, 12, or 16 bits wide:
%000 = 16 bits wide
%001 = 12 bits wide
%01x = 8 bits wide
%1xx = 4 bits wide
If the counter is less than 16 bits, the high bits are not altered by IRQ counter clocking; they retain their
value.
Example: if the IRQ counter contains $1232, and is in 4-bit mode, it counts like so:
$1232
$1231
$1230
$123F $123E
...
Any write to the reset reg ($F000) will copy the 16-bit reload value into the IRQ counter (full 16 bits are
copied, regardless of current 'S' value).
Any write to $F000 or $F001 will acknowledge the IRQ.
========================
= Mapper 019 =
= + 210 =
========================
aka
--------------------------
Namcot 106
N106
Example Games:
--------------------------
Digital Devil Story - Megami Tensei 2 (019)
Final Lap (019)
Rolling Thunder (J) (019)
Splatter House (019)
Mappy Kids (019)
Family Circuit '91 (210)
Wagyan Land 2,3 (210)
Dream Master (210)
General Notes:
--------------------------
For a while, this mapper number was shared with 210. Therefore, there are a lot of ROMs floating around that
are labelled as mapper 019 that are really mapper 210.
Some games require CHR-RAM in addition to any CHR-ROM present. I'm uncertain exactly how much, but giving
them 8k seems to work.
Mapper 019 also has an additional 128 bytes of Sound RAM, which is used for waveform tables and sound
registers. Kaijuu Monogatari uses this as battery backed SRAM.
The rest of the doc applies to both mapper numbers. Differences between the two (mirroring and sound) will
be noted where appropriate.
Registers:
--------------------------
Range,Mask: $4800-FFFF, $F800
Writable and Readable:
$4800: [DDDD DDDD] Sound Data port (see Sound section for details)
(mapper 019 only)
$5000: [IIII IIII] Low 8 bits of IRQ counter
$5800: [EIII IIII]
E = IRQ Enable (0=disabled, 1=enabled)
I = High 7 bits of IRQ counter
$6000-7FFF: mapped to PRG-RAM, not registers
Writable only:
$8000-B800: CHR Regs
$C000-D800: Mirroring Regs (mapper 019 only)
$E000: [..PP PPPP] PRG Reg 0 (8k @ $8000)
$E800: [HLPP PPPP]
H = High CHR RAM Disable (see CHR setup for details)
L = Low CHR RAM Disable
P = PRG Reg 1 (8k @ A000)
$F000: [..PP PPPP] PRG Reg 2 (8k @ $C000)
$F800: [IAAA AAAA] Sound Address (with auto-increment enable bit)
(See Sound section for details) (mapper 019 only)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $E000 | $E800 | $F000 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
--------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| $8000 | $8800 | $9000 | $9800 | $A000 | $A800 | $B000 | $B800 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Page numbers lower than $E0 will select CHR-ROM. Page numbers greater than or equal to $E0 will select
CHR-RAM (RAM page N - $E0) *unless* CHR-RAM for the region is disabled via the appropriate bit in $E800.
$E800.6, when set, disables RAM selection for $0xxx ($8000-9800 will always select ROM)
$E800.7, when set, disables RAM selection for $1xxx ($A000-B800 will always select ROM)
CHR-RAM disable allows games to utilize all 256k of CHR-ROM. When CHR-RAM is enabled, only 224k can be
accessed.
Mirroring:
--------------------------
This section applies to mapper 019 only. 210 has hardwired mirroring
[ $C000 ][ $C800 ]
[ $D000 ][ $D800 ]
Values less than $E0 select a CHR-ROM page for a NT. Values $E0 and up use NES's internal nametables
(low bit selects which).
Typical Examples:
$C000 $C800 $D000 $D800
-----------------------
Horz: $E0 $E0 $E1 $E1
Vert: $E0 $E1 $E0 $E1
IRQ Operation:
--------------------------
IRQs are driven by a 15-bit CPU cycle up-counter. $5000 and $5800 are *direct* access to the IRQ counter
(they are not a reload value). Games can also read back the real-time state of the IRQ counter by reading
those regs.
When IRQs are enabled, the following occurs every CPU cycle:
- If IRQ Counter = $7FFF
a) Trip IRQ
- otherwise...
a) Increment IRQ counter by 1
Reading/Writing $5000 or $5800 will acknowledge the pending IRQ.
Sources on the behavior of this IRQ counter vary. Some say that the IRQ counter wraps from $7FFF to $0000,
and trips an IRQ only when it wraps -- however Sangokushi 2 polls $5800, and emulating IRQs that way results
in the game locking up shortly after it starts (once it sees that $5800 is not what it expects, it resets the
IRQ counter and loops)
Emulating the IRQ counter as above seems to work for every game out there -- although it probably isn't 100%
accurate.
Sound:
--------------------------
Sound applies to mapper 019 only. Mapper 210 has no extra sound.
N106 has some pretty sweet expansion sound. And it's used in several games to boot (More than any other
expansion except for FDS)
The N106 has up to 8 additional sound channels, each which plays back a configurable waveform of variable
length, as well as having full volume control for each channel.
There are 128 bytes of Sound RAM inside the N106 which is used to hold the waveform data, as well as sound
registers. This RAM is accessed by setting the desired address by writing to $F800, then writing the
desired data to $4800. $4800 is also readable.
$F800: [IAAA AAAA]
I = Auto-increment flag
A = Sound RAM Address
If the auto-increment flag is set, the Sound RAM address will increment (wrapping $7F->00) after every $4800
read/write.
Sound Channel registers (inside Sound RAM):
regs: "A" "B" "C" "D" "E"
------------------------------
Ch 0 - $40 $42 $44 $46 $47
Ch 1 - $48 $4A $4C $4E $4F
Ch 2 - $50 $52 $54 $56 $57
Ch 3 - $58 $5A $5C $5E $5F
Ch 4 - $60 $62 $64 $66 $67
Ch 5 - $68 $6A $6C $6E $6F
Ch 6 - $70 $72 $74 $76 $77
Ch 7 - $78 $7A $7C $7E $7F
"A": [FFFF FFFF] Low 8 freq bits
"B": [FFFF FFFF] Mid 8 freq bits
"C": [...L LLFF]
F = High 2 freq bits
L = Instrument Length (4 * (8-L))
"D": [AAAA AAAA] Instrument address
"E": [.... VVVV] Volume
Special Reg $7F:
[.EEE VVVV]
E = Number of Enabled channels (E+1)
V = Channel 7's volume control
Instruments:
Instruments are in 4-bit samples. Each byte in sound RAM represents two samples (low 4 bits being the first
sample, high 4 bits being the second sample). Each channel has an address which it uses to look for the
instrument ('A' bits in reg "D"), as well as a length indicating how many samples are in the instrument ('L'
bits in reg "C").
The instrument address is in 4-bit samples. IE: When the instrument address is $20, the instrument starts
at the low 4 bits of byte address $10. A instrument address of $41 would be the high 4 bits of byte address
$20.
Instrument Length is 4 * (8-L) 4-bit samples. Therefore if L=3, the instrument is 20 4-bit samples long.
Samples are unsigned: '0' is low, 'F' is high.
For an example waveform... given the following instrument:
$A8 DC EE FF FF EF DE AC 58 23 11 00 00 10 21 53 (length of 32 ... L=0)
The following waveform (a pseudo-sine wave) would be produced:
F - *****
E - ** **
D - * *
C - * *
B -
A - * *
9 -
8 - * *
7 -
6 -
5 - * *
4 -
3 - * *
2 - * *
1 - ** **
0 - *****
__________________________________
The waveform would continually loop this pattern
Channel Disabling:
Reg $7F controls the number of enabled channels. As little as 1 or as many as all 8 channels can be enabled.
When not all channels are enabled, the high channels are the ones being used. That is, if only 3 channels
are enabled, channels 5, 6, and 7 are the ones enabled, and the others are disabled.
Disabling channels frees up more Sound RAM space for instruments (since the lower channels' registers are
unused when disabled). Also, since there are fewer channels to clock, the enabled channels are clocked more
quickly, resulting in higher quality sound and potentially higher tones (see frequency calculation)
Frequency Calculation:
The generated tone of each channel can be calculated with the following formula:
F * CPU_CLOCK
Hz = --------------------------
$F0000 * (E+1) * (8-L)*4
where:
F = the 18-bit Freq value
CPU_CLOCK = CPU clock rate (1789772.727272 on NTSC)
E = Enabled Channels (bits as written to reg $7F)
L = Instrument Length (bits as written)
Or... you can figure it as the number of CPU cycles that have to pass before the channel takes the next
step through its instrument:
$F0000 * (E+1)
Cycs = ------------------
F
When F is 0, the channel is essentially "frozen" at it's current position and does not update (and thus,
becomes silent).
========================
= Mapper 021 =
= + 023 =
= + 025 =
========================
aka
--------------------------
VRC4
Example Games:
--------------------------
Wai Wai World 2 (021)
Ganbare Goemon Gaiden 2 (021)
Boku Dracula-kun (023)
Tiny Toon Adventures (J) (023)
Gradius 2 (J) (025)
Bio Miracle Bokutte Upa (025)
Multiple numbers, just one mapper:
--------------------------
These three mapper numbers (021, 023, 025) collectively represent different wiring variations of the same mapper:
VRC4. Each variation operates exactly the same, only the registers used are different because they all use
different address lines. Some lines are even reversed from the norm.
variant lines registers Mapper Number
=================================================================
VRC4a: A1, A2 $x000, $x002, $x004, $x006 021
VRC4b: A1, A0 $x000, $x002, $x001, $x003 025
VRC4c: A6, A7 $x000, $x040, $x080, $x0C0 021
VRC4d: A3, A2 $x000, $x008, $x004, $x00C 025
VRC4e: A2, A3 $x000, $x004, $x008, $x00C 023
VRC4f: A0, A1 $x000, $x001, $x002, $x003 023 * see below *
This doc will use the 'VRC4a' registers (0,2,4,6) in all following register descriptions. For other
variants, use the above chart to convert.
I'm unsure whether or not 'VRC4f' really exists. It seems to use the same registers are mapper 023's VRC2
counterpart (see 022.txt) but also has IRQ functionality (appears to be used by Tiny Toon Adventures). Could
it be that 023 is really VRC4 and not a VRC4+VRC2 mix?
Registers:
--------------------------
Some registers are mirrored across several addresses. For example, writing to $9004 has the same effect as
writing to $9006.
$8000-$8006: [...P PPPP] PRG Reg 0
$9000,$9002: [.... ..MM] Mirroring:
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
$9004,$9006: [.... ..M.] PRG Swap Mode Select
$A000-$A006: [...P PPPP] PRG Reg 1
$B000-$E006: [.... CCCC] CHR Regs (see CHR Setup)
$F000+$F002: [.... IIII] IRQ Reload Value (see IRQ section)
$F004 [.... .MEA] IRQ Control (see IRQ section)
$F006 [.... ....] IRQ Acknowledge (see IRQ section)
PRG Setup:
--------------------------
There are two PRG modes, which can be seleted via $9004.
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
PRG Mode 0: | $8000 | $A000 | { -2} | { -1} |
+-------+-------+-------+-------+
PRG Mode 1: | { -2} | $A000 | $8000 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
--------------------------
The VRC4 only has 4 data pins for CHR Regs. To compensate, two CHR regs are combined to form a single page
number. One reg contains the high 4 bits and the other reg contains the low 4 bits (allowing for 8-bit page
numbers)
Example: $B000+$B002 select 1k CHR page @ $0000
if $B000=$03
and $B002=$01
then use page $13
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
|$B000+2|$B004+6|$C000+2|$C004+6|$D000+2|$D004+6|$E000+2|$E004+6|
+-------+-------+-------+-------+-------+-------+-------+-------+
--------------------------------------------------
--------------------------------------------------
VRC IRQs:
--------------------------
VRC IRQ logic is shared by VRC4, VRC6, and VRC7. IRQs for all of those mappers operate exactly the same way.
Therefore, this section applies to all of those mappers (other docs refer here).
One thing in paticular to note with VRC4 that is different from VRC6, VRC7 is that the reload register is
split in two just as CHR regs are. $F000 specifies the low 4 bits of the reload value, and $F002 specfies
the high 4 bits. This only happens in VRC4. VRC6 and VRC7 have a single 8-bit register to specify the
reload value. The rest of this doc will refer to this reload value as a single register.
Notes:
--------------------------
VRC IRQs are unique in that they simulate a scanline counter, without actually counting scanlines. The IRQ
counter is actually a CPU cycle counter, with a prescaler that divides clocks by ~113.666667 CPU cycles (one
NTSC scanline). This results in the IRQ counter being clocked once per scanline -- however unlike true
scanline counters, it will be clocked even when the PPU is inactive, and even during VBlank
Registers:
--------------------------
There are 3 registers relevant to VRC IRQs. See respective mapper doc for which register corresponds to
which address:
IRQ Reload: [IIII IIII]
This register specifies the counter reload value. It does not affect the counter itself.
IRQ Control: [.... .MEA]
M = IRQ Mode (0=scanline mode, 1=CPU cycle mode)
E = Enable (0=disabled, 1=enabled)
A = Enable-on-acknowledge (see below)
- If 'E' is written as set, the IRQ counter will be immediately reloaded with the reload value, and the
prescaler will be reset. IRQs will also be enabled.
- If 'E' is written as clear, the IRQ counter and prescaler are not changed, and IRQs are disabled
- Any write to this register will acknowledge the IRQ.
IRQ Acknowledge: [.... ....]
Any write to this register will acknowledge the IRQ. In addition, the 'A' control bit is copied to the
'E' control bit (enabling or disabling IRQs). No write to this register will change the state of the IRQ
counter or prescaler.
Operation:
--------------------------
When in scanline mode ('M' control bit clear), a prescaler divides the passing CPU cycles by 114, 114, then
113 (and then repeats that pattern). This averages 113 + 2/3 CPU cycles (1 NTSC scanline). When the
prescaler is reset, the sequence is reset, and it will be 114 CPU cycles until the next IRQ counter clock.
A simple way to emulate prescaler behavior is to have it reset to 341, and subtract 3 every CPU cycle. When
it drops to or below 0, increment it by 341 and clock the IRQ counter once. This will produce the
114,114,113 repeating pattern.
When in cycle mode ('M' control bit set), the prescaler is effectively bypassed, and the IRQ counter gets
clocked every CPU cycle. In this mode, the prescaler remains unchanged by passing CPU cycles.
If IRQs are disabled, neither the prescaler nor IRQ counter get clocked.
When the IRQ counter is clocked:
- If IRQ counter = $FF...
a) reload IRQ counter with reload value
b) trip IRQ
- otherwise...
a) increment IRQ counter by 1
========================
= Mapper 022 =
= + 023 =
========================
aka
--------------------------
VRC2
Example Games:
--------------------------
Ganbare Pennant Race (022)
TwinBee 3 (022)
Wai Wai World (023)
Multiple numbers, just one mapper:
--------------------------
These mapper numbers (022, 023) represent 2 wiring variations of the same mapper: VRC2. Each variation
operates the same, only the registers used are different because their lines are reversed from each other:
variant lines registers Mapper Number
=================================================================
VRC2a: A1, A0 $x000, $x002, $x001, $x003 022
VRC2b: A0, A1 $x000, $x001, $x002, $x003 023
This doc will use the 'VRC2b' registers (0,1,2,3) in all following register descriptions. For 'VRC2a',
simply reverse $x001 and $x002 registers.
VRC2a CHR:
---------------------------
Important note On VRC2a (mapper 022) only the high 7 bits of the CHR regs are used -- the low bit is
ignored. Therefore, you effectively have to right-shift the CHR page by 1 to get the actual page number.
For example... both $06 and $07 would both indicate page $03
This applies to VRC2a only. VRC2b (mapper 023) behaves normally.
VRC2 vs. VRC4:
--------------------------
VRC2 is strikingly similar to VRC4 (see mapper 021). The differences are:
1) VRC4 has IRQs, VRC2 does not
2) VRC4 has 5 bits for PRG regs, VRC2 only has 4 bits
3) VRC4 has 2 PRG modes, VRC2 does not.
Those differences aside -- they act exactly the same.
Registers:
--------------------------
Some registers are mirrored across several addresses. For example, writing to $8003 has the same effect as
writing to $8000.
$8000-$8003: [.... PPPP] PRG Reg 0 (select 8k @ $8000)
$9000-$9003: [.... ..MM] Mirroring:
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
$A000-$A003: [.... PPPP] PRG Reg 1 (select 8k @ $A000)
$B000-$E003: [.... CCCC] CHR Regs (see CHR Setup)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $8000 | $A000 | { -2} | { -1} |
+-------+-------+-------+-------+
CHR Setup:
--------------------------
The VRC2 only has 4 data pins for CHR Regs. To compensate, two CHR regs are combined to form a single page
number. One reg contains the high 4 bits and the other reg contains the low 4 bits (allowing for 8-bit page
numbers)
Example: $B000+$B001 select 1k CHR page @ $0000
if $B000=$03
and $B001=$01
then use page $13 (VRC2b)
or page $09 (VRC2a -- see notes above)
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
|$B000+1|$B002+3|$C000+1|$C002+3|$D000+1|$D002+3|$E000+1|$E002+3|
+-------+-------+-------+-------+-------+-------+-------+-------+
========================
= Mapper 023 =
========================
Mapper 023 includes both a variant of VRC4, and a variant of VRC2. Both of which are covered in other docs.
For details see the following:
mapper 021 (VRC4)
mapper 022 (VRC2)
========================
= Mapper 024 =
= + 026 =
========================
aka
--------------------------
VRC6
Example Games:
--------------------------
Akumajou Densetsu (024)
Madara (026)
Esper Dream 2 (026)
Multiple numbers, just one mapper:
--------------------------
As is the VRC way... VRC6 comes in two varieties. Both variants operate exactly the same, only the reigster
addresses are different:
variant lines registers Mapper Number
=================================================================
VRC6a: A0, A1 $x000, $x001, $x002, $x003 024
VRC6b: A1, A0 $x000, $x002, $x001, $x003 026
This doc will use the 'VRC6a' registers (0,1,2,3) in all following register descriptions. For 'VRC6b',
simply reverse $x001 and $x002.
Registers:
--------------------------
Some registers are mirrored across several addresses. For example, writing to $8003 has the same effect as
writing to $8000.
$8000-$8003: [PPPP PPPP] PRG Reg 0 (Select 16k @ $8000)
$9000-$9002: Sound, Pulse 1 (see sound section)
$A000-$A002: Sound, Pulse 2
$B000-$B002: Sound, Sawtooth
$B003: [.... MM..] Mirroring:
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
$C000-$C003: [PPPP PPPP] PRG Reg 1 (Select 8k @ $C000)
$D000-$E003: [CCCC CCCC] CHR regs (See CHR setup)
$F000-$F002: IRQ regs (See IRQ section)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+-------+-------+
| $8000 | $C000 | { -1} |
+---------------+-------+-------+
CHR Setup:
--------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| $D000 | $D001 | $D002 | $D003 | $E000 | $E001 | $E002 | $E003 |
+-------+-------+-------+-------+-------+-------+-------+-------+
IRQs:
--------------------------
VRC6 use the "VRC IRQ" setup shared by several VRCs. It uses the following registers:
$F000: [IIII IIII] IRQ Reload
$F001: [.... .MEA] IRQ Control
$F002: [.... ....] IRQ Acknowledge
For info on how these IRQs work, see the "VRC IRQs" section in mapper 021
==========================
Sound:
--------------------------
VRC6 has two additional pulse channels, and one sawtooth channel. Both operate very similarly to the NES's
native channels.
Pulse Channels:
------------------------
$9000, $A000: [MDDD VVVV]
M = Mode (0=normal mode, 1=digitized mode)
D = Duty cycle (duty cycle is (D+1)/16)
V = Volume
$9001, $A001: [FFFF FFFF]
F = Low 8 bits of Frequency
$9002, $A002: [E... FFFF]
F = High 4 bits of Frequency
E = Channel Enable (0=disabled, 1=enabled)
Pulse 1 uses regs $900x
Pulse 2 uses regs $A00x
Just like the NES's own pulse channels, an internal counter is counted down each CPU cycle, and when it
wraps, it's reloaded with the 'F' frequency value, and the duty cycle unit takes another step. VRC6's pulses
can have a duty cycle anywhere between 1/16 and 8/16 depending on the given 'D' value.
Channel output is either 0 or 'V', depending on the current state of the duty cycle unit (or digitized
mode).
When 'M' is set (digitized mode), the duty cycle is ignored, and 'V' is always output. In this mode, the
channel essentially is no longer a Pulse wave, but rather $9000/$A000 acts like a 4-bit PCM streaming
register (similar to $4011).
When 'E' is clear (channel disabled), output of the channel is forced to '0' (silencing the channel).
Generated tone in Hz can be calculated by the following:
CPU_CLOCK
Hz = -------------
(F+1) * 16
Sawtooth Channel:
------------------------
$B000: [..AA AAAA]
A = Accum Rate
$B001: [FFFF FFFF]
F = Low 8 bits of frequency
$B002: [E... FFFF]
F = High 4 bits of frequency
E = Channel Enable (0=disabled, 1=enabled)
The sawtooth uses an 8-bit accumulation register. Every time it is clocked, 'A' is added until the 7th
clock, at which point it is reset to 0. The high 5 bits of this accumulation reg are then used as the
channel output. Strangely, though, the accumulation register seems to only be clocked once for every *two*
times the frequency divider expires. This results in a tone that's an octave lower than you might expect.
It's difficult to put in words, so here's an example using $0B as a value for the accum rate ('A'):
Step Accum. Channel output
-------------------------------
0 $00 $00
1 $00 $00 odd steps do nothing
2 $0B $01 even steps.. add value of 'A' to accum
3 $0B $01
4 $16 $02
5 $16 $02
6 $21 $04
7 $21 $04
8 $2C $05
9 $2C $05
10 $37 $06
11 $37 $06
12 $42 $08 6th and final time 'A' is added
13 $42 $08
0 $00 $00 7th time, accum is reset instead
... and the process repeats
Channel output is the high 5 bits of the accumulation reg (right shift reg by 3). If the accum rate is too
high, the accum reg WILL wrap at 8 bits, causing ugly distortion. The highest accum rate you can use without
wrapping is $2A.
If 'E' is clear (channel disabled), channel output is forced to 0 (silencing the channel).
Generated tone in Hz can be calculated by the following:
CPU_CLOCK
Hz = -------------
(F+1) * 14
========================
= Mapper 025 =
========================
Mapper 025 is a variant of VRC4, which is covered in another doc.
For info, see mapper 021.
========================
= Mapper 026 =
========================
Mapper 026 is a variant of VRC6, which is covered in another doc.
For info, see mapper 024.
========================
= Mapper 032 =
========================
Example Games:
--------------------------
Image Fight
Major League
Kaiketsu Yanchamaru 2
Notes:
--------------------------
Major League seems to want hardwired 1-screen mirroring. As far as I know, there is no seperate mapper
number assigned to address this issue, so you'll have to rely on a CRC or hash check or something for
treating Major League as a special case.
Registers:
--------------------------
Range,Mask: $8000-BFFF, $F007
$8000-$8007: [PPPP PPPP] PRG Reg 0
$9000-$9007: [.... ..PM]
P = PRG Mode
M = Mirroring (0=Vert, 1=Horz) **Ignore for Major League**
$A000-$A007: [PPPP PPPP] PRG Reg 1
$B000-$B007: [CCCC CCCC] CHR Regs
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
PRG Mode 0: | $8000 | $A000 | { -2} | { -1} |
+-------+-------+-------+-------+
PRG Mode 1: | { 0 } | $A000 | $8000 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| $B000 | $B001 | $B002 | $B003 | $B004 | $B005 | $B006 | $B007 |
+-------+-------+-------+-------+-------+-------+-------+-------+
========================
= Mapper 033 =
========================
Example Games:
--------------------------
Akira
Bakushou Jinsei Gekijou
Don Doko Don
Insector X
Note:
--------------------------
Most dumps of mapper 048 games floating around are erroneously labelled as mapper 033. Mapper 033 does not
have IRQs, mapper 048 does, and mirroring on each is handled a bit differently. Apart from that, the two
are very similar.
Registers:
--------------------------
Range,Mask: $8000-BFFF, $A003
$8000 [.MPP PPPP]
M = Mirroring (0=Vert, 1=Horz)
P = PRG Reg 0 (8k @ $8000)
$8001 [..PP PPPP] PRG Reg 1 (8k @ $A000)
$8002 [CCCC CCCC] CHR Reg 0 (2k @ $0000)
$8003 [CCCC CCCC] CHR Reg 1 (2k @ $0800)
$A000 [CCCC CCCC] CHR Reg 2 (1k @ $1000)
$A001 [CCCC CCCC] CHR Reg 3 (1k @ $1400)
$A002 [CCCC CCCC] CHR Reg 4 (1k @ $1800)
$A003 [CCCC CCCC] CHR Reg 5 (1k @ $1C00)
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $8000 | $8001 | { -2} | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| $8002 | $8003 | $A000 | $A001 | $A002 | $A003 |
+---------------+---------------+-------+-------+-------+-------+
========================
= Mapper 034 =
========================
aka
--------------------------
BxROM
NINA-001
Example Games:
--------------------------
Darkseed (BxROM)
Mashou (BxROM)
Impossible Mission 2 (NINA-001)
Notes:
--------------------------
How these two seperate and completely imcompatible mappers got assigned the same mapper number is a mystery.
BxROM and NINA-001 are both assigned mapper 034, however they both work totally differently. There is no
reliable way to tell the difference between the two apart from a CRC or Hash check.
=================================
BxROM
=================================
BxROM has bus conflicts... however this mapper also covers some BxROM compatible boards that do
not suffer from bus conflicts.
Registers (**BUS CONFLICTS** sometimes):
--------------------------
$8000-FFFF: Select 32k PRG @ $8000
Note on a real BxROM, only the low 2 bits are used (PRG capped at 128k). But since this is BxROM and
compatible, emus should use all 8 bits
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
| $8000 |
+-------------------------------+
=================================
NINA-001
=================================
Registers:
--------------------------
$7FFD: Select 32k PRG @ $8000
$7FFE: Select 4k CHR @ $0000
$7FFF: Select 4k CHR @ $1000
I'm not sure whether or not WRAM can also exist at $6000-7FFF
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
| $7FFD |
+-------------------------------+
CHR Setup:
--------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
| $7FFE | $7FFF |
+-------------------------------+-------------------------------+
========================
= Mapper 044 =
========================
Example Game:
--------------------------
Super Big 7-in-1
Notes:
---------------------------
This mapper is an MMC3 based multicart. The multicart selects a block of PRG and CHR depending on the
selected game, and the MMC3 regs act as they normally would within the given block. For info on MMC3, see
mapper 004.
Registers:
---------------------------
Range,Mask: $8000-FFFF, $E001
All registers behave exactly like a normal MMC3, except for:
$A001: [EW.. .BBB]
E,W = Same as on typical MMC3
B = Block select
Blocks:
---------------------------
Selecting block 7 is the same as selecting block 6.
All blocks have 128k PRG and CHR... except for block 6 which has 256k PRG and CHR. All MMC3 selected pages
are chosen from the given block (including fixed pages). This can be accomplished by ANDing the MMC3 regs
with a given value, and ORing them with a value based on the current block:
Block PRG-AND PRG-OR CHR-AND CHR-OR
---------------------------------------------
0 $0F $00 $7F $000
1 $0F $10 $7F $080
2 $0F $20 $7F $100
3 $0F $30 $7F $180
4 $0F $40 $7F $200
5 $0F $50 $7F $280
6,7 $1F $60 $FF $300
Powerup:
---------------------------
Block 0 must be selected at powerup (and possibly reset?)
========================
= Mapper 045 =
========================
Example Games:
--------------------------
Super 8-in-1
Super 4-in-1
Super 1000000-in-1
Notes:
---------------------------
This mapper is another MMC3 multicart, only it works a bit strangely. The multicart selects PRG/CHR blocks
independently through 4 internal registers (accessed via $6000-7FFF). MMC3 registers then operate normally
within the current block.
For info on MMC3, see mapper 004.
Registers:
---------------------------
$6000-7FFF: Multicart regs
$8000-FFFF: Same as MMC3 for selected blocks
When Multicart regs are locked, writes to $6000-7FFF proceed to PRG-RAM, as normal.
Where the game writes in the $6000-7FFF range doesn't matter. An internal counter selects which reg gets
written to. ie:
LDA #$00
STA $6000 ; first write, goes to reg 0
STA $6000 ; second write, goes to reg 1
STA $6000 ; reg 2
STA $6000 ; reg 3
STA $6000 ; back to reg 0, etc
Reg 0: [CCCC CCCC] Low 8 bits of CHR-OR
Reg 1: [PPPP PPPP] PRG-OR
Reg 2: [CCCC SSSS]
S = CHR-AND block size
C = High 4 bits of CHR-OR
Reg 3: [.LAA AAAA]
L = Lock Multicart regs (1=locked)
A = Inverted PRG-AND
Once multicart regs are locked, the only way to unlock is to Reset the system.
CHR Setup:
--------------------------
'S' bits are somewhat strange. They seem to select the size of the CHR block to mask out:
'S' Block size CHR-AND
----------------------------
$F 256k $FF
$E 128k $7F
$D 64k $3F
...
$8 2k $01
7-0 1k $00
An easy way to emulate this:
chr_and = 0xFF >> ~S_bits;
CHR-OR is straightforward
PRG Setup:
-------------------------
PRG-OR is straightforward.
PRG-AND is inverted. XOR written value with $3F for actual PRG-AND.
Odd game behavior:
-------------------------
Games seem to set the multicart registers in a loop that runs 256 times. Why it does this isn't known,
neither is whether or not it is actually necessary.
Powerup and reset:
-------------------------
Block 0 must be selected on powerup and reset. Regs must be unlocked, as well... and they must be reset so
that the next write will write to reg 0.
========================
= Mapper 046 =
========================
Example Game:
--------------------------
Rumblestation 15-in-1
Bus Conflicts?:
---------------------------
No idea whether or not this mapper suffers from bus conflicts. Use caution
Registers:
---------------------------
Regs at $6000-7FFF means no PRG-RAM.
$6000-7FFF: [CCCC PPPP] High CHR, PRG bits
$8000-FFFF: [.CCC ...P] Low CHR, PRG bits
'C' selects 8k CHR @ $0000
'P' select 32k PRG @ $8000
Powerup:
---------------------------
$6000 set to 0 on powerup.
========================
= Mapper 047 =
========================
Example Game:
--------------------------
Super Spike V'Ball + Nintendo World Cup
Notes:
---------------------------
Yet another MMC3 multicart. See mapper 004 for info on MMC3.
There is no PRG-RAM. The multicart reg lies at $6000-7FFF, but is only writable when MMC3 PRG-RAM is enabled
and writable (see $A001)
Registers:
---------------------------
$6000-7FFF: [.... ...B] Block select
$8000-FFFF: Same as MMC3 for selected block
Each block has 128k PRG and 128k CHR.
========================
= Mapper 048 =
========================
Example Games:
--------------------------
Bubble Bobble 2 (J)
Don Doko Don 2
Captain Saver
Notes:
--------------------------
Most dumps of mapper 048 games floating around are erroneously labelled as mapper 033. Mapper 033 does not
have IRQs, mapper 048 does, and mirroring on each is handled a bit differently. Apart from that, the two are
very similar.
This mapper is very similar to MMC3 in a lot of ways, including how the IRQ counter operates.
Registers:
--------------------------
Range,Mask: $8000-FFFF, $E003
$8000: PRG Reg 0 (8k @ $8000)
$8001: PRG Reg 1 (8k @ $A000)
$8002: CHR Reg 0 (2k @ $0000)
$8003: CHR Reg 1 (2k @ $0800)
$A000: CHR Reg 2 (1k @ $1000)
$A001: CHR Reg 3 (1k @ $1400)
$A002: CHR Reg 4 (1k @ $1800)
$A003: CHR Reg 5 (1k @ $1C00)
$C000: IRQ Reload
$C001: IRQ Clear
$C002: IRQ Enable
$C003: IRQ Acknowledge
$E000: [.M.. ....] Mirroring
0 = Vert
1 = Horz
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $8000 | $8001 | { -2} | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| $8002 | $8003 | $A000 | $A001 | $A002 | $A003 |
+---------------+---------------+-------+-------+-------+-------+
IRQs:
---------------------------
IRQs on this mapper seem to behave exactly like MMC3's IRQs, with 2 exceptions:
1) The written reload value is inverted. EG: Writing $06 to the reload reg on this mapper would be like
writing $F9 on MMC3. You can simply XOR the writes with $FF and it will work just like MMC3.
2) The IRQ seems to trip a little later than it does on MMC3. It looks like about a 4 CPU cycle delay from
the normal MMC3 IRQ time. Failure to put in this delay results in shaking and other graphical quirks in some
games.
The registers on this mapper corespond directly to regs on the MMC3:
048 - MMC3
---------------
$C000 $C000 (XOR written value with $FF)
$C001 $C001
$C002 $E001
$C003 $E000
For details on MMC3 IRQ operation, see mapper 004.
========================
= Mapper 049 =
========================
Example Game:
--------------------------
Super HIK 4-in-1
Notes:
---------------------------
Yet another MMC3 multicart. For info on MMC3, see mapper 004.
There is no PRG-RAM. The multicart reg lies at $6000-7FFF, but is only writable when MMC3 PRG-RAM is enabled
and writable (see $A001)
Registers:
---------------------------
$6000-7FFF: [BBPP ...O] Multicart reg
B = Block
P = 32k PRG Reg
O = PRG Mode (0=32k mode)
$8000-FFFF: Same as MMC3 for selected block
Each block is 128k PRG and 128k CHR
PRG Setup:
---------------------------
When the 'O' mode bit is clear, ordinary MMC3 PRG regs are ignored, and instead, 32k PRG page 'P' is swapped
in at $8000. When 'O' is set, 'P' is ignored, and MMC3 PRG regs work normally for the current block.
Powerup:
---------------------------
$6000 set to 0 on powerup.
========================
= Mapper 050 =
========================
Example Game:
--------------------------
Super Mario Bros. (JU) (Alt Levels) (SMB2j pirate cart)
Notes:
---------------------------
No PRG-RAM. PRG setup is bizarre, as is the scrambled PRG reg.
Registers:
---------------------------
Range,Mask: $4020-5FFF, $4120
$4020: [.... HLLM]
L,M,H = Low, middle, and high bits of PRG Reg
$4120: [.... ...E] IRQ Enable (0=Disabled, 1=Enabled)
PRG Setup:
---------------------------
$6000 $8000 $A000 $C000 $E000
+-------+-------+-------+-------+-------+
| {$0F} | { 8 } | { 9 } | $4020 | {$0B} |
+-------+-------+-------+-------+-------+
IRQs:
---------------------------
Writing to $4120 with E=0 will disable IRQs, acknowledge the pending IRQ, and reset the IRQ counter to 0.
Writing with E=1 will just enable IRQs (but will not change anything else).
When enabled, The IRQ counter will count up every CPU cycle. When it makes the transition from
$0FFF->$1000, and IRQ is generated. The counter appears to be a full 16-bits (so it will not wrap until
$FFFF)
========================
= Mapper 052 =
========================
Example Game:
--------------------------
Mario 7-in-1
Notes:
---------------------------
Yet another MMC3 multicart. For info on MMC3, see mapper 004.
Registers:
---------------------------
$6000-7FFF: [.MHL SBPP] Multicart reg
P = PRG Block (bits 0,1)
B = CHR+PRG Block Select bit (PRG bit 2, CHR bit 1)
S = PRG Block size (0=512k 1=256k)
L = CHR Block low bit (bit 0)
H = CHR Block high bit (bit 2)
M = CHR Block size (0=256k 1=128k)
$8000-FFFF: Same as MMC3 for selected block
$6000 can only be written to once ... and only if PRG-RAM is enabled and writable (see $A001). Once $6000
has been written to, $6000-7FFF maps to PRG-RAM
PRG Setup:
---------------------------
'S' PRG-AND PRG-OR
------------------------
0 $1F %BP0 0000
1 $0F %BPP 0000
'B' and 'P' bits make a 3-bit value used as PRG-OR (left shift 4). When 'S' is clear, the low bit of that
value is forced to 0.
PRG swapping behaves just like a normal MMC3 within this selected block
CHR Setup:
---------------------------
'M' CHR-AND CHR-OR
------------------------
0 $FF %HB 0000 0000
1 $7F %HB L000 0000
'H', 'B' and 'L' bits make a 3-bit value used as CHR-OR (left shift 7). When 'M' is clear, the low bit of
that value is forced to 0.
CHR swapping behaves just like a normal MMC3 within this selected block
Powerup and Reset:
---------------------------
$6000 set to 0 on reset and powerup.
========================
= Mapper 057 =
========================
Example Games:
--------------------------
GK 47-in-1
6-in-1 (SuperGK)
Registers:
---------------------------
Range,Mask: $8000-FFFF, $8800
$8000: [.H.. .AAA]
H = High bit of CHR reg (bit 4)
A = Low 3 bits of CHR Reg (OR with 'B' bits)
$8800: [PPPO MBBB]
P = PRG Reg
O = PRG Mode
M = Mirroring (0=Vert, 1=Horz)
B = Low 3 bits of CHR Reg (OR with 'A' bits)
CHR Setup:
---------------------------
'A' and 'B' bits combine with an OR to get the low 3 bits of the desired page, and the 'H' bit is the high
bit. This 4-bit value selects an 8k page @ $0000
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
PRG Mode 0: | $8800 | $8800 |
+-------------------------------+
PRG Mode 1: | <$8800> |
+-------------------------------+
========================
= Mapper 058 =
========================
Example Games:
--------------------------
68-in-1 (Game Star)
Study and Game 32-in-1
Registers:
---------------------------
$8000-FFFF: A~[.... .... MOCC CPPP]
P = PRG page select
C = CHR page select (8k @ $0000)
O = PRG Mode
M = Mirroring (0=Vert, 1=Horz)
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | <$8000> |
+-------------------------------+
PRG Mode 1: | $8000 | $8000 |
+---------------+---------------+
========================
= Mapper 060 =
========================
Example Game:
--------------------------
Reset Based 4-in-1
Notes:
---------------------------
This mapper is very, very unique.
It's a multicart that consists of four NROM games, each with 16k PRG (put at $8000 and $C000) and 8k CHR.
The current block that is selected is determined by an internal register that can only be incremented by a
soft reset
I would assume the register is 2 bits wide? Don't know for sure.
========================
= Mapper 061 =
========================
Example Game:
--------------------------
20-in-1
Registers:
---------------------------
$8000-FFFF: A~[.... .... M.LO HHHH]
H = High 4 bits of PRG Reg
L = Low bit of PRG Reg
O = PRG Mode
M = Mirroring (0=Vert, 1=Horz)
PRG Setup:
---------------------------
PRG Reg is 5 bits -- combination of 'H' and 'L' bits.
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | <$8000> |
+-------------------------------+
PRG Mode 1: | $8000 | $8000 |
+---------------+---------------+
========================
= Mapper 062 =
========================
Example Game:
--------------------------
Super 700-in-1
Registers:
---------------------------
$8000-FFFF: A~[..pp pppp MPOC CCCC]
[.... ..cc]
p = Low bits of PRG Reg
P = High bit of PRG Reg
c = Low bits of CHR Reg
C = High bits of CHR Reg
O = PRG Mode
M = Mirroring (0=Vert, 1=Horz)
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | <$8000> |
+-------------------------------+
PRG Mode 1: | $8000 | $8000 |
+---------------+---------------+
CHR Setup:
----------------------------
'C' and 'c' select an 8k page @ $0000
========================
= Mapper 064 =
========================
aka
--------------------------
Tengen RAMBO-1
Example Games:
--------------------------
Klax
Skull and Crossbones
Shinobi
Notes:
--------------------------
This mapper is very similar to MMC3. It uses a similar swapping system, but adds a little functionality.
IRQs are set up similar as well... but have some major differences.
This is one of those mappers that is a big pain to impliment in an emu -- especially since so few games use
it. And the games that use it really blow hard.
Registers:
--------------------------
Range,Mask: $8000-FFFF, $E001
$8000: [CPK. AAAA]
C = CHR mode select
P = PRG mode select
K = full 1k CHR mode select (see CHR setup)
A = Address for use with $8001
$8001: [DDDD DDDD] Data port
R:0 -> CHR reg 0
R:1 -> CHR reg 1
R:2 -> CHR reg 2
R:3 -> CHR reg 3
R:4 -> CHR reg 4
R:5 -> CHR reg 5
R:6 -> PRG reg 0
R:7 -> PRG reg 1
R:8 -> CHR reg 6
R:9 -> CHR reg 7
R:A - R:E not used
R:F -> PRG reg 2
$A000: [.... ...M] Mirroring
0 = Vert
1 = Horz
$C000: [IIII IIII] IRQ Reload value
$C001: [.... ...M] IRQ Mode select and reset
0 = Scanline (A12) mode
1 = Cycle mode
$E000: [.... ....] IRQ Acknowledge/Disable
$E001: [.... ....] IRQ Enable
PRG Setup:
---------------------------
PRG mode is selected via $8000.6
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
PRG Mode 0: | R:6 | R:7 | R:F | { -1} |
+-------+-------+-------+-------+
PRG Mode 1: | R:F | R:6 | R:7 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
$8000 has 2 bits to configure CHR modes. Therefore there are effectively 4 CHR modes.
$8000: [CPK. AAAA] $0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
C=0, K=0 | | | R:2 | R:3 | R:4 | R:5 |
+---------------+---------------+-------+-------+-------+-------+
C=0, K=1 | R:0 | R:8 | R:1 | R:9 | R:2 | R:3 | R:4 | R:5 |
+-------+-------+-------+-------+---------------+---------------+
C=1, K=0 | R:2 | R:3 | R:4 | R:5 | | |
+-------+-------+-------+-------+---------------+---------------+
C=1, K=1 | R:2 | R:3 | R:4 | R:5 | R:0 | R:8 | R:1 | R:9 |
+-------+-------+-------+-------+-------+-------+-------+-------+
IRQs:
---------------------------
There are two seperate IRQ modes. One uses A12 to count scanlines in a manner just like MMC3 does (see
mapper 004 for details on how scanlines are counted and the restrictions involved). The other mode uses CPU
cycles with a 4-step prescaler (so the IRQ counter gets clocked every 4 CPU cycles).
Regardless of the mode used to clock the counter... every time the counter is clocked, the following actions
occur:
- If Reset reg ($C001) was written to after previous clock...
a) reload IRQ counter with IRQ Reload value **PLUS ONE**
- Otherwise... If IRQ Counter is 0...
a) reload IRQ counter with IRQ Reload value
- Otherwise...
a) Decrement IRQ counter by 1
b) If IRQ counter is now 0 and IRQs are enabled, trigger IRQ
Just like with MMC3, the counter is clocked and updated even when IRQs are disabled -- however IRQs will only
be triggered when enabled.
Note about the plus one: I'm not sure if 1 is really added or if there's simply an additional 1 clock delay
before the IRQ counter is updated. From a software standpoint, it doesn't really matter -- adding the
additional 1 works without any side-effects.
Registers involved with IRQs:
---------------------------
$C000: [IIII IIII] - IRQ Reload value
$C001: [.... ...M] - IRQ Reset reg, mode select
0 = Scanline mode (A12)
1 = CPU Cycle mode (with prescaler)
Any write to this register will make it so that the IRQ counter will reload with the reload value +1 on
its next clock. Whether or not writing to this register clears the IRQ counter like it does with MMC3 isn't
known... and doesn't matter, since it's reloaded later anyway.
Also, any write to this register will reset the CPU cycle prescaler (so that it will be 4 CPU cycles
until the next clock).
$E000: [.... ....] - IRQ Acknowledge/Disable
Any write to this register will acknowledge the pending IRQ, and disable IRQs
$E001: [.... ....] - IRQ Enable
Any write to this register will enable IRQs
A note about IRQs:
------------------
Scanline IRQs seem to trip a little later than they do on the MMC3. It looks like about a 5 dot delay
from the normal MMC3 IRQ time (265 instead of 260). Failure to put in this delay results in shaking and
other graphical quirks in some games... notably Klax. This delay also seems to exist for CPU cycle driven
IRQs (Skull & Crossbones will suffer without it). Perhaps the RAMBO-1's IRQ generating hardware is a little
slower than usual?
Apart from that timing difference, A12 clocks RAMBO-1's IRQ counter just exactly like it does MMC3, so all
the notes about A12, $2006/7, etc from the mapper 004 documenation apply to this mapper as well.
========================
= Mapper 065 =
========================
Example Games:
--------------------------
Daiku no Gen San 2
Kaiketsu Yanchamaru 3
Spartan X 2
Registers:
--------------------------
$8000: PRG Reg 0 (8k @ $8000)
$A000: PRG Reg 1 (8k @ $A000)
$C000: PRG Reg 2 (8k @ $C000)
$B000-$B007: CHR regs
$9001: [M... ....] Mirroring
0 = Vert
1 = Horz
$9003: [E... ....] IRQ Enable (0=disabled, 1=enabled)
$9004: [.... ....] Reload IRQ counter
$9005: [IIII IIII] High 8 bits of IRQ Reload value
$9006: [IIII IIII] Low 8 bits of IRQ Reload value
On Powerup:
---------------------------
On powerup, it appears as though PRG regs are inited to specific values:
$8000 = $00
$A000 = $01
$C000 = $FE
Games do rely on this and will crash otherwise.
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $8000 | $A000 | $C000 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| $B000 | $B001 | $B002 | $B003 | $B004 | $B005 | $B006 | $B007 |
+-------+-------+-------+-------+-------+-------+-------+-------+
IRQs:
---------------------------
This mapper's IRQ system is very simple. There's a 16-bit internal down counter which (when enabled),
decrements by 1 every CPU cycle. When the counter reaches 0, an IRQ is fired. The counter stops at 0 -- it
does not wrap and isn't automatically reloaded.
Any write to $9003 or $9004 will acknowledge the pending IRQ.
Any write to $9004 will copy the 16-bit reload value into the counter.
$9006 and $9005 set the reload value, but do not have any effect on the actual counter. Note that $9005 is
the HIGH bits, not the low bits.
========================
= Mapper 066 =
========================
aka
--------------------------
GxROM and compatible
Example Games:
--------------------------
Doraemon
Dragon Power
Gumshoe
Thunder & Lightning
Super Mario Bros. + Duck Hunt
Notes:
---------------------------
I do not know whether or not this mapper suffers from bus conflicts. Use caution
This mapper is INFAMOUS for having bad headers. Probably 80% or more of these ROMs floating around out
there have the wrong mirroring mode set in the header.
Some games are marked as mapper 066 that are really mapper 140. See mapper 140 for info.
Registers:
--------------------------
$8000-FFFF: [..PP ..CC]
P = Selects 32k PRG @ $8000
C = Selects 8k CHR @ $0000
========================
= Mapper 067 =
========================
Example Games:
--------------------------
Fantasy Zone 2 (J)
Mito Koumon - Sekai Manyuu Ki
Registers:
---------------------------
Range,Mask: $8000-FFFF, $F800
$8800: CHR Reg 0 (2k @ $0000)
$9800: CHR Reg 1 (2k @ $0800)
$A800: CHR Reg 2 (2k @ $1000)
$B800: CHR Reg 3 (2k @ $1800)
$C800: IRQ Load (write twice)
$D800: [...E ....] IRQ Enable (0=disabled, 1=enabled)
$E800: [.... ..MM] Mirroring
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
$F800: PRG Reg (16k @ $8000)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+---------------+---------------+
| $8800 | $9800 | $A800 | $B800 |
+---------------+---------------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $F800 | { -1} |
+---------------+---------------+
IRQ Operation:
---------------------------
$C800 is a write-twice register (similar to $2005 and $2006). The first write sets the *high* 8 bits of the
IRQ counter, and the second write sets the *low* 8 bits. This directly changes the actual IRQ counter -- not
a reload value.
Any write to $D800 will acknowledge the IRQ, and will also reset the toggle so that the next write to
$C800 will be the first write. $D800, of course, also enables/disables IRQs (bit 4).
The IRQ counter, when enabled, counts down every CPU cycle. When it wraps ($0000->FFFF), it disables
itself and triggers an IRQ.
========================
= Mapper 068 =
========================
Example Games:
--------------------------
After Burner 2
Maharaja
Registers:
---------------------------
Range,Mask: $8000-FFFF, $F000
$8000: CHR Reg 0 (2k @ $0000)
$9000: CHR Reg 1 (2k @ $0800)
$A000: CHR Reg 2 (2k @ $1000)
$B000: CHR Reg 3 (2k @ $1800)
$C000: [.NNN NNNN] NT-ROM Reg 0
$D000: [.NNN NNNN] NT-ROM Reg 1
$E000: [...R ...M] Mirroring (see section below)
$F000: PRG Reg (16k @ $8000)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+---------------+---------------+
| $8000 | $9000 | $A000 | $B000 |
+---------------+---------------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $F000 | { -1} |
+---------------+---------------+
Mirroring:
---------------------------
The mirroring reg has two significant bits:
$E000: [...R ...M]
'M' selects H/V:
0 = Vert
1 = Horz
'R' selects whether or not to use CHR-ROM as nametables.
0 = normal mirroring
1 = use CHR-ROM
When 'R' is set, $C000 and $D000 are used to select 1k CHR-ROM pages to use as nametables. They are arranged
in either Horz or Vert mirroring fashion depending on the 'M' bit ($C000 would be used in place of NTA,
$D000 in place of NTB).
R=1, M=0:
[ $C000 ][ $D000 ]
[ $C000 ][ $D000 ]
R=1, M=1:
[ $C000 ][ $C000 ]
[ $D000 ][ $D000 ]
Note that CHR-ROM for nametables is taken from the last 128k of CHR. This means you must effectively OR the
value written to $C000/$D000 with $80.
========================
= Mapper 069 =
========================
aka
--------------------------
FME-7
Sunsoft 5B
Example Games:
--------------------------
Gimmick
Batman: Return of the Joker
Hebereke
Gremlins 2 (J)
Notes:
--------------------------
This mapper is FME-7 and compatible. Sunsoft 5B operates the same as FME-7, only it has additional sound
hardware. For a long time, it was thought Gimmick uses FME-7, so the expansion sound is labeled as FME-7
in various places -- however -- technically FME-7 has no extra sound.
Gimmick is the only known game to use the extra sound found on Sunsoft 5B
Registers:
--------------------------
Range,Mask: $8000-FFFF, $E000
$8000: [.... AAAA] Address for use with $A000
$A000: [DDDD DDDD] Data port
R:0-7 -> CHR Regs
R:8-B -> PRG Regs
R:C -> Mirroring
R=D-F -> IRQ Control
$C000: [.... AAAA] Address for use with $E000 (sound)
$E000: [DDDD DDDD] Data port (sound -- see sound section)
PRG Setup:
---------------------------
R:8 controls $6000-7FFF. It can map in PRG-RAM, PRG-ROM, or leave it unmapped (open bus), depending on the
mode it sets:
R:8: [ERPP PPPP]
E = Enable RAM (0=disabled, 1=enabled)
R = RAM/ROM select (0=ROM, 1=RAM)
P = PRG page
if E=0 and R=1, RAM is selected, but it's disabled, resulting in open bus. In case it's still unclear:
R=0: ROM @ $6000-7FFF
R=1, E=0: Open Bus @ $6000-7FFF
R=1, E=1: RAM @ $6000-7FFF
R:9 - R:B appear to be a full 8 bits: [PPPP PPPP], and select only ROM.
$6000 $8000 $A000 $C000 $E000
+-------+-------+-------+-------+-------+
| R:8 | R:9 | R:A | R:B | { -1} |
+-------+-------+-------+-------+-------+
No games seem to use more than 8k PRG-RAM, so I'm unsure whether or not it's swappable when selected. I
don't see why it wouldn't be.
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| R:0 | R:1 | R:2 | R:3 | R:4 | R:5 | R:6 | R:7 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Mirroring:
---------------------------
R:C: [.... ..MM]
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
IRQs:
---------------------------
This mapper has a 16-bit IRQ counter which decrements every CPU cycle. When it wraps from $0000->FFFF, an
IRQ is tripped.
reg R:E sets the low 8 bits of the counter
reg R:F sets the high 8 bits
Note the regs change the actual counter -- not a reload value.
reg R:D is the IRQ control:
[C... ...T]
C = Enable countdown (0=disabled, 1=enabled)
T = Enable IRQ triggering (0=disabled, 1=enabled)
In order for IRQs to work as expected, both bits must be set. If either bit is cleared, an IRQ won't occur:
C=0, T=1: IRQs are enabled, but the counter will never decrement
C=1, T=0: Counter decrements, but IRQs are disabled
Acknowledging IRQs can only be done by disabling them (T=0).
Sound:
---------------------------
Sunsoft 5B appears to be identical to the AY 3-8910 (or a similar chip -- possibly a different AY 3-891x or a
YM2149). The only game to use the sound, Gimmick, does not use the envelope or noise functionality that
exists on the AY 3-891x, however, through testing it has been shown that such functionality does in fact
exist.
The sound info below is a simplified version of the behavior. Envelope and Noise are not covered (aside from
the noise shift formula), and registers relating to those areas are not mentioned. However the information
below is enough to satisfy Gimmick If you want further information and full register descriptions, consult
an AY 3-8910 datasheet or doc.
Sunsoft 5B has 3 Square channels (no configurable duty cycle -- always play at 50% duty). Each operate
similarly to the native NES sound channels. They output sound at 1 octave lower than what may be expected,
though (see below).
Sound Regs:
---------------------------
$C000: [.... AAAA] Address for use with $E000
$E000: [DDDD DDDD] Data port:
R:0 -> [FFFF FFFF] Chan 0, Low 8 bits of Freq
R:1 -> [.... FFFF] Chan 0, High 4 bits of Freq
R:2 -> [FFFF FFFF] Chan 1, Low 8 bits of Freq
R:3 -> [.... FFFF] Chan 1, High 4 bits of Freq
R:4 -> [FFFF FFFF] Chan 2, Low 8 bits of Freq
R:5 -> [.... FFFF] Chan 2, High 4 bits of Freq
R:7 -> [.... .CBA] Channel disable flags (0=enabled, 1=disabled)
C = Disable Chan 2
B = Disable Chan 1
A = Disable Chan 0
R:8 -> [.... VVVV] Chan 0, Volume
R:9 -> [.... VVVV] Chan 1, Volume
R:A -> [.... VVVV] Chan 2, Volume
Operation:
---------------------------
For tone generation, a counter is counted up each CPU cycle. When it reaches the given 'F' value, it resets
to zero, and another step through the duty cycle is taken. These squares' duty cycles are fixed at 50%
(AY 3-8910 docs say 8/16, but see below).
Emulating in this fashion, with a 16-step duty, these channels play 1 octave higher than they should
Therefore, either channels are only clocked every other CPU cycle... or (what I find to be easiest to
emulate) the duty is actually 16/32 instead of 8/16, or something else is going on. I do not know which is
actually happening.
The generated tone in Hz can be calculated with the following:
CPU_CLOCK
Hz = -------------
(F+1) * 32
When the duty cycle outputs high, 'V' is output, otherwise 0 is output. When the channel is disabled (see
R:7), 0 is forced as output for the channel.
Non-linear volume:
---------------------------
Output volume is non-linear... increasing in steps of 3 dB.
Output can be calculated with the following pseudo-code:
vol = 1.0;
for(i = 0; i < 0x10; ++i)
{
sunsoft_out[i] = vol * base;
vol *= step;
}
Where 'base' can be adjusted to match your native NES sound channel levels, and 'step' is "10^(dB/20)".
For 3 dB, 'step' would be ~1.4125
Noise Formula:
---------------------------
>> >>
+-->[nnnn nnnn nnnn nnnn]->output
| | |
| | ++
| | |
| v v
+-------------------XOR
- 16-bit right-shift reg
- bits 0,3 (before shift) XOR to create new input bit
- bit 0 is shifted to output
- initial feed is 1
========================
= Mapper 070 =
========================
Example Games:
--------------------------
Family Trainer - Manhattan Police
Family Trainer - Meiro Daisakusen
Kamen Rider Club
Space Shadow
Notes:
---------------------------
I do not know whether or not this mapper suffers from bus conflicts. Use caution
Many of these games use the family trainer mat as an input device.
Registers:
--------------------------
$8000-FFFF: [PPPP CCCC]
P = Selects 16k PRG @ $8000
C = Selects 8k CHR @ $0000
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 071 =
========================
Example Games:
--------------------------
MiG 29 - Soviet Fighter
Fire Hawk
The Fantastic Adventures of Dizzy
Bee 52
Notes:
--------------------------
This mapper covers several Camerica/Codemasters boards. One in paticular that needs to be noted is the board
used by Fire Hawk -- which has mapper controlled 1-screen mirroring. On other boards, mirroring is
hardwired This is yet another one of those terrific mapper number incompatibilities.
Some of these games are EXTREMELY DIFFICULT to emulate. Not because the mapper is complicated (it's actually
very simple), but because the games are picky about timing and use some seldom used aspects of the NES.
In paticular:
- Bee 52 uses the sprite overflow flag ($2002.5)
- MiG 29 uses DMC IRQs, and is VERY PICKY about their timing. If your DMC IRQ timing isn't spot on (or at
least really freaking close), this game will glitch like hell.
This mapper also involves a custom lockout defeat circuit which is mostly unimportant for emulation purposes.
Details will not be mentioned here, but are outlined in Kevtris' Camerica Mappers documentation.
Fire Hawk does some strange timing code when changing the mirroring mode. It is unknown whether or not any
special timing is required.
Registers:
--------------------------
$8000-9FFF: [...M ....] Mirroring (for Fire Hawk only)
0 = 1ScA
1 = 1ScB
$C000-FFFF: PRG Select (16k @ $8000)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $C000 | { -1} |
+---------------+---------------+
========================
= Mapper 072 =
========================
Example Games:
--------------------------
Pinball Quest (J)
Moero Pro Tennis
Moero Juudou Warriors
Registers (**BUS CONFLICTS**):
---------------------------
$8000-FFFF: [MM.. PPPP]
P = Page number
M = Command
Notes:
---------------------------
Page numbers seem to pass through a latch. Rather than writing to the regs directly, you write the
desired page number and command to the latch, then send another command that copies the latch to the
appropriate internal register.
Commands:
%00 = Copy latch to appropriate reg
%01 = Set CHR Page
%10 = Set PRG page
%11 = Nothing/invalid
Example:
If a game wanted to select CHR page 3, it would first write $43, then $03. Presumably, the $43 fills
the latch, then the $03 looks at the latch, sees that it wants to set the CHR page, then copies the page
number to the CHR reg (actually performing the swap).
No idea if that's really how it works or not, but emulating it that way seems to work.
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
| CHR Reg |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| PRG Reg | { -1} |
+---------------+---------------+
========================
= Mapper 073 =
========================
aka
--------------------------
VRC3
Example Games:
--------------------------
Salamander
Registers:
--------------------------
Range,Mask: $8000-FFFF, $F000
$8000: [.... IIII] Bits 0- 3 of IRQ reload value
$9000: [.... IIII] Bits 4- 7 of IRQ reload value
$A000: [.... IIII] Bits 8-11 of IRQ reload value
$B000: [.... IIII] Bits 12-15 of IRQ reload value
$C000: [.... .MEA] IRQ Control
M = IRQ Mode (0=16-bit mode, 1=8-bit mode)
E = IRQ Enable (0=disabled, 1=enabled)
A = Enable-on-Acknowledge (see IRQ section)
$D000: [.... ....] IRQ Acknowledge (see IRQ section)
$F000: [.... PPPP] PRG Select (16k @ $8000)
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $F000 | { -1} |
+---------------+---------------+
IRQs:
---------------------------
VRC3 IRQs operate differently from other VRCs. The counter is 16 bits instead of 8 bits, and there is no
scanline mode -- only CPU cycle mode. Other aspects, however, are very similar.
$8000-B000 set the 16-bit reload value (not the actual IRQ counter). When $C000 is written to with the 'E'
bit set, the reload value is copied into the actual IRQ counter.
When enabled, the IRQ counter will increment by 1 every CPU cycle until it wraps, at which point the IRQ
counter is reloaded with the reload value (relevent bits only see Modes below) and an IRQ is tripped.
Any write to $C000 or $D000 will acknowledge the IRQ.
Any write to $D000 will also copy the 'A' control bit to the 'E' control bit... enabling or disabling IRQs.
This does not change the contents of the IRQ counter.
Modes:
---------------------------
There are 8-bit and 16-bit modes for the IRQ counter, as controlled by the 'M' bit in $C000.
In 16-bit mode (M=0):
- Counter is a full 16-bits.
- IRQ is triggered when IRQ counter is incremented from $FFFF
In 8-bit mode (M=1):
- Only the low 8-bit bits of counter are used
- IRQ is triggered when low 8 bits of IRQ counter are incremented from $FF
- Incrementing the low bits *never* alters the high bits of the counter
- When low 8 bits wrap, only the low 8 bits are copied from the reload value... high bits remain unchanged
- Reloading via $C000 write will still reload all 16 bits.
========================
= Mapper 074 =
========================
aka:
--------------------------
Pirate MMC3 variant
Example Games:
--------------------------
Di 4 Ci - Ji Qi Ren Dai Zhan
Ji Jia Zhan Shi
Notes:
--------------------------
This mapper is a modified MMC3 (or is based on MMC3?).
In addition to any CHR-ROM present, there is also an additional 2k of CHR-RAM which is selectable. CHR pages
$08 and $09 select CHR-RAM, other pages select CHR-ROM
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.
========================
= Mapper 075 =
========================
aka:
--------------------------
VRC1
Example Games:
--------------------------
Tetsuwan Atom
Ganbare Goemon - Karakuri Douchuu
Registers:
--------------------------
Range,Mask: $8000-FFFF, $F000
$8000: [.... PPPP] PRG Reg 0 (8k @ $8000)
$A000: [.... PPPP] PRG Reg 1 (8k @ $A000)
$C000: [.... PPPP] PRG Reg 2 (8k @ $C000)
$9000: [.... .BAM] Mirroring, CHR reg high bits
M = Mirroring (0=Vert, 1=Horz)
A = High bit of CHR Reg 0
B = High bit of CHR Reg 1
$E000: [.... CCCC] Low 4 bits of CHR Reg 0 (4k @ $0000)
$F000: [.... CCCC] Low 4 bits of CHR Reg 1 (4k @ $1000)
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $8000 | $A000 | $C000 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
---------------------------
CHR regs are 5 bits wide. The low 4 bits of each reg are set by $E000 and $F000, and the high bit is taken
from the appropriate bits of $9000.
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
| $9000.1 + $E000 | $9000.2 + $F000 |
+-------------------------------+-------------------------------+
========================
= Mapper 076 =
========================
Example Games:
--------------------------
Digital Devil Story - Megami Tensei
Notes:
---------------------------
PRG Swapping on this mapper defies logic. I don't know if this is accurate, but it appears to work.
Registers:
---------------------------
Range,Mask: $8000-FFFF, $E001
$8000: [.P.. .AAA]
P = PRG register select (see PRG setup)
A = Address for use with $8001
$8001: [DDDD DDDD] Data port:
R:2 -> CHR reg 0 (2k @ $0000)
R:3 -> CHR reg 1 (2k @ $0800)
R:4 -> CHR reg 2 (2k @ $1000)
R:5 -> CHR reg 3 (2k @ $1800)
R:6 -> PRG reg 0 or 2 (depending on 'P' bit in $8000)
R:7 -> PRG reg 1
$A000: [.... ...M]
Mirroring: 0=Vert
1=Horz
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+---------------+---------------+
| R:2 | R:3 | R:4 | R:5 |
+---------------+---------------+---------------+---------------+
PRG Setup:
---------------------------
R:6 actually seems to access two seperate regs. Therefore, unlike the typical MMC3-style setup, $8000 and
$C000 are both independently selectable. When R:6 is written to, the 'P' bit determines which reg gets
changed:
P=0: PRG reg 0 (8k @ $8000 -- "R:6a" below)
P=1: PRG reg 2 (8k @ $C000 -- "R:6b" below)
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| R:6a | R:7 | R:6b | { -1} |
+-------+-------+-------+-------+
Powerup:
---------------------------
R:6b seems to be reset to $FE on powerup. The game does rely on this.
========================
= Mapper 077 =
========================
Example Game:
--------------------------
Napoleon Senki
Notes:
---------------------------
This mapper has 4-screen mirroring
Also, it has 8k CHR-RAM in addition to any CHR-ROM present.
I'm unsure whether or not this mapper suffers from bus conflicts. Use caution
Registers:
---------------------------
$8000-FFFF: [CCCC PPPP]
C = CHR Reg (2k @ $0000)
P = PRG Reg (32k @ $8000)
CHR Setup:
---------------------------
CHR-RAM is fixed at $0800-$1FFF. CHR-ROM is swappable at $0000:
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+---------------+---------------+
| $8000,ROM | {0},RAM | {1},RAM | {2},RAM |
+---------------+---------------+---------------+---------------+
========================
= Mapper 078 =
========================
Example Games:
--------------------------
Holy Diver
Uchuusen - Cosmo Carrier
Notes:
---------------------------
This mapper number covers two seperate mappers which are *almost* identical... however the mirroring control
on each is different (making them incompatible). You'll probably have to do a CRC or Hash check to figure
out which mirroring setup to use.
I think some emus might also look at the mirroring bit in the iNES header to determine which setup to use --
however the ROMs I have do not seem to have the mirroring bit set differently, so I don't know how well that
would work (not to mention it's probably not a good idea anyway).
I'm unsure whether or not this mapper suffers from bus conflicts. Use caution
Registers:
---------------------------
$8000-FFFF: [CCCC MPPP]
C = CHR Reg (8k @ $0000)
P = PRG Reg (16k @ $8000)
M = Mirroring:
--For Uchuusen - Cosmo Carrier--
0 = 1ScA
1 = 1ScB
--For Holy Diver--
0 = Horz
1 = Vert
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 079 =
========================
Example Games:
--------------------------
Blackjack
Dudes with Attitude
F-15 City War
Krazy Kreatures
Registers:
---------------------------
Range,Mask: $4100-5FFF, $4100
be sure to make note of the mask -- $4200 does not map to the register, but $4300 does.
$4100: [.CPP PCCC]
C = CHR Reg (8k @ $0000)
P = PRG Reg (32k @ $8000)
Note the high bit of the CHR Reg.
========================
= Mapper 080 =
========================
Example Games:
--------------------------
Kyonshiizu 2
Minelvaton Saga
Taito Grand Prix - Eikou heno License
Notes:
---------------------------
Regs appear at $7EFx, I'm unsure whether or not PRG-RAM can exist at $6000-7FFF
Fudou Myouou Den is often marked to use this mapper -- however it uses mapper 207.
Registers:
---------------------------
$7EF0-7EF5: CHR Regs
$7EF6: [.... ...M] Mirroring
0 = Horz
1 = Vert
$7EFA,7EFB: PRG Reg 0 (8k @ $8000)
$7EFC,7EFD: PRG Reg 1 (8k @ $A000)
$7EFE,7EFF: PRG Reg 2 (8k @ $C000)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| <$7EF0> | <$7EF1> | $7EF2 | $7EF3 | $7EF4 | $7EF5 |
+---------------+---------------+-------+-------+-------+-------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $7EFA | $7EFC | $7EFE | { -1} |
+-------+-------+-------+-------+
========================
= Mapper 082 =
========================
Example Games:
--------------------------
SD Keiji - Blader
Kyuukyoku Harikiri Stadium
Notes:
---------------------------
Regs appear at $7EFx, I'm unsure whether or not PRG-RAM can exist at $6000-7FFF
Registers:
---------------------------
$7EF0-7EF5: CHR Regs
$7EF6: [.... ..CM] CHR Mode/Mirroring
C = CHR Mode select
M = Mirroring:
0 = Horz
1 = Vert
$7EFA: [PPPP PP..] PRG Reg 0 (8k @ $8000)
$7EFB: [PPPP PP..] PRG Reg 1 (8k @ $A000)
$7EFC: [PPPP PP..] PRG Reg 2 (8k @ $C000)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
CHR Mode 0: | <$7EF0> | <$7EF1> | $7EF2 | $7EF3 | $7EF4 | $7EF5 |
+---------------+---------------+---------------+---------------+
CHR Mode 1: | $7EF2 | $7EF3 | $7EF4 | $7EF5 | <$7EF0> | <$7EF1> |
+-------+-------+-------+-------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $7EFA | $7EFB | $7EFC | { -1} |
+-------+-------+-------+-------+
Note: remember that the low 2 bits are not used (right-shift written values by 2)
========================
= Mapper 085 =
========================
aka
--------------------------
VRC7
Example Games:
--------------------------
Lagrange Point
Tiny Toon Adventures 2 (J)
VRC7a vs. VRC7b
--------------------------
Lagrange Point ('VRC7a') and Tiny Toon Adventures 2 ('VRC7b') both operate exactly the same, but are wired a
bit differently. VRC7a uses $x010 for regs, and VRC7b uses $x008. Registers below are listed as they exist
on VRC7a. For VRC7b, make the appropriate adjustments
Also, only Lagrange Point seems to use the extra sound. It's unknown whether or not the sound hardware
exists on VRC7b, as Tiny Toon doesn't use it.
CHR-RAM note:
--------------------------
Lagrange Point, for some reason I still don't understand, swaps its 8k CHR-RAM around. How this offers any
functionality is beyond me, but the game does it, so your emu must support it.
Registers:
--------------------------
$8000: PRG Reg 0 (8k @ $8000)
$8010: PRG Reg 1 (8k @ $A000)
$9000: PRG Reg 2 (8k @ $C000)
$9010: Sound Address Reg (see below)
$9030: Sound Data Port (see below)
$A000-$D010: CHR Regs
$E000: [.... ..MM] Mirroring:
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
$E010: [IIII IIII] IRQ Reload value
$F000: [.... .MEA] IRQ Control
$F010: [.... ....] IRQ Acknowledge
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $8000 | $8010 | $9000 | { -1} |
+-------+-------+-------+-------+
CHR Setup:
--------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------+-------+-------+-------+-------+-------+-------+-------+
| $A000 | $A010 | $B000 | $B010 | $C000 | $C010 | $D000 | $D010 |
+-------+-------+-------+-------+-------+-------+-------+-------+
IRQs:
--------------------------
VRC7 uses the "VRC IRQ" setup shared by several VRCs. It uses the following registers:
$E010: [IIII IIII] IRQ Reload
$F000: [.... .MEA] IRQ Control
$F010: [.... ....] IRQ Acknowledge
For info on how these IRQs work, see the "VRC IRQs" section in mapper 021
Sound:
--------------------------
VRC7 has additional sound channels It is a slightly dumbed down version of the YM2413 (aka OPLL). There
are only 6 harmony channels and no rhythmic channels. Note that some older docs claim it's an OPL2 -- but it
is, in fact, OPLL.
Due to the complexity of FM-synth ... details will not be covered here. For details, refer to a YM2413 data
sheet or technical doc.
$9010 is the address port
$9030 is the data port
They behave just like the address/data ports on the YM2413. Though remember that there's no rhythm, and
only 6 channels.
Channels can choose from 16 instruments. One is customizable by the game, the other 15 are fixed with the
following values:
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // custom instrument
0x03,0x21,0x04,0x06,0x8D,0xF2,0x42,0x17, // begin fixed instruments
0x13,0x41,0x05,0x0E,0x99,0x96,0x63,0x12,
0x31,0x11,0x10,0x0A,0xF0,0x9C,0x32,0x02,
0x21,0x61,0x1D,0x07,0x9F,0x64,0x20,0x27,
0x22,0x21,0x1E,0x06,0xF0,0x76,0x08,0x28,
0x02,0x01,0x06,0x00,0xF0,0xF2,0x03,0x95,
0x21,0x61,0x1C,0x07,0x82,0x81,0x16,0x07,
0x23,0x21,0x1A,0x17,0xEF,0x82,0x25,0x15,
0x25,0x11,0x1F,0x00,0x86,0x41,0x20,0x11,
0x85,0x01,0x1F,0x0F,0xE4,0xA2,0x11,0x12,
0x07,0xC1,0x2B,0x45,0xB4,0xF1,0x24,0xF4,
0x61,0x23,0x11,0x06,0x96,0x96,0x13,0x16,
0x01,0x02,0xD3,0x05,0x82,0xA2,0x31,0x51,
0x61,0x22,0x0D,0x02,0xC3,0x7F,0x24,0x05,
0x21,0x62,0x0E,0x00,0xA1,0xA0,0x44,0x17
};
========================
= Mapper 086 =
========================
Example Games:
--------------------------
Moero Pro Yakyuu (Black)
Moero Pro Yakyuu (Red)
Notes:
---------------------------
Regs are at $6000-7FFF, so these games have no SRAM.
Registers:
--------------------------
$6000-6FFF: [.CPP ..CC]
P = Selects 32k PRG @ $8000
C = Selects 8k CHR @ $0000
$7000-7FFF: [..SS IIII] Sound control **not sure about this**
S = Sound Start/Stop:
%10 = start sound effect?
anything else = stop sound effect?
I = Sound effect ID
Sound:
--------------------------
This mapper has some sort of sample playback mechanism. Writing to $7xxx starts/stops the currently playing
sample. How this playback works (apart from the sketchy notes above) is a complete mystery to me.
The sound effects themselves are NOT PART of the .nes file. Therefore the only real way to support them
currently would be to load external .wav files or something and play them back when they're triggered.
========================
= Mapper 087 =
========================
Example Games:
--------------------------
Argus (J)
City Connection (J)
Ninja Jajamaru Kun
Notes:
---------------------------
Regs are at $6000-7FFF, so these games have no SRAM.
Registers:
--------------------------
$6000-7FFF: [.... ..AB]
B = High CHR Bit
A = Low CHR Bit
This reg selects 8k CHR @ $0000. Note the reversed bit orders. Most games using this mapper only have 16k
CHR, so the 'B' bit is usually unused.
========================
= Mapper 088 =
========================
Example Games:
--------------------------
Quinty (J)
Namcot Mahjong 3
Dragon Spirit - Aratanaru Densetsu
Registers:
---------------------------
Range,Mask: $8000-FFFF, $8001
$8000: [.... .AAA] Address for use with $8001
$8001: [DDDD DDDD]
Data port:
R:0 -> CHR reg 0
R:1 -> CHR reg 1
R:2 -> CHR reg 2
R:3 -> CHR reg 3
R:4 -> CHR reg 4
R:5 -> CHR reg 5
R:6 -> PRG reg 0
R:7 -> PRG reg 1
CHR Setup:
---------------------------
CHR is split into two halves. $0xxx can only have CHR from the first 64k, $1xxx can only have CHR from the
second 64k.
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| | | R:2 | R:3 | R:4 | R:5 |
+---------------+---------------+-------+-------+-------+-------+
| | |
| AND written values with $3F | OR written values with $40 |
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| R:6 | R:7 | { -2} | { -1} |
+-------+-------+-------+-------+
========================
= Mapper 089 =
========================
Example Games:
--------------------------
Mito Koumon
Notes:
---------------------------
I do not know whether or not this mapper suffers from bus conflicts. Use caution
Registers:
--------------------------
$8000-FFFF: [CPPP MCCC]
C = Select 8k CHR @ $0000
P = Select 16k PRG @ $8000
M = Mirroring:
0 = 1ScA
1 = 1ScB
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 090 =
= + 209 =
========================
aka
--------------------------
Tekken 2 Pirate Cart
a big fat pile of ass
Example Games:
--------------------------
Tekken 2 (090)
Mortal Kombat 2 (090)
Super Contra 3 (090)
Super Mario World (090)
Shin Samurai Spirits 2 (209)
Rants:
---------------------------
This mapper is such a big pain in the ass. Not only is it overly complicated in every possible way, but
every single game that uses it SUCKS. Plus the composers for these horrible pirate games must have been
tone-deaf, because the music is always out of key. I freaking hate this mapper with a passion (can you
tell?).
090 vs. 209
---------------------------
209 split from 090 somewhere along the line... but at some time, 090 was shared by both. Therefore you may
come across ROMs mislabelled as 090 that are actually 209.
The two mappers are exactly the same. The only difference is a jumper setting which controls the extended
nametable control. 090 has extended NT control permanently disabled, 209 has it enabled. Why this is in a
jumper setting I don't know... since the game can already freaking enable/disable the mode through software
Regardless... two mappers are needed because some games that don't use the NT control don't disable it
through software (they rely on the jumper setting disabling it).
This doc, as a whole, applies to both 090 and 209 -- with the exception of the Mirroring section, which draws
the distinctions between the two.
Notes:
---------------------------
This mapper has no PRG-RAM. As suprising as that is.
In addition to the above mentioned jumper setting that controls mirroring, there are 2 other dipswitch
settings which can be read back by the game via reg $5000. Changing the dipswitch can change the game being
played in some ROMs (really, it's more or less the same game, just with slight differences).
This document's organization:
---------------------------
Since there are so many registers for this mapper, registers will be listed and outlined as the features are
explained... and the overall registers section will be extremely brief -- serving primarily as a very quick
reference or checklist.
PRG Setup:
---------------------------
$8000-8003 are PRG regs. $8004-8007 are mirrors of them.
$8000-$8003: [.PPP PPPP]
$D000 is the PRG mode select (among other things):
$D000: [SRNC CPPP]
R,N = Relate to Mirroring (see mirroring section for details)
C = Relate to CHR Setup (see chr setup for details)
S = Put PRG @ $6000-7FFF
P = PRG Mode Select
If 'S' is clear, $6000-7FFF is always open bus. It is only when 'S' is set, that $6000 reflects the page
indicated in the setup chart below.
Notice that page numbers are "actual" pages.
Some modes are bit reversed (as marked below). This means that the PRG registers are to be interpretted
backwards:
[.ABC DEFG] normal order
[.GFE DCBA] bit reversed order
$6000 $8000 $A000 $C000 $E000
+-----------------+-------------------------------+
PRG Mode %000 | ($8003 * 4)+3 | { -1} |
+-----------------+-------------------------------+
PRG Mode %001 | ($8003 * 2)+1 | $8001 | { -1} |
+-----------------+---------------+---------------+
PRG Mode %010 | $8003 | $8000 | $8001 | $8002 | { -1} |
+-----------------+-------+-------+-------+-------+
PRG Mode %011 | $8003 | $8000 | $8001 | $8002 | { -1} | *BIT REVERSE*
+-----------------+-------------------------------+
PRG Mode %100 | ($8003 * 4)+3 | $8003 |
+-----------------+-------------------------------+
PRG Mode %101 | ($8003 * 2)+1 | $8001 | $8003 |
+-----------------+---------------+---------------+
PRG Mode %110 | $8003 | $8000 | $8001 | $8002 | $8003 |
+-----------------+-------+-------+-------+-------+
PRG Mode %111 | $8003 | $8000 | $8001 | $8002 | $8003 | *BIT REVERSE*
+-----------------+-------+-------+-------+-------+
In case you don't see the patterns:
- PRG modes %1xx are the same as %0xx, only $8003 is used for the last page instead of {-1}
- $6000 is always swapped to the last 8k in the block specified by $8003. In %1xx modes, this means $6000
will always mirror $E000.
CHR Setup:
---------------------------
$9000-9007 are CHR regs -- each specifies the low 8 bits of the CHR page
$A000-A007 -- specifies the high 8 bits of the CHR page (work with above regs)
The rest of this section refers to above regs as $900x only -- but note that it all includes $900x and $A00x.
CHR Mode is set by the following:
$D000: [SRNC CPPP]
R,N = Relate to Mirroring (see mirroring section for details)
S,P = Relate to PRG (see prg setup for details)
C = CHR Mode
$D003: [M.BH HHHH]
M = Mirror CHR (very strange, see below)
B = CHR Block mode (0=enabled, 1=disabled)
H = CHR Block (when in block mode)
In CHR Block mode ('B' clear), $A00x is ignored, and instead, the H bits selects a 256k block for all CHR.
$9000-9007 select a page within that block.
In normal mode ('B' set), $9000-9007 select a page from the entire CHR.
Mirror CHR mode ('M' set), only takes effect when in 1k or 2k mode ('C' = %10 or %11). In this mode,
$0800-$0FFF always mirrors $0000-07FF. ($1800 is unaffected, however). This is relatively easily
emulatable by using $9000+$9001 in place of $9002+$9003 in the chart below.
Note that page numbers are in "actual" pages.
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
CHR Mode %00: | $9000 |
+---------------------------------------------------------------+
CHR Mode %01: | $9000 | $9004 |
+-------------------------------+-------------------------------+
CHR Mode %10: | $9000 | $9002 | $9004 | $9006 |
+---------------+---------------+---------------+---------------+
CHR Mode %11: | $9000 | $9001 | $9002 | $9003 | $9004 | $9005 | $9006 | $9007 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Mirroring:
---------------------------
At first glance... mirroring appears simple:
$D001: [.... ..MM]
%00 = Vert
%01 = Horz
%10 = 1ScA
%11 = 1ScB
However there is a special setting to complicate this, of course.
Note None of the below special mirroring stuff applies. The below
mirroring info applies *only* to mapper 209.
$D000: [SRNC CPPP]
S,P = Relate to PRG (see prg setup for details)
C = Relates to CHR (see chr setup for details)
N = Enable advanced NT control (0=disabled, 1=enabled)
R = disable NT RAM (0=NT can be RAM or ROM, 1=NT ROM only)
When 'N' is clear, $D001 controls mirroring, and all other mirroring regs are ignored (including 'R' bit of
$D000). When 'N' is set, $D001 is ignored, and the below regs control mirroring.
$D002: [A... ....] NT RAM select bit
$B000-B003 NT Regs (low 8 bits)
$B004-B007 NT Regs (high 8 bits)
Just like with normal CHR Regs, NT CHR regs are 16-bits... $B000-B003 specify the low bits, and $B004-B007
specify the high bit. They are arranged in the following:
[ $B000 ][ $B001 ]
[ $B002 ][ $B003 ]
When 'R' is set, $D002 is ignored, and CHR-ROM is always used as NT (with page selected by appropriate reg).
When 'R' is clear... CHR-ROM is only used if bit 7 of the NT Reg does not match the 'A' bit of $D002. If the
bits match, then NES internal NT RAM is used instead (either NTA or NTB, depending on bit 0 of the NT reg)
IRQs
---------------------------
IRQs on this mapper are 100% completely insane. They decided to do everything possible in order to make IRQs
as obfuscated and ridiculous as possible.
IRQs are triggered by any one of 4 sources:
1) CPU Cycles
2) A12 Rises
3) PPU Reads (wtf, I know, but it's true)
4) CPU Writes (wtf, I know, but it's true)
I *think* the only method used by any games is the A12. CPU Cycles may also be used... and I really doubt
the other two are used anywhere.
A12 rises operate just like they do for MMC3 (mapper 004 -- see that doc for details). One key difference:
Unlike the MMC3, nearby rises are not ignored. This means that under "normal" conditions, this IRQ counter
is clocked 8 times per scanline (not just once).
Clocks are first run through a prescaler, which divides the clocks by either 256 or 8 (prescaling by 8 is
useful with A12 mode).
Also.. the counter can be configured to count up, or count down Among other oddities.
Related regs are as follows:
$C001: [DU.. FPSS]
D = Count-down mode (0=disabled, 1=enabled)
U = Count-up mode (0=disabled, 1=enabled)
F = Funky mode (0=disabled, 1=enabled) -- see below
P = Prescaler size (0=256, 1=8)
S = IRQ source:
%00 = CPU Cycles
%01 = PPU A12 rising edges
%10 = PPU Reads
%11 = CPU Writes
$C002: [.... ....] Any write here will acknowledge and disable IRQs
$C003: [.... ....] Any write here will enable IRQs
$C000: [.... ...E] Alternate method:
writing to this reg with E=0: same as writing to $C002
writing to this reg with E=1: same as writing to $C003
$C004: [PPPP PPPP] Prescaler. Any write here will set the prescaler to 'P' XOR $C006
$C005: [IIII IIII] IRQ Counter. Any write here will set the IRQ counter to 'I' XOR $C006
$C006: [XXXX XXXX] This value is used as a XOR when writing to $C004/5
$C007: Funky Mode Reg
$C004 and $C005 directly change the IRQ counter/prescaler. They do not change a reload value.
When Count-up and count-down mode are both enabled, or both disabled, the IRQ counter will stand still. Only
one can be enabled for IRQs to work.
When the prescaler is in 3-bit mode (divide by 8), the high 5 bits of the prescaler remain unchanged when
clocked and only the low 3 bits are used. When the low 3 bits wrap, the IRQ counter is clocked. 8-bit mode
(divide by 256) works as you'd expect.
When the IRQ counter wraps (either $FF->00 or $00->FF, depending on whether it's incrementing or
decrementing), an IRQ is tripped (if enabled).
Disabling IRQs does not stop the counter or prescaler from counting, it simply stops the IRQ from being
generated.
Funky Mode:
When 'F' in $C001 is clear, $C007 is ignored. When set, exact operation is unknown. It appears to funkify
the prescaler. $C007 containing any value other than $FF will result in the IRQ counter not being clocked at
all... and $FF will result in the prescaler dividing by strange amounts (sometimes 8? sometimes 12?
sometimes 257?). Details are unknown. Fortunately, no games use this funky mode.
Other crap:
---------------------------
$5000: [DD.. ....] Dipswitch settings (readable only)
These bits can be read back as any value depending on dipswitch settings on the cart. The high bit, in
paticular, has an effect in some games.
$5800, $5801: 8*8->16 multiplication reg. (read+write)
These are similar to MMC5's multiplication reg. You write two values you want multiplied to $5801 and
$5800, then the 16-bit product can be read back ($5800 has low 8 bits, $5801 has high 8 bits).
Mulitplication is unsigned. Multiplication appears to need some processing time. After writing values, wait
8 CPU cycles before reading.
$5803: a single byte of RAM (read+write)
$5804-$5807 may also be RAM -- it's unknown.
Registers:
---------------------------
Registers were all covered in detail in previous sections. This section is just an overall
reference/checklist.
Range, Mask: $5000-FFFF, $F007
$5000: Dipswitch (read only)
$5800-5801: 8*8->16 multiplier (read+write)
$5803: RAM (read+write)
$5804-5807: ??? (possibly RAM)
$8000-8003: PRG Regs
$8004-8007: Mirror of PRG Regs
$9000-9007: CHR Regs (low bits)
$A000-A007: CHR Regs (high bits)
$B000-B003: NT Regs (low bits)
$B004-B007: NT Regs (high bits)
$C000-C007: IRQ Regs
$D000-D003: Control/Mode Regs
$D004-D007: mirror $D000-D003
========================
= Mapper 091 =
========================
Example Game:
--------------------------
Street Fighter 3
Notes:
---------------------------
Regs exist at $6000-7FFF, so this mapper has no SRAM.
Registers:
---------------------------
Range,Mask: $6000-7FFF, $7003
$6000-6003: CHR Regs
$7000-7001: [.... PPPP] PRG Regs
$7002 [.... ....] IRQ Stop
$7003 [.... ....] IRQ Start
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+---------------+---------------+
| $6000 | $6001 | $6002 | $6003 |
+---------------+---------------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $7000 | $7001 | { -2} | { -1} |
+-------+-------+-------+-------+
IRQs:
---------------------------
IRQs on this mapper seem to behave exactly like MMC3 -- except it's fixed so that it will only fire after 8
scanlines. This is easily emulatable by using MMC3 logic.
Write to $7002/$7003 can translate directly to write(s) to the following MMC3 registers:
on $7002 write:
a) write to $E000
on $7003 write:
a) write $07 to $C000
b) write to $C001
c) write to $E001
For details on MMC3 IRQ operation, see mapper 004
========================
= Mapper 092 =
========================
Example Games:
--------------------------
Moero Pro Soccer
Moero Pro Yakyuu '88 - Ketteiban
Notes:
---------------------------
This mapper is identical to mapper 072 except for the different PRG Setup. See mapper 072 for details.
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| { 0 } | PRG Reg |
+---------------+---------------+
========================
= Mapper 093 =
========================
Example Games:
--------------------------
Fantasy Zone (J)
Registers:
--------------------------
I don't know if this mapper suffers from bus conflicts or not. Use caution
$8000-FFFF: [PPPP ...M]
P = PRG Reg (16k @ $8000)
M = Mirroring:
0 = Vert
1 = Horz
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 094 =
========================
Example Games:
--------------------------
Senjou no Ookami
Registers:
--------------------------
I don't know if this mapper suffers from bus conflicts or not. Use caution
$8000-FFFF: [...P PP..] PRG Reg (16k @ $8000)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 095 =
========================
aka
--------------------------
MMC3 (modified)
Example Game:
--------------------------
Dragon Buster (J)
Notes:
---------------------------
This mapper is a modified MMC3. It behaves exactly like your normal MMC3, only mirroring is handled
differently. For details on MMC3, refer to mapper 004.
Regs:
---------------------------
$8000: [CP.. .AAA]
C = CHR Mode
P = PRG Mode
A = Address for $8001
This register operates exactly like it does on your normal MMC3. It is mentioned here because the 'C' bit
has another usage for mirroring.
The normal mirroring reg ($A000) is totally ignored, and the CHR regs select nametables:
When 'C' is set:
[ R:2 ][ R:3 ]
[ R:4 ][ R:5 ]
When 'C' is clear:
[ R:0 ][ R:0 ]
[ R:1 ][ R:1 ]
For mirroring, only bit 5 of the CHR regs is significant. Bit 5 of the appropriate reg selects either NTA or
NTB.
========================
= Mapper 096 =
========================
Example Games:
--------------------------
Oeka Kids - Anpanman no Hiragana Daisuki
Oeka Kids - Anpanman to Oekaki Shiyou
Notes:
---------------------------
These games use the Oeka kids tablet -- so you'll need to add support for that if you really want to test
these.
These games use 32k of CHR-RAM, which is swappable in a very unique fashion. Be sure to read the CHR Setup
section in detail.
Registers:
---------------------------
I'm unsure whether or not this mapper suffers from bus conflicts. Use caution
$8000-FFFF: [.... .CPP]
C = CHR Block select (see CHR Setup)
P = PRG Page select (32k @ $8000)
CHR Setup:
---------------------------
This mapper is tricky
Firstly, this mapper divides the 32k CHR-RAM into two 16k blocks (above 'C' bit selects which block is used).
The selected pages (including the fixed page) are taken from only the currently selected 16k block.
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
| **See below** | { 3 } |
+-------------------------------+-------------------------------+
But that's the easy part. This mapper does a very, very cool trick which watches the PPU address lines to
effectively "split" the nametable into 4 smaller sections -- thereby assigning a different CHR-RAM page to
each section. This allows **every single tile in the NT** to have a unique tile graphic
Long story short:
A nametable spans from $2000-$23BF ($23C0-$23FF are the attribute table).
The mapper breaks the NT up like so:
$2000-20FF = use CHR page 0
$2100-21FF = use CHR page 1
$2200-22FF = use CHR page 2
$2300-23BF = use CHR page 3
the other nametables at $2400, $2800, $2C00 are broken up in the same fashion.
Long story long:
PPU Address lines are modified as the PPU fetches tiles, and also when the game manually changes the PPU
address (via the second write to $2006 --- or by the increment after read/writing $2007). The mapper
monitors every change to the PPU Address lines, and when it lies within a certain range, it swaps the
appropriate CHR page in.
It will only swap CHR when the address falls between $2000-2FFF (or mirrored regions like $6000-6FFF,
$A000-AFFF, $E000-EFFF). $3xxx will not trigger a swap.
When in that range, it checks to make sure the address is not attribute tables ((Addr AND $03FF) < $03C0).
Note I'm not 100% sure if the mapper really does this or not. It's very possible that attribute fetches will
also swap CHR... this would not really disrupt anything other than making the game be more careful about its
PPU writes.
When all that checks out, bits 8 and 9 (Addr AND $0300) select the 4k CHR page to swap in to $0000.
Note that the mapper does not distinguish between PPU driven line changes and game driven line changes.
This means that games can manually swap the CHR page by doing specific writes to $2006:
LDA #$20
STA $2006
STA $2006 ; Addr set to $20xx -- CHR page 0 selected
LDA #$21
STA $2006
STA $2006 ; Addr set to $21xx -- CHR page 1 selected
And in fact, games would HAVE to do that to select CHR, since that's the only way to fill CHR RAM with the
desired data. So make sure your emu supports this.
========================
= Mapper 097 =
========================
Example Game:
--------------------------
Kaiketsu Yanchamaru
Registers:
--------------------------
I'm not sure whether or not this mapper suffers from bus conflicts. Use caution
$8000-FFFF: [MM.. PPPP]
P = PRG Reg (16k @ $C000)
M = Mirroring:
%00 = 1ScA
%01 = Horz
%10 = Vert
%11 = 1ScB
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| { -1} | $8000 |
+---------------+---------------+
========================
= Mapper 105 =
========================
aka
--------------------------
NES-EVENT
Example Game:
--------------------------
Nintendo World Championships 1990
Notes:
---------------------------
This mapper is an MMC1 with crazy wiring and a huge 30-bit CPU cycle driven IRQ counter. Registers are all
internal and not directly accessable -- and the latch must be written to 1 bit at a time -- just like on a
normal MMC1. For details on how regs are written to, see mapper 001.
This mapper has 8k CHR-RAM, and it is not swappable.
Registers:
---------------------------
Note that like a normal MMC1, registers are internal and not accessed directly.
$8000-9FFF: [.... PSMM] Same as MMC1 (but CHR mode bit isn't used)
$A000-BFFF: [...I OAA.]
I = IRQ control / initialization toggle
O = PRG Mode/Chip select
A = PRG Reg 'A'
$C000-DFFF: [.... ....] Unused
$E000-FFFF: [...W BBBB]
W = WRAM disable (same as MMC1)
B = PRG Reg 'B'
Powerup / Reset / Initialization:
---------------------------
On powerup and reset, the first 32k of PRG (from the first PRG chip) is selected at $8000 *no matter what*.
PRG cannot be swapped until the mapper has been "initialized" by setting the 'I' bit to 0, then to '1'. This
toggling will "unlock" PRG swapping on the mapper.
Note 'I' also controls the IRQ counter (see below)
PRG Setup:
---------------------------
There are 2 PRG chips, each 128k. The 'O' bit selects between the chips, and also determines which PRG Reg
is used to select the page.
O=0: Use first PRG chip (first 128k), use 'A' PRG Reg, 32k swap
O=1: Use second PRG chip (second 128k), use 'B' PRG Reg, MMC1 style swap
In addition, if the mapper has not been "unlocked", the first 32k of the first chip is always selected
regardless (as if $A000 contained $00).
Modes as listed below:
$8000 $A000 $C000 $E000
+-------------------------------+
Uninitialized: | { 0 } | +-------------------------------+
O=0: | $A000 | +-------------------------------+
O=1, P=0: | <$E000> | +-------------------------------+
O=1, P=1, S=0: | { 0 } | $E000 | +---------------+---------------+
O=1, P=1, S=1: | $E000 | {$07} | +---------------+---------------+
IRQ Counter:
---------------------------
The 'I' bit in $A000 controls the IRQ counter. When cleared, the IRQ counter counts up every cycle. When
set, the IRQ counter is reset to 0 and stays there (does not count), and the pending IRQ is acknowledged.
The cart has 4 dipswitches which control how high the counter must reach for an IRQ to be generated.
The IRQ counter is 30 bits wide.. when it reaches the following value, an IRQ is fired:
[1D CBAx xxxx xxxx xxxx xxxx xxxx xxxx]
^ ^^^
| |||
either 0 or 1, depending on the corresponding dipswitch.
So if all dipswitches are open (use '0' above), the counter must reach $20000000.
If all dipswitches are closed (use '1' above), the counter must reach $3E000000.
etc
In the official tournament, 'C' was closed, and the others were open, so the counter had to reach $2800000.
========================
= Mapper 107 =
========================
Example Game:
--------------------------
Magic Dragon
Registers:
---------------------------
I do not know whether or not this mapper suffers from bus conflicts. Use caution
$8000-FFFF: [PPPP PPP.]
[CCCC CCCC]
P = Selects 32k PRG @ $8000
C = Selects 8k CHR @ $0000
This is very strange. Bits 1-7 seem to be used by both CHR and PRG.
========================
= Mapper 112 =
========================
Example Games:
--------------------------
Huang Di
San Guo Zhi - Qun Xiong Zheng Ba
Registers:
---------------------------
Range,Mask: $8000-FFFF, $E001
$8000: [.... .AAA]
A = Address for use with $A000
$A000: [DDDD DDDD]
Data port:
R:0 -> PRG reg 0
R:1 -> PRG reg 1
R:2 -> CHR reg 0
R:3 -> CHR reg 1
R:4 -> CHR reg 2
R:5 -> CHR reg 3
R:6 -> CHR reg 4
R:7 -> CHR reg 5
$E000: [.... ...M]
Mirroring: 0=Vert
1=Horz
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| | | R:4 | R:5 | R:6 | R:7 |
+---------------+---------------+-------+-------+-------+-------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| R:0 | R:1 | { -2} | { -1} |
+-------+-------+-------+-------+
========================
= Mapper 113 =
========================
Example Games:
--------------------------
Rad Racket - Deluxe Tennis II
Papillion
Registers:
---------------------------
Range,Mask: $4100-5FFF, $4100
be sure to make note of the mask -- $4200 does not map to the register, but $4300 does.
$4100: [MCPP PCCC]
C = CHR Reg (8k @ $0000)
P = PRG Reg (32k @ $8000)
M = Mirroring:
0 = Horz
1 = Vert
Note the high bit of the CHR Reg.
========================
= Mapper 115 =
========================
Example Game:
--------------------------
Yuu Yuu Hakusho Final - Makai Saikyou Retsuden
Notes:
---------------------------
MMC3 variant. For info on MMC3, see mapper 004.
Regs at $6000-7FFF means no PRG-RAM
Registers:
---------------------------
Range,Mask: $6000-7FFF, $6001
$6000: [O... PPPP]
O = PRG Mode
P = 16k PRG Page
$6001: [.... ...C]
C = CHR Block select
$8000-FFFF: Same as MMC3
CHR Setup:
---------------------------
'C' selects a 256k CHR block for all the CHR selected by the MMC3. You can think of this as a CHR-OR of
$000 or $100 depending on 'C'.
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
O=0: | MMC3 |
+-------------------------------+
O=1: | $6000 | MMC3 |
+---------------+---------------+
Normal MMC3 PRG setup applies. If the O mode bit is set, then $8000-BFFF no longer reflects the typical MMC3
setup, and instead has a 16k page selected by $6000.
========================
= Mapper 118 =
========================
aka
--------------------------
MMC3 (modified)
Example Games:
--------------------------
Armadillo
Pro Sport Hockey
Notes:
---------------------------
This mapper is a modified MMC3. It behaves exactly like your normal MMC3, only mirroring is handled
differently. For details on MMC3, refer to mapper 004.
Regs:
---------------------------
$8000: [CP.. .AAA]
C = CHR Mode
P = PRG Mode
A = Address for $8001
This register operates exactly like it does on your normal MMC3. It is mentioned here because the 'C' bit
has another usage for mirroring.
The normal mirroring reg ($A000) is totally ignored, and the CHR regs select nametables:
When 'C' is set:
[ R:2 ][ R:3 ]
[ R:4 ][ R:5 ]
When 'C' is clear:
[ R:0 ][ R:0 ]
[ R:1 ][ R:1 ]
For mirroring, only bit 7 of the CHR regs is significant. Bit 7 of the appropriate reg selects either NTA or
NTB.
========================
= Mapper 119 =
========================
aka
--------------------------
TQROM
MMC3 (alternate)
Example Games:
--------------------------
High Speed
Pinbot
Notes:
---------------------------
In addition to any CHR-ROM present, this mapper has 8k CHR-RAM. CHR-RAM is selectable just like ROM. Bit 6
of each CHR Reg (R:0 - R:5) indicates whether ROM or RAM is selected (1=use RAM).
Other than that, this mapper is your plain, vanilla MMC3. See mapper 004 for details.
========================
= Mapper 140 =
========================
Example Game:
--------------------------
Bio Senshi Dan - Increaser Tono Tatakai
Notes:
---------------------------
Regs lie at $6000-7FFF, so there's no SRAM
Registers:
--------------------------
$6000-7FFF: [..PP CCCC]
P = Selects 32k PRG @ $8000
C = Selects 8k CHR @ $0000
========================
= Mapper 152 =
========================
Example Games:
--------------------------
Arkanoid 2 (J)
Gegege no Kitarou 2
Registers:
--------------------------
I don't know whether or not this mapper suffers from bus conflicts. Use caution
$8000-FFFF: [MPPP CCCC]
M = Mirroring:
0 = 1ScA
1 = 1ScB
P = PRG Reg (16k @ $8000)
C = CHR Reg (8k @ $0000)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | { -1} |
+---------------+---------------+
========================
= Mapper 154 =
========================
Example Game:
--------------------------
Devil Man
Registers:
---------------------------
Range,Mask: $8000-FFFF, $8001
$8000: [.M.. .AAA]
M = Mirroring
0 = 1ScA
1 = 1ScB
A = Address for use with $8001
$8001: [DDDD DDDD]
Data port:
R:0 -> CHR reg 0
R:1 -> CHR reg 1
R:2 -> CHR reg 2
R:3 -> CHR reg 3
R:4 -> CHR reg 4
R:5 -> CHR reg 5
R:6 -> PRG reg 0 (8k @ $8000)
R:7 -> PRG reg 1 (8k @ $A000)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| | | R:2 | R:3 | R:4 | R:5 |
+---------------+---------------+-------+-------+-------+-------+
R:0,R:1 select CHR from the first 64k block. R:2-R:5 select CHR from the second 64k block.
Therefore, you must effectively AND the written values to R:0,R:1 with $3F, and OR the written values to
R:2-R:5 with $40.
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| R:6 | R:7 | { -2} | { -1} |
+-------+-------+-------+-------+
========================
= Mapper 159 =
========================
This mapper is covered in full in mapper 016's doc. See that doc for details.
========================
= Mapper 164 =
========================
Example Game:
--------------------------
Final Fantasy V
Registers:
---------------------------
Range,Mask: $5000-FFFF, $F300
$5000, $D000: PRG reg (32k @ $8000)
$6000-7FFF may have SRAM (not sure)
On Reset
---------------------------
Reg seems to contain $FF on powerup/reset
Notes:
---------------------------
Swapping is really simple -- the thing that is funky is the register range/mask. $5000 and $D000 will access
the register, however $5100, $5200, etc will not.
========================
= Mapper 165 =
========================
Example Games:
--------------------------
Fire Emblem (Unl) (some weird ?Chinese? pirate version)
Notes:
---------------------------
This mapper is a strange MMC2+MMC3 hybrid. Register style, PRG, mirroring, ?and even IRQs? of MMC3, with the
CHR swapping and CHR latch functionality of MMC2.
There is 4k CHR-RAM in addition to any CHR-ROM present.
For details on MMC3, see mapper 004. For details on MMC2, see mapper 009. Both will be referenced heavily
in this doc.
Operation:
---------------------------
Register layout, PRG Setup, SRAM enabling, Mirroring, all function as they do on your vanilla MMC3.
The CHR Regs (R:0 - R:5) are used in MMC2 style:
CHR Setup:
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
| <> or <> | <> or <> |
+-------------------------------+-------------------------------+
The same latches that exist on MMC2 exist on this mapper as well, and determine the appropriate reg.
CHR page 0 is CHR-RAM, other pages are CHR-ROM.
Notes:
---------------------------
This game specifically will read ppu$xFD0 or ppu$xFE0 via $2007 to manually toggle the latch (specifically,
to swap in the CHR-RAM page). Failure to emulate this method of MMC2 latch toggling will result in garbled
graphics.
========================
= Mapper 180 =
========================
Example Game:
--------------------------
Crazy Climber (J)
Notes:
---------------------------
This game uses a special input device (the crazy climber controller), so you'll need to emulate that in order
to really test this mapper.
Registers:
--------------------------
Don't know whether or not this mapper suffers from bus conflicts. Use caution
$8000-FFFF: [.... .PPP]
PRG Reg (16k @ $C000)
PRG Setup:
--------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| { 0 } | $8000 |
+---------------+---------------+
Powerup:
--------------------------
Unsure whether or not the PRG reg is inited to anything specific on startup. I don't think it is.
========================
= Mapper 182 =
========================
Example Games:
--------------------------
Pocahontas
Super Donkey Kong
Registers:
---------------------------
This mapper is an MMC3 with its registers all scrambled to hell. Rather than a typical register outline,
this section will "translate" mapper 182 registers to their coresponding "normal" MMC3 counterpart. For MMC3
details, see mapper 004.
Range, Mask: $8000-FFFF, $E001
Mapper 182 MMC3
--------------------
$8000 -
$8001 $A000
$A000 $8000 (addresses further scrambled, see below)
$A001 -
$C000 $8001
$C001 $C000+$C001 *
$E000 $E000
$E001 $E001
A write to $C001 would be like a write to both $C000 and $C001 on a normal MMC3 (sets reload value, and
clears the IRQ counter).
The Address/Data port registers are further scrambled:
Mapper 182 MMC3
--------------------
R:0 R:0
R:1 R:3
R:2 R:1
R:3 R:5
R:4 R:6
R:5 R:7
R:6 R:2
R:7 R:4
Other than this scrambling mess, the mapper operates exactly like a normal MMC3.
========================
= Mapper 184 =
========================
Example Games:
--------------------------
Atlantis no Nazo
The Wing of Madoola
Registers:
--------------------------
$6000-7FFF: [.HHH .LLL]
H = Selects 4k CHR @ $1000
L = Selects 4k CHR @ $0000
Regs at $6000-7FFF means no SRAM
========================
= Mapper 185 =
========================
Example Games:
--------------------------
Spy Vs. Spy (J)
Mighty Bomb Jack (J)
Registers:
---------------------------
I'm unsure whether or not this mapper suffers from bus conflicts. I believe it does
$8000-FFFF: [CCCC CCCC]
CHR Reg
Notes:
---------------------------
This mapper is retarded. These games only have 8k of CHR, but they seem to attempt to disable CHR by writing
a specific value to the CHR Reg, then they VERIFY that garbage is read back, then they swap back to the
actual CHR. If they don't get the expected garbage, they lock up.
Perhaps this was some sort of copy protection?
Each game has their own value that enables/disables CHR. Rather than failing to attempt to list all the
exact values used here (I don't know what all of them are), I can provide some logic:
if C AND $0F is nonzero, and if C does not equal $13: CHR is enabled
otherwise CHR is disabled
When CHR is disabled, it is as if CHR is filled with all $12's
========================
= Mapper 189 =
========================
Example Game:
--------------------------
Thunder Warrior
Notes:
---------------------------
This mapper is a modified MMC3. Everything operates just as it does on the MMC3, only the normal PRG regs
(R:6,R:7) are ignored, and a new PRG Reg is used instead.
For details on MMC3, see mapper 004
Registers:
---------------------------
Regs at $6000-7FFF means no SRAM
$4120-7FFF: [AAAA BBBB]
A,B: PRG Reg
$8000-FFFF: Same as on MMC3
PRG Setup:
--------------------------
'A' and 'B' bits of the $4120 reg seem to be effectively OR'd.
That is... $30, $03, and $21 will all select page 3
$8000 $A000 $C000 $E000
+-------------------------------+
| $4120 |
+-------------------------------+
========================
= Mapper 191 =
========================
aka:
--------------------------
Pirate MMC3 variant
Example Game:
--------------------------
Sugoro Quest - Dice no Senshitachi (As)
Notes:
--------------------------
This mapper is a modified MMC3 (or is based on MMC3?).
In addition to any CHR-ROM present, there is also an additional 2k of CHR-RAM which is selectable. Bit 7 of
each CHR reg selects RAM or ROM (1=RAM, 0=ROM)
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.
========================
= Mapper 192 =
========================
aka:
--------------------------
Pirate MMC3 variant
Example Game:
--------------------------
Ying Lie Qun Xia Zhuan
Notes:
--------------------------
This mapper is a modified MMC3 (or is based on MMC3?).
In addition to any CHR-ROM present, there is also an additional 4k of CHR-RAM which is selectable.
CHR Pages $08-$0B are CHR-RAM, other pages are CHR-ROM.
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.
========================
= Mapper 193 =
========================
Example Game:
--------------------------
Fighting Hero (Unl)
Registers:
---------------------------
Regs at $6000-7FFF = no SRAM
Range,Mask: $6000-7FFF, $6003
$6000: CHR Reg 0
$6001: CHR Reg 1
$6002: CHR Reg 2
$6003: PRG Reg
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+---------------+---------------+
| <<$6000>> | <$6001> | <$6002> |
+-------------------------------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $6003 | { -3} | { -2} | { -1} |
+-------+-------+-------+-------+
========================
= Mapper 194 =
========================
aka:
--------------------------
Pirate MMC3 variant
Example Game:
--------------------------
Dai-2-Ji - Super Robot Taisen (As)
Notes:
--------------------------
This mapper is a modified MMC3 (or is based on MMC3?).
In addition to any CHR-ROM present, there is also an additional 2k of CHR-RAM which is selectable.
CHR Pages $00-$01 are CHR-RAM, other pages are CHR-ROM.
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.
========================
= Mapper 200 =
========================
Example Games:
--------------------------
1200-in-1
36-in-1
Registers:
---------------------------
$8000-FFFF: A~[.... .... .... MRRR]
M = Mirroring (0=Vert, 1=Horz)
R = PRG/CHR Reg
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
| $8000 |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | $8000 |
+---------------+---------------+
========================
= Mapper 201 =
========================
Example Games:
--------------------------
8-in-1
21-in-1 (2006-CA) (Unl)
Registers:
---------------------------
$8000-FFFF: A~[.... .... RRRR RRRR]
R = PRG/CHR Reg
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
| $8000 |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
| $8000 |
+-------------------------------+
========================
= Mapper 203 =
========================
Example Games:
--------------------------
35-in-1
Registers:
---------------------------
$8000-FFFF: [PPPP PPCC]
P = PRG Reg
C = CHR Reg
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
| $8000 |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 | $8000 |
+---------------+---------------+
========================
= Mapper 205 =
========================
Example Games:
--------------------------
15-in-1
3-in-1
Registers:
---------------------------
Regs at $6000-7FFF means no SRAM
$6000-7FFF: [.... ..MM] Game Mode / Block
$8000-FFFF: MMC3
Notes:
---------------------------
These multicarts select the game mode by writing to $6000-7FFF, the individual games then use traditional
MMC3 style regs at $8000-FFFF. The MMC3 regs only swap to pages *within* the block specifed by the game
mode. This can be easily emulated by ANDing the page numbers written to MMC3 with certain values, and then
ORing them with other values, based on the selected block.
Chart below to illustrate:
Block PRG-AND PRG-OR CHR-AND CHR-OR
-------------------------------------------------
0 $1F $00 $FF $000
1 $1F $10 $FF $080
2 $0F $20 $7F $100
3 $0F $30 $7F $180
For details on MMC3, see mapper 004
========================
= Mapper 207 =
========================
Example Game:
--------------------------
Fudou Myouou Den
Notes:
---------------------------
Regs appear at $7EFx, I'm unsure whether or not PRG-RAM can exist at $6000-7FFF
Registers:
---------------------------
$7EF0: [MCCC CCCC]
M = Mirroring 0
C = CHR Reg 0
$7EF1: [MCCC CCCC]
M = Mirroring 1
C = CHR Reg 1
$7EF2-7EF5: CHR Regs 2-5
$7EFA,7EFB: PRG Reg 0 (8k @ $8000)
$7EFC,7EFD: PRG Reg 1 (8k @ $A000)
$7EFE,7EFF: PRG Reg 2 (8k @ $C000)
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+-------+-------+-------+-------+
| <$7EF0> | <$7EF1> | $7EF2 | $7EF3 | $7EF4 | $7EF5 |
+---------------+---------------+-------+-------+-------+-------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $7EFA | $7EFC | $7EFE | { -1} |
+-------+-------+-------+-------+
Mirroring:
---------------------------
[ $7EF0 ][ $7EF0 ]
[ $7EF1 ][ $7EF1 ]
Mirroring bit of appropriate reg selects NTA or NTB
========================
= Mapper 209 =
========================
This mapper is covered in full in mapper 090's doc. See that doc for details.
========================
= Mapper 210 =
========================
This mapper is covered in full in mapper 019's doc. See that doc for details.
========================
= Mapper 225 =
========================
Example Games:
--------------------------
52 Games
58-in-1
64-in-1
Registers:
---------------------------
$5800-5803: [.... RRRR] RAM (readable/writable)
(16 bits of RAM -- 4 bits in each of the 4 regs)
$5804-5FFF: mirrors $5800-5803
$8000-FFFF: A~[.HMO PPPP PPCC CCCC]
H = High bit (acts as bit 7 for PRG and CHR regs)
M = Mirroring (0=Vert, 1=Horz)
O = PRG Mode
P = PRG Reg
C = CHR Reg
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
CHR Mode 0: | $8000 |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | <$8000> |
+-------------------------------+
PRG Mode 1: | $8000 | $8000 |
+---------------+---------------+
========================
= Mapper 226 =
========================
Example Games:
--------------------------
76-in-1
Super 42-in-1
Registers:
---------------------------
Range, Mask: $8000-FFFF, $8001
$8000: [PMOP PPPP]
P = Low 6 bits of PRG Reg
M = Mirroring (0=Horz, 1=Vert)
O = PRG Mode
$8001: [.... ...H]
H = high bit of PRG
PRG Setup:
---------------------------
Low 6 bits of the PRG Reg come from $8000, high bit comes from $8001
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | |
+-------------------------------+
PRG Mode 1: | Reg | Reg |
+---------------+---------------+
========================
= Mapper 227 =
========================
Example Game:
--------------------------
1200-in-1
Notes:
---------------------------
This mapper has 8k CHR-RAM, and also has the ability to write protect it's CHR-RAM
Registers:
---------------------------
$8000-FFFF: A~[.... ..LP OPPP PPMS]
L = Last PRG Page Mode
P = PRG Reg
O = Mode
M = Mirroring (0=Vert, 1=Horz)
S = PRG Size
Setup:
---------------------------
When 'O' is set, CHR-RAM is write protected (writes have no effect). 'O' also changes the PRG mode.
Note there is funky ANDs and ORs going on below depending on the modes:
$8000 $A000 $C000 $E000
+---------------+---------------+
O=1, S=0: | P | P |
+-------------------------------+
O=1, S=1: | < P > |
+-------------------------------+
O=0, S=0, L=0: | P | P AND $38 |
+---------------+---------------+
O=0, S=1, L=0: | P AND $3E | P AND $38 |
+---------------+---------------+
O=0, S=0, L=1: | P | P OR $07 |
+---------------+---------------+
O=0, S=1, L=1: | P AND $3E | P OR $07 |
+---------------+---------------+
========================
= Mapper 228 =
========================
Example Games:
--------------------------
Action 52
Cheetah Men II
Notes:
---------------------------
Cheetah Men II is infamous for how freaking terrible it is. Action 52 is none better. These games are SO
bad, it's hilarious.
Action 52's PRG size is weird (not a power of 2 value). This is because there are 3 seperate 512k PRG chips.
PRG Setup section will cover details.
Powerup and Reset:
---------------------------
Apparently the games expect $00 to be written to $8000 on powerup/reset.
Registers:
---------------------------
$4020-4023: [.... RRRR] RAM (readable/writable)
(16 bits of RAM -- 4 bits in each of the 4 regs)
$4024-5FFF: mirrors $4020-4023
$8000-FFFF: [.... ..CC] Low 2 bits of CHR
A~[..MH HPPP PPO. CCCC]
M = Mirroring (0=Vert, 1=Horz)
H = PRG Chip Select
P = PRG Page Select
O = PRG Mode
C = High 4 bits of CHR
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------------------------------------------------------+
| $8000 |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
'H' bits select the PRG chip. Each chip is 512k in size. Chip 2 does not exist, and when selected, will
result in open bus. The Action 52 .nes ROM file contains chips 0, 1, and 3:
chip 0: offset 0x000010
chip 1: offset 0x080010
chip 2: -- non existant --
chip 3: offset 0x100010
'P' selects the PRG page on the currently selected chip.
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | <$8000> |
+-------------------------------+
PRG Mode 1: | $8000 | $8000 |
+---------------+---------------+
========================
= Mapper 230 =
========================
Example Game:
--------------------------
22-in-1
Reset Driven:
---------------------------
The mapper has 2 main modes: Contra mode, and multicart mode. Performing a Soft Reset switches between
them.
Notes:
---------------------------
This multicart has an odd PRG size (not power of 2). This is because there are 2 PRG chips.
The first is 128k and contains Contra, the other is 512k and contains the multicart.
A soft reset changes which chip is used as well as other stuff relating to the mode
Registers:
---------------------------
Contra Mode $8000-FFFF: [.... .PPP]
Multicart Mode $8000-FFFF: [.MOP PPPP]
M = Mirroring (0=Horz, 1=Vert)
O = PRG Mode
P = PRG Page
Note:
Mirroring is always Vert in Contra Mode.
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+---------------+---------------+
Contra Mode: | $8000 | { 7 } | +-------------------------------+
Multi Mode 0: | | +-------------------------------+
Multi Mode 1: | Reg | Reg | +---------------+---------------+
chip 0 = 128k PRG (offset 0x00010-0x2000F)
chip 1 = 512k PRG (offset 0x20010-0xA000F)
========================
= Mapper 231 =
========================
Example Game:
--------------------------
20-in-1
Registers:
---------------------------
$8000-FFFF: A~[.... .... M.LP PPP.]
M = Mirroring (0=Vert, 1=Horz)
L = Low bit of PRG
P = High bits of PRG
PRG Setup:
---------------------------
Note that 'L' and 'P' bits make up the PRG reg, and the 'L' is the low bit.
$8000 $A000 $C000 $E000
+---------------+---------------+
| $8000 AND $1E | $8000 |
+---------------+---------------+
========================
= Mapper 232 =
========================
Example Games:
--------------------------
Quattro Adventure
Quattro Sports
Quattro Arcade
Notes:
--------------------------
This is another Camerica/Codemasters mapper like 071. Like 071, this mapper also involves a custom lockout
defeat circuit which is mostly unimportant for emulation purposes. Details will not be mentioned here, but
are outlined in Kevtris' Camerica Mappers documentation.
Registers:
---------------------------
$8000-BFFF: [...B B...] PRG Block Select
$C000-FFFF: [.... ..PP] PRG Page Select
PRG Setup:
---------------------------
Pages are taken from the 64k block currently selected by $8000.
$8000 $A000 $C000 $E000
+---------------+---------------+
| $C000 | { 3 } |
+---------------+---------------+
========================
= Mapper 233 =
========================
Example Game:
--------------------------
???? "42-in-1" ????
Notes:
---------------------------
Sources report this mapper as "42-in-1" with description layed out below. I did not test this,
since I could not find a copy of the ROM in question. The only ROM I have that's marked as
233 is "Unknown Multicart 1", and it does *not* follow the description in this doc at all.
There is a "Super 42-in-1"... but that is mapper 226. 226, by the way, is strikingly similar
to the below description. I wonder if below description really applies to 233?
Registers:
---------------------------
$8000-FFFF: [MMOP PPPP]
M = Mirroring
O = PRG Mode
P = PRG Page
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------------------------------+
PRG Mode 0: | <$8000> |
+-------------------------------+
PRG Mode 1: | $8000 | $8000 |
+---------------+---------------+
Mirroring:
---------------------------
'M' mirroring bits:
%00 = See below
%01 = Vert
%10 = Horz
%11 = 1ScB
Mode %00 (almost, but not quite 1ScA):
[ NTA ][ NTA ]
[ NTA ][ NTB ]
-----------------------------------------------
--------------------------
"Unknown Multi Cart 1"
--------------------------
-----------------------------------------------
Notes:
--------------------------
This ROM is a mystery.
It consists of 32 individual mapper 0 games, each 16k PRG + 8k CHR.
Games do not use compatible mirroring modes -- the ROM includes Ice Climber (which uses H mirroring) and
Excitebike (V mirroring).
No games seem to be modified to make any kind of writes to $8000-FFFF, so I didn't find any clue as to what
mapper registers are being written to (if any).
There does not appear to be *ANY* game selection screen for the multicart. I have paged through every 16k
of PRG and they all run the individual games straight up. So unless the mapper aligns to 8k (or smaller) pages
on startup and there's some crap hidden in there, I don't see how these games are held together.
Could it be that this ROM dump is bad or incomplete? The *only* other thing I can think of is that this cart might
be reset based (a la mapper 060) -- but that is complicated by the fact that games use conflicting mirroring modes.
So perhaps the mapper sets the mirroring mode based on what game is selected?
More weirdness: games seem to have mismatching PRG/CHR pages. Ice Climber's PRG is on page $1F, but its CHR is
on page $17. It seems that you need to subtract 8 from the PRG page to get the matching CHR page (and wrap where
appropriate)
Even more weirdness: despite each game only having 16k PRG, some of the games in the package normally have 32k
I don't know if the games were just hacked and had a bunch of stuff removed for what.
It's possible this ROM dump is bogus and/or bad. It might even be assigned the wrong mapper number.
At any rate... here are the games.
Game name PRG page CHR Page Mirroring
----------------------------------------------------------
Galaxian $00 $18 Horz
10 Yard Fight $01 $19 Horz
DKJ Math $02 $1A Vert
Antarctic Adventure $03 $1B Horz
Balloon Fight $04 $1C Horz
Baseball $05 $1D Horz
Battle City $06 $1E Horz
Binary Land $07 $1F Horz
Burger Time $08 $00 Horz
Chack 'n Pop $09 $01 Horz
Clu Clu Land $0A $02 Horz
Lode Runner $0B $03 Vert
?? Go / Othello ?? $0C $04 ????
Field Combat $0D $05 Horz ** really 32k PRG? **
Devil World $0E $06 Horz
Dig Dug $0F $07 Horz
Donkey Kong $10 $08 Horz
Donkey Kong Jr. $11 $09 Horz
Donkey Kong 3 $12 $0A Vert
Door Door $13 $0B Vert
Duck Hunt $14 $0C Vert
Excitebike $15 $0D Vert
Exerion $16 $0E Horz
F1-Race $17 $0F Vert
Formation Z $18 $10 Horz
Front Line $19 $11 Horz
Galaga $1A $12 Horz ** really 32k PRG? **
Golf $1B $13 Vert
Hogan's Alley $1C $14 Vert
Hyper Olympic $1D $15 Vert
?? some gun game ?? $1E $16 ????
Ice Climber $1F $17 Horz
========================
= Mapper 234 =
========================
Example Game:
--------------------------
Maxi 15 (PAL)
Notes:
--------------------------
Verrrry strange. Registers seem to lie at $FF80-$FFFF... the kicker is that *reading* those addresses also
trigger a register write (the value written is the value being read).
Example:
LDA $FF80 ; where $FF80 contains $62
would have the same effect on the mapper as:
LDA #$62
STA $FF80
Registers:
---------------------------
Range,Mask: $FF80-FFFF, $FFF8
$FF80, $FF88, $FF90, $FF98: [MO.. BBBb] Reg 0
M = Mirroring (0=Vert, 1=Horz)
O = Mode
B,b = Block selection
$FFC0, $FFC8, $FFD0, $FFD8: [???? ????] Reg 1
$FFE8, $FFF0: [.cCC ...P] Reg 2
C,c = CHR page
P = PRG page
Once Reg 0 contains a non-zero value, it is locked and cannot be changed until the system is reset.
?Same is true for Reg 1?
Reg 2 is never locked.
CHR Setup:
---------------------------
8k page @ $0000 selected by the following:
'O' CHR page
---------------------
0 %BB BbCC
1 %BB BcCC
PRG Setup:
---------------------------
32k page @ $8000 selected by the following:
'O' PRG page
---------------------
0 %BBBb
1 %BBBP
On Powerup/Reset:
---------------------------
Regs all filled with 0 and unlocked.
========================
= Mapper 240 =
========================
Example Games:
--------------------------
Jing Ke Xin Zhuan
Sheng Huo Lie Zhuan
Registers:
--------------------------
$4020-5FFF: [PPPP CCCC]
P = Selects 32k PRG @ $8000
C = Selects 8k CHR @ $0000
========================
= Mapper 242 =
========================
Example Game:
--------------------------
Wai Xing Zhan Shi
Registers:
---------------------------
$8000-FFFF: A~[.... .... .PPP P.M.]
P = PRG Reg (32k @ $8000)
M = Mirroring (0=Vert, 1=Horz)
Powerup/Reset:
---------------------------
Register set to 0 on powerup/reset.
========================
= Mapper 243 =
========================
Example Games:
--------------------------
Honey
Poker III 5-in-1
Registers:
---------------------------
Range,Mask: $4020-4FFF, $4101
$4100: [.... .AAA] Address for use with $4101
$4101: Data port
R:2 -> [.... ...H] High bit of CHR reg
R:4 -> [.... ...L] Low bit of CHR reg
R:5 -> [.... .PPP] PRG reg (32k @ $8000)
R:6 -> [.... ..DD] Middle bits of CHR reg
R:7 -> [.... .MM.] Mirroring
%00 = Horz
%01 = Vert
%10 = See below
%11 = 1ScB
Mirroring:
---------------------------
Mirroing mode %10 is not quite 1ScB:
[ NTA ][ NTB ]
[ NTB ][ NTB ]
CHR Setup:
---------------------------
8k CHR page @ $0000 is selected by the given 4 bit CHR page number ('HDDL')
========================
= Mapper 245 =
========================
Example Games:
--------------------------
Chu Han Zheng Ba - The War Between Chu & Han
Xing Ji Wu Shi - Super Fighter
Yin He Shi Dai
Yong Zhe Dou e Long - Dragon Quest VII (As)
Dong Fang de Chuan Shuo - The Hyrule Fantasy
Notes:
---------------------------
Another ?Chinese? MMC3 clone. Very similar to your typical MMC3. For MMC3 info, see mapper 004.
Register layout is identical to a typical MMC3.
CHR Setup:
---------------------------
CHR-RAM is not swappable. When there is no CHR-ROM present, 8k CHR-RAM is fixed. However the CHR Mode bit
($8000.7) can still "flip" the left/right pattern tables.
Example:
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+-------------------------------+-------------------------------+
CHR-RAM, Mode 0: | { 0 } | { 1 } |
+-------------------------------+-------------------------------+
CHR-RAM, Mode 1: | { 1 } | { 0 } |
+---------------------------------------------------------------+
CHR-ROM: | Typical MMC3 |
+---------------------------------------------------------------+
PRG Setup:
---------------------------
PRG Setup is the same as a normal MMC3, although there's a PRG-AND of $3F, and games select a 512k Block with
bit 1 of R:0. Pretty simple really:
R:0: [.... ..P.]
'P' PRG-AND PRG-OR
--------------------------
0 $3F $00
1 $3F $40
R:0 remains the normal MMC3 CHR reg, as well. Although the game that uses it as a PRG block selector ("DQ7")
uses CHR-RAM, so it is normally ignored.
========================
= Mapper 246 =
========================
Example Game:
--------------------------
Fong Shen Bang - Zhu Lu Zhi Zhan
Notes:
--------------------------
Regs lie at $6000-67FF, but SRAM exists at $6800-7FFF.
Don't know if there's only 6k of SRAM, or if there's 8k, but the first 2k is inaccessable. I find the latter
more likely.
Registers:
---------------------------
Range,Mask: $6000-67FF, $6007
$6000-6003: PRG Regs
$6004-6007: CHR Regs
CHR Setup:
---------------------------
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00
+---------------+---------------+---------------+---------------+
| $6004 | $6005 | $6006 | $6007 |
+---------------+---------------+---------------+---------------+
PRG Setup:
---------------------------
$8000 $A000 $C000 $E000
+-------+-------+-------+-------+
| $6000 | $6001 | $6002 | $6003 |
+-------+-------+-------+-------+
Powerup/Reset:
---------------------------
$6003 set to $FF on powerup (and probably reset, but not sure).