MMC6: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
mNo edit summary
m (typo)
 
(20 intermediate revisions by 8 users not shown)
Line 1: Line 1:
[[Category:ASIC mappers]]
{{Infobox_iNES_mapper
The '''Nintendo MMC6''' is a [[MMC|mapper]] [[:Category:ASIC mappers|ASIC]] used in Nintendo's NES-[[HKROM]] and HVC-HKROM Game Pak boards. This board, along with most common [[TxROM]] boards (which use the [[Nintendo MMC3]]) are assigned to [[iNES Mapper 004]].
|name=MMC6
|name2=HxROM
|company=Nintendo
|mapper=4
|nescartdbgames=2
|complexity=ASIC
|boards=HKROM
|pinout=MMC6 pinout
|prgmax=512K
|prgpage=8K
|wrammax=1K
|wrampage=1K
|chrmax=256K
|chrpage=1K + 2K
|mirroring=H or V, switchable
|busconflicts=No
|irq=Yes
}}
[[Category:MMC3-like mappers]][[Category:Nintendo licensed mappers]][[Category:Mappers with scanline IRQs]]
The '''Nintendo MMC6''' is a [[MMC|mapper]] [[:Category:ASIC mappers|ASIC]] used in Nintendo's NES-HKROM Game Pak board. This board, along with most common [[TxROM]] boards (which use the [[MMC3|Nintendo MMC3]]) are assigned to [[iNES Mapper 004]]. The MMC3C and the MMC6 are alike, except the MMC6 has 1 KB of internal PRG RAM with different write/enable controls. This page only explains the differences, see [[MMC3]] for full details on the rest of the mapper.


== Overview ==
The [[NES 2.0 submappers#004: 1 MMC6|NES 2.0 submapper 004:1]] was assigned to disambiguate MMC6 from the MMC3 mapper it shares an iNES mapper with.
* PRG ROM size: Up to 512 KB
 
* PRG ROM bank size: 8 KB
This chip first appeared in December 1990.  A total of two commercial games were released using the MMC6:
* PRG RAM: 1 KB (internal)
*StarTropics
* CHR capacity: Up to 256 KB ROM
*Zoda's Revenge: StarTropics II
* CHR bank size: 1 KB and 2 KB
* Nametable [[mirroring]]: Controlled by mapper
* Subject to [[bus conflict]]s: No


== Banks ==
== Banks ==
Line 26: Line 42:
== Registers ==
== Registers ==


The MMC6 has 4 pairs of registers at $8000-$9FFF, $A000-$BFFF, $C000-$DFFF, and $E000-$FFFF - even addresses ($8000, $8002, etc.) select the low register and odd addresses ($8001, $8003, etc.) select the high register in each pair.
The MMC6 has 4 pairs of registers at $8000-$9FFF, $A000-$BFFF, $C000-$DFFF, and $E000-$FFFF - even addresses ($8000, $8002, etc.) select the low register and odd addresses ($8001, $8003, etc.) select the high register in each pair. Only $8000 and $A001 are covered here. For the rest of the registers, see [[MMC3]].


=== Bank select ($8000-$9FFE, even) ===
=== Bank select ($8000-$9FFE, even) ===
Line 34: Line 50:
  |||  |||
  |||  |||
  |||  +++- Specify which bank register to update on next write to Bank Data register
  |||  +++- Specify which bank register to update on next write to Bank Data register
  ||+------- PRG RAM enable*
  ||+------- PRG RAM enable
  |+-------- PRG ROM bank configuration (0: $8000-$9FFF swappable, $C000-$DFFF fixed to second-last bank;
  |+-------- PRG ROM bank configuration (0: $8000-$9FFF swappable, $C000-$DFFF fixed to second-last bank;
  |                                      1: $C000-$DFFF swappable, $8000-$9FFF fixed to second-last bank)
  |                                      1: $C000-$DFFF swappable, $8000-$9FFF fixed to second-last bank)
  +--------- CHR ROM bank configuration (0: two 2 KB banks at $0000-$0FFF, four 1 KB banks at $1000-$1FFF;
  +--------- CHR ROM bank configuration (0: two 2 KB banks at $0000-$0FFF, four 1 KB banks at $1000-$1FFF;
                                         1: four 1 KB banks at $0000-$0FFF, two 2 KB banks at $1000-$1FFF)
                                         1: four 1 KB banks at $0000-$0FFF, two 2 KB banks at $1000-$1FFF)
Once PRG RAM has been enabled by writing 1 to the specified bit above, it cannot be disabled without resetting the game.
=== Bank data ($8001-$9FFF, odd) ===
7  bit  0
---- ----
DDDD DDDD
|||| ||||
++++-++++- New bank value, based on last value written to Bank select register
            0: Select 2 KB CHR bank at PPU $0000-$07FF (or $1000-$17FF);
            1: Select 2 KB CHR bank at PPU $0800-$0FFF (or $1800-$1FFF);
            2: Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF);
            3: Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF);
            4: Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF);
            5: Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF);
            6: Select 8 KB PRG bank at $8000-$9FFF (or $C000-$DFFF);
            7: Select 8 KB PRG bank at $A000-$BFFF
=== Mirroring ($A000-$BFFE, even) ===
7  bit  0
---- ----
xxxx xxxM
        |
        +- [[Mirroring]] (0: vertical; 1: horizontal)


=== PRG RAM protect ($A001-$BFFF, odd) ===
=== PRG RAM protect ($A001-$BFFF, odd) ===
Line 73: Line 65:
  |+-------- Enable writing to RAM at $7200-$73FF
  |+-------- Enable writing to RAM at $7200-$73FF
  +--------- Enable reading RAM at $7200-$73FF
  +--------- Enable reading RAM at $7200-$73FF
=== IRQ latch ($C000-$DFFE, even) ===
7  bit  0
---- ----
DDDD DDDD
|||| ||||
++++-++++- IRQ latch value
This register specifies the IRQ counter reload value. When the IRQ counter is zero (or a reload is requested through $C001), this value will be copied into the MMC6 IRQ counter at the end of the current scanline.
=== IRQ reload ($C001-$DFFF, odd) ===
7  bit  0
---- ----
xxxx xxxx
Writing any value to this register requests that the MMC3 IRQ counter be reloaded at the end of the current scanline.
=== IRQ disable ($E000-$FFFE, even) ===
7  bit  0
---- ----
xxxx xxxx
Writing any value to this register will disable MMC3 interrupts AND acknowledge any pending interrupts.
=== IRQ enable ($E001-$FFFF, odd) ===
7  bit  0
---- ----
xxxx xxxx
Writing any value to this register will enable MMC3 interrupts.


== Hardware ==
== Hardware ==


The MMC6 exists in a [[Nintendo MMC6 Pinout|64-pin TQFP package]].
The MMC6 exists in a [[MMC6 pinout|64-pin TQFP package]].
At least two revisions exist, though only MMC6B has been observed.
At least two revisions exist{{Citation needed}}, though only MMC6B has been observed.
 
The MMC6 scanline counter is based entirely on PPU A12, triggered on rising edges (after the line remains low for a sufficiently long period of time).
 
When the scanline counter is clocked, the value will first be checked. If it is zero, it will be reloaded from the IRQ latch ($C000); otherwise, it will decrement. If the old value in the counter is nonzero and new value is zero (whether from decrementing or reloading), an IRQ will be generated IF IRQ generation is enabled (by writing to $E001).


Important points:
The PRG RAM protect bits control mapping of two 512B banks of RAM. If neither bank is enabled for reading, the $7000-$7FFF area is [[open bus]]. If only one bank is enabled for reading, the other reads back as zero. The write-enable bits only have effect if that bank is enabled for reading, otherwise the bank is not writable. Both banks may be enabled for reading (and optionally writing) at the same time.
* The scanline counter cannot be stopped. It will continue to decrement and reload as long as PPU A12 on the PPU bus toggles.
* There is no direct access to the counter! The best you can do is update the reload value and immediately request a reload.
* Writing to $E000 will only prevent the MMC6 from generating IRQs - the counter will continue to run.
* Writing to $E001 will simply allow the MMC6 to generate IRQs - the counter remains unaffected.
* Writing to $C001 will cause the counter to be reloaded on the NEXT rising edge of PPU A12 instead of being decremented.
* Writing to $C000 does not immediately affect the value within the counter - this value is only used when the counter is reloaded, whether from reaching 0 or from writing to $C001.
* Whenever the IRQ counter reaches $00, an IRQ will be generated (if enabled).
* The exact number of scanlines between IRQs is N+1, where N is the value written to $C000. 1 to 256 scanlines are supported.
* Writing $00 to $C000 will result in an IRQ being generated at every rising edge of PPU A12. Writing a non-zero value to $C000 will reload the counter the next time it is clocked.
* The counter will not work properly unless you use different pattern tables for background and sprite data. The standard configuration is to use PPU $0000-$0FFF for background tiles and $1000-$1FFF for sprite tiles, whether 8x8 or 8x16.


Some versions of the [[Nintendo MMC3]] have been observed to have IRQ counters which behave as above when inintialized to zero, while others behave differently, generating a single interrupt and remaining silent until reloaded with a nonzero value.
When PRG RAM is disabled via $8000, the mapper continuously sets $A001 to $00, and so all writes to $A001 are ignored.

Latest revision as of 07:09, 13 May 2021


MMC6
HxROM
Company Nintendo
Games 2 in NesCartDB
Complexity ASIC
Boards HKROM
Pinout MMC6 pinout
PRG ROM capacity 512K
PRG ROM window 8K
PRG RAM capacity 1K
PRG RAM window 1K
CHR capacity 256K
CHR window 1K + 2K
Nametable mirroring H or V, switchable
Bus conflicts No
IRQ Yes
Audio No
iNES mappers 004

The Nintendo MMC6 is a mapper ASIC used in Nintendo's NES-HKROM Game Pak board. This board, along with most common TxROM boards (which use the Nintendo MMC3) are assigned to iNES Mapper 004. The MMC3C and the MMC6 are alike, except the MMC6 has 1 KB of internal PRG RAM with different write/enable controls. This page only explains the differences, see MMC3 for full details on the rest of the mapper.

The NES 2.0 submapper 004:1 was assigned to disambiguate MMC6 from the MMC3 mapper it shares an iNES mapper with.

This chip first appeared in December 1990. A total of two commercial games were released using the MMC6:

  • StarTropics
  • Zoda's Revenge: StarTropics II

Banks

  • CPU $7000-$7FFF: 1 KB PRG RAM, mirrored
  • CPU $8000-$9FFF (or $C000-$DFFF): 8 KB switchable PRG ROM bank
  • CPU $A000-$BFFF: 8 KB switchable PRG ROM bank
  • CPU $C000-$DFFF (or $8000-$9FFF): 8 KB PRG ROM bank, fixed to the second-last bank
  • CPU $E000-$FFFF: 8 KB PRG ROM bank, fixed to the last bank
  • PPU $0000-$07FF (or $1000-$17FF): 2 KB switchable CHR bank
  • PPU $0800-$0FFF (or $1800-$1FFF): 2 KB switchable CHR bank
  • PPU $1000-$13FF (or $0000-$03FF): 1 KB switchable CHR bank
  • PPU $1400-$17FF (or $0400-$07FF): 1 KB switchable CHR bank
  • PPU $1800-$1BFF (or $0800-$0BFF): 1 KB switchable CHR bank
  • PPU $1C00-$1FFF (or $0C00-$0FFF): 1 KB switchable CHR bank

Registers

The MMC6 has 4 pairs of registers at $8000-$9FFF, $A000-$BFFF, $C000-$DFFF, and $E000-$FFFF - even addresses ($8000, $8002, etc.) select the low register and odd addresses ($8001, $8003, etc.) select the high register in each pair. Only $8000 and $A001 are covered here. For the rest of the registers, see MMC3.

Bank select ($8000-$9FFE, even)

7  bit  0
---- ----
CPMx xRRR
|||   |||
|||   +++- Specify which bank register to update on next write to Bank Data register
||+------- PRG RAM enable
|+-------- PRG ROM bank configuration (0: $8000-$9FFF swappable, $C000-$DFFF fixed to second-last bank;
|                                      1: $C000-$DFFF swappable, $8000-$9FFF fixed to second-last bank)
+--------- CHR ROM bank configuration (0: two 2 KB banks at $0000-$0FFF, four 1 KB banks at $1000-$1FFF;
                                       1: four 1 KB banks at $0000-$0FFF, two 2 KB banks at $1000-$1FFF)

PRG RAM protect ($A001-$BFFF, odd)

7  bit  0
---- ----
HhLl xxxx
||||
|||+------ Enable writing to RAM at $7000-$71FF
||+------- Enable reading RAM at $7000-$71FF
|+-------- Enable writing to RAM at $7200-$73FF
+--------- Enable reading RAM at $7200-$73FF

Hardware

The MMC6 exists in a 64-pin TQFP package. At least two revisions exist[citation needed], though only MMC6B has been observed.

The PRG RAM protect bits control mapping of two 512B banks of RAM. If neither bank is enabled for reading, the $7000-$7FFF area is open bus. If only one bank is enabled for reading, the other reads back as zero. The write-enable bits only have effect if that bank is enabled for reading, otherwise the bank is not writable. Both banks may be enabled for reading (and optionally writing) at the same time.

When PRG RAM is disabled via $8000, the mapper continuously sets $A001 to $00, and so all writes to $A001 are ignored.