|
|
(18 intermediate revisions by 6 users not shown) |
Line 1: |
Line 1: |
| [[iNES Mapper 004]] is a wide abstraction that can represent boards using the Nintendo [[MMC3]], Nintendo [[MMC6]], or exact clones of any of the above. Most games utilizing [[TxROM]], [[DxROM]], and [[HKROM]] boards use this designation.
| | #REDIRECT [[MMC3]] |
| | | {{DEFAULTSORT:004}}[[Category:iNES Mappers]][[Category:MMC3-like mappers]][[Category:in NesCartDB]][[Category:Nintendo licensed mappers]][[Category:NES 2.0 mappers with submappers]][[Category:Mappers with scanline IRQs]] |
| A few specific TxROM boards handle the PPU bus differently and thus have separate mapper numbers:
| |
| *[[iNES Mapper 118]] covers TKSROM and TLSROM, which use CHR bank bits to control VRAM mirroring
| |
| *[[iNES Mapper 119]] covers TQROM, which has both CHR RAM and CHR ROM
| |
| | |
| Some [[:Category:MMC3-like mappers|MMC3-like mappers]] have different behaviors and thus their own mapper numbers:
| |
| *[[iNES Mapper 204]] covers Tengen MIMIC-1 or Namco 109 chip, the MMC3's predecessor with no mirroring control or IRQ
| |
| *[[iNES Mapper 64]] covers Tengen RAMBO-1, an MMC3 with additional PRG and CHR bankswitching and IRQ functionality
| |
| *Several MMC3-based multicarts
| |
| | |
| Here are Disch's original notes:
| |
| ========================
| |
| = 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:0> | <R:1> | R:2 | R:3 | R:4 | R:5 |
| |
| +---------------+---------------+---------------+---------------+
| |
| CHR Mode 1: | R:2 | R:3 | R:4 | R:5 | <R:0> | <R:1> |
| |
| +-------+-------+-------+-------+---------------+---------------+
| |
|
| |
| 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 <--- all 4 rises consecutive, will only clock once
| |
| 0,1,0,1,0,1,0,1 <---- all 4 rises nonconsecutive, counter clocked each time!
| |
|
| |
| 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.
| |
| | |
| == See also ==
| |
| *[[iNES Mapper 076]]: more specific Namco 109
| |
| *[[iNES Mapper 064]]: [[Tengen RAMBO-1]], successor to MIMIC-1
| |
| | |
| [[Category:iNES Mappers]][[Category:MMC3-like mappers]] | |