INES Mapper 176: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
mNo edit summary
(Slightly reorganized and shortened for better readability)
Line 1: Line 1:
[[Category:iNES Mappers|176]]
[[Category:iNES Mappers|176]]{{DEFAULTSORT:176}}[[Category:MMC3-like mappers]][[Category:MMC3 with CHR ROM and CHR RAM]][[Category:Mappers with scanline IRQs]]
Mapper 176 is used by FK23C- and FK23CA-based multicarts as well as the re-releases of Waixing games that were originally released on boards using a variety of mappers. Being primarily designed for multicarts, it consists of an MMC3 clone with extended PRG and CHR bankswitch registers. Its UNIF board names are '''BMC-FK23C''', '''BMC-FK23CA''', '''BMC-Super24in1SC03''' and '''WAIXING-FS005''' (the latter with 32 KiB of PRG-RAM, 16 of which are battery-backed).
iNES Mapper 176 is used by many multicarts as well as mid-2000 new releases and re-releases from Waixing. It consists of an [[MMC3]] clone with greatly extended capabilities.
Its UNIF board names are:
* '''BMC-FK23C''' (no WRAM, no DIP switch)
* '''BMC-FK23CA''' (no WRAM, no DIP switch)
* '''BMC-Super24in1SC03''' (functional duplicate of '''BMC-FK23C''')
* '''WAIXING-FS005''' (32 KiB WRAM, 16 KiB of which battery-backed, no DIP switch)


PRG and CHR bank switching is done via the normal MMC3 registers, whose high bits can be masked off if necessary, before being ORed with higher-order PRG and CHR Base bank bits. Additional Mode Register bits can be set to disable MMC3 PRG and/or CHR banking to solely use the PRG and CHR base directly as bank numbers in a GNROM-like fashion. A special CNROM mode allows ORing the CHR base with a data latch that responds to writes in the $8000-$FFFF range (except $A000-$BFFF). A few multicart menus use an extended MMC3 mode that provides full 1 KiB CHR bank granularity and switching the PRG banks that in a normal MMC3 are fixed. The RAM Configuration Register enables 32 KiB of WRAM, 16 KiB of which are non-volatile (i.e. battery-backed), and allows specifying that only the first 8 KiB of CHR memory are RAM.
Three incompatible subtypes exist that do not correspond to these UNIF board names. No submappers have been proposed, as the subtypes can be easily discerned heuristically by looking at ROM sizes:
* '''Subtype 0''', ROM size other than specified below: boot in first 512 KiB of PRG-ROM.
* '''Subtype 1''', 1024 KiB PRG-ROM, 1024 KiB CHR-ROM: boot in second 512 KiB of PRG-ROM.
* '''Subtype 2''', 16384 KiB PRG-ROM, no CHR-ROM: Like '''Subtype 0''', but MMC3 registers $46 and $47 swapped.


Except for [https://wiki.nesdev.org/w/index.php?title=INES_Mapper_176#1:_Extra_PRG_for_multicart_menu Variant 1], the power-on state is that all new registers are initialized to $00, causing the FK23C to mimic a standard MMC3, which means that the 8 KiB bank in CPU space at $E000 is the bank that ends the first 512 KiB ($7E000), even if the ROM image is larger than that. Several games and multicarts rely on the eight standard MMC3 bank registers being initialized to 0/2/4/5/6/7/0/1 and the four additional bank registers for Extended MMC3 Mode all being initialized to $FF in their power-on state.
'''Subtype 1''' is used by multicarts holding four 128 KiB PRG-ROM-bearing games with no space left in those 512 KiB for the multicart menu. The menu is then put into a separate 32 KiB PRG bank that is mapped into the full PRG address space as the end of a second 512 KiB PRG-ROM bank, the other 480 KiB of that second 512 KiB PRG-ROM bank being empty.


==Registers==
=Registers=
FK23CA-variant boards have a DIP switch that changes the address mask at which the board hardware responds to CPU writes in the $5000-$5FFF range. The address mask is $10 SHL DIP, e.g. a DIP value of zero results in an address mask of $5010, a value of one in an address mask of $5020, and so on. Multicarts determine the DIP setting by attempting a PRG bankswitch at $5011, $5021, $5041, then checking after each attempt whether the bankswitch actually occured; subsequently registers are accessed at $5FFx, which will bankswitch at any DIP switch setting. A DIP setting of zero (address mask $5010) will produce a usable result for any ROM image, although the multicart's menu is sometimes found at other settings; such ROMs will not be recognizable as multicarts on emulators that do not allow changing the DIP switch setting and will instead appear to be oversized variants of one of the individual games.
Registers in the $5000-$5FFF range can be temporarily disabled through the [[#RAM Configuration Register ($A001)|RAM Configuration Register ($A001)]].


Note that the registers in the $5000-$5FFF range can be temporarily disabled by the RAM Configuration Register ($A001). Waixing games do this apparently for [[#RAM_Configuration_Register_.28.24A001.29|protection purposes]].
==Mode Register ($5xx0)==
Mask: $5''xx''F, ''x'' determined by [[#DIP Switch|DIP Switch setting]]


===Mode Register ($5xx0)===
  7654 3210
  7654 3210
  ---- ----
  ---- ----
  PCTm PMMM
  PCTm PMMM
  |||| ||||
  |||| ||||
  |||| |+++- PRG Mode/Mask (*1)
  |||| |+++- Select PRG Banking Mode
  |||| |      0: MMC3 Bank AND $3F OR ((PRG Base SHL 1) AND NOT $3F)
  |||| |      0: MMC3 PRG Mode, 512 KiB Outer PRG Bank Size
  |||| |      1: MMC3 Bank AND $1F OR ((PRG Base SHL 1) AND NOT $1F)
  |||| |      1: MMC3 PRG Mode, 256 KiB Outer PRG Bank Size
  |||| |      2: MMC3 Bank AND $0F OR ((PRG Base SHL 1) AND NOT $0F)
  |||| |      2: MMC3 PRG Mode, 128 KiB Outer PRG Bank Size
  |||| |      3: PRG Base selects the same 16 KiB PRG bank at CPU $8000 and $C000
  |||| |      3: NROM-128 PRG Mode, 16 KiB PRG at $8000-$BFFF mirrored at $C000-$FFFF
  |||| |      4: PRG Base SHR 1 selects 32 KiB PRG bank at CPU $8000
  |||| |      4: NROM-256 PRG Mode, 32 KiB PRG at $8000-$FFFF
  |||| |      5-7: Never used
  |||| |      5-7: Never used
  |||| +---- PRG Base bit 7
  |||| +---- 16 KiB PRG Base bit 7
  |||+------ CHR Mask
  |||+------ Select Outer CHR Bank Size
  |||        0: $FF in MMC3 CHR Mode (bit 6 clear), $03 in CNROM Mode ($5xx0 bit 6 set and $5xx3 bit 2/6 set)
  |||        0: In MMC3 CHR Mode: 256 KiB
  |||        1: $FF/$FF/$7F (selected by bits 0-2) in MMC3 CHR Mode (bit 6 clear), $01 in CNROM Mode ($5xx0 bit 6 set and $5xx3 bit 2/6 set)
|||            In CNROM CHR Mode: 32 KiB
  ||+------- CHR Type (0: ROM, 1: RAM) (*2)
  |||        1: In MMC3 CHR Mode: Same as Outer PRG Bank Size
|||            In CNROM CHR Mode: 16 KiB
  ||+------- Select CHR Memory Type
||          0: CHR-ROM
||          1: CHR-RAM
  |+-------- CHR Mode
  |+-------- CHR Mode
  |          0: MMC3 Bank AND CHR Mask (bit 4) OR ((CHR Base SHL 3 AND NOT CHR Mask)
  |          0: MMC3 CHR Mode
  |          1: CHR Base selects 8 KiB CHR bank at PPU $8000. If CNROM Mode is active, the CNROM latch ANDed with the mask set by bit 4 and ORed with the CHR base.
  |          1: NROM/CNROM CHR Mode
+--------- PRG Base bit 8
+--------- 16 KiB PRG Base bit 8
Power-on value: $00
* It is possible to use NROM mode for PRG banking and MMC3 mode for CHR banking.
* NROM versus CNROM CHR Mode is decided in the Extended Mode Register ($5xx3).
* Bit 5 applies to CHR Memory in its entirety, while Bit 2 of the [[#RAM Configuration Register ($A001)|RAM Configuration Register ($A001)]] selects mixed CHR-ROM/RAM mode.
* The inner and outer bank numbers are combined ...
** ... in MMC3 PRG/CHR modes: by masking the MMC3 bank register content according to the specified size (128 or 256 KiB) and OR'ing with the opposite-masked content of the PRG ($5xx1)/CHR ($5xx2) Base;
** ... in NROM PRG/CHR mode: by using the PRG ($5xx1)/CHR Base ($5xx2) directly.
** ... in CNROM CHR mode: by masking the CNROM Latch according to the selected Outer CHR Bank Size, and OR'ing with the opposite-masked content of the CHR Base ($5xx2);


* (*1) In Extended MMC3 Mode ($5xx3 bit 1 set), the MMC3 Bank mask is $7F regardless of the value of $5xx0 bits 0 to 2.
==PRG Base Register ($5xx1)==
* (*2) The CHR Type (bit 5) is only meaningful on carts that have both CHR-RAM and CHR-ROM, such as the Rockman I-VI multicart. On carts that only have one type of CHR memory, this bit cannot be relied upon to correctly specify the installed memory type.
Mask: $5''xx''F, ''x'' determined by [[#DIP Switch|DIP Switch setting]]


===PRG Base Register ($5xx1)===
  7654 3210
  7654 3210
  ---- ----
  ---- ----
Line 42: Line 62:
   ||| ||||
   ||| ||||
   +++-++++- 16 KiB PRG Base bits 0-6
   +++-++++- 16 KiB PRG Base bits 0-6
Power-on value: $00 ('''Subtypes 0 and 2'''), $20 ('''Subtype 1''')
==CHR Base Register ($5xx2)==
Mask: $5''xx''F, ''x'' determined by [[#DIP Switch|DIP Switch setting]]


===CHR Base Register ($5xx2)===
  7654 3210
  7654 3210
  ---- ----
  ---- ----
Line 50: Line 73:
  ++++-++++- 8 KiB CHR Base bits 0-7
  ++++-++++- 8 KiB CHR Base bits 0-7
   |
   |
   +-------- also: PRG Base bit 9
   +-------- 16 KiB PRG Base bit 9
Power-on value: $00
Writing to the CHR Base Register also resets the CNROM latch.
 
==Extended Mode Register ($5xx3)==
Mask: $5''xx''F, ''x'' determined by [[#DIP Switch|DIP Switch setting]]


Writing to the CHR Base Register also resets the CNROM latch.
===Extended Mode Register ($5xx3)===
  7654 3210
  7654 3210
  ---- ----
  ---- ----
  .C.. .CE.
  .C.. .CE.
   |    ||  
   |    ||  
   |    |+- Extended MMC3 Mode (0: disable, 1: enable)
   |    |+- [[#MMC3-compatible registers ($8000/$8001, $A000, $C000/$C001, $E000/$E001)|Extended MMC3 Mode]]
   +----+-- CNROM mode (0: disable, 1: enable)
  |    |    0: disable
  |    |    1: enable
   +----+-- Select NROM/CNROM CHR Mode
            0: NROM
            1: CNROM
Power-on value: $00
Since all games that use CNROM mode always set both bits 2 and 6 simultaneously, it's not clear which one of these bits actually triggers the CNROM mode, and what the function of the other bit would be.


Since all games that use CNROM mode always set both bits 2 and 6 simultaneously, it's not clear which one of these bits actually triggers the CNROM mode, and what the function of the other bit would be.
==RAM Configuration Register ($A001)==
Mask: $E001


===RAM Configuration Register ($A001)===
This register functions like MMC3 register $A001 until bit 5 is set, which turns it into the RAM Configuration Register.
This register functions like MMC3 register $A001 until bit 5 is set, which turns it into the RAM Configuration Register.


Line 82: Line 116:
  |          1: FK23C Registers enabled in the $5000-$5FFF range
  |          1: FK23C Registers enabled in the $5000-$5FFF range
  +--------- PRG RAM enable (0: disable, 1: enable)
  +--------- PRG RAM enable (0: disable, 1: enable)
 
Power-on value: $00
Of the four 8 KiB WRAM banks, only bank 1 and 3 are non-volatile. Games usually use bank 0 as work RAM, bank 2 for protection, and banks 1 and 3 for save game data.
Of the four 8 KiB WRAM banks, only bank 1 and 3 are non-volatile. Games usually use bank 0 as work RAM, bank 2 for protection, and banks 1 and 3 for save game data.


The protection check involves disabling the FK23C registers in the $5000-$5FFF range by writing $Ax to $A001, then writing some code to $5000, $5010 and $5013 which will land in the second half of WRAM bank 2. After re-enabling the FK23C registers and copying save game data from banks 1 and/or 3 into work RAM in bank 0, bank 2 is switched in, and the three code code bytes originally written via the $5000-$5FFF window are copied to internal RAM and executed, which in many games are just a simple RTS. Most Waixing mapper 176 ROM images in GoodNES 3.23b have been hacked to partially remove this protection and to allow them to be run in emulators that merely ignore the WRAM writes to $5000, $5010 and $5013.
==CNROM latch ($8000-$9FFF, $C000-$FFFF)==
In CNROM Mode, writing to these address ranges changes the inner CHR bank.


===CNROM latch ($8000-$9FFF, $C000-$FFFF)===
==MMC3-compatible registers ($8000/$8001, $A000, $C000/$C001, $E000/$E001)==
If CNROM Mode is active ($5xx0 bit 6 set and $5xx3 bit 2/6 set), writes to these ranges will update a data latch similar to a normal [[INES Mapper 003|CNROM]] board, with the latch value being masked according to $5xx0 bit 4 before being ORed with the CHR Base.
 
===MMC3-compatible registers ($8000/$8001, $A000, $C000/$C001, $E000/$E001)===
If the "Extended MMC3 Mode" bit in register $5xx3 is clear, then these registers function identically to the [[MMC3]]. If the "Extended MMC3 Mode" bit is set, four more bank registers become available at [[MMC3#Bank_select_.28.248000-.249FFE.2C_even.29|$8000/$8001]], so that the original two 2 KiB CHR banks become four 1 KiB CHR banks, and the two fixed 8 KiB PRG banks become selectable:
If the "Extended MMC3 Mode" bit in register $5xx3 is clear, then these registers function identically to the [[MMC3]]. If the "Extended MMC3 Mode" bit is set, four more bank registers become available at [[MMC3#Bank_select_.28.248000-.249FFE.2C_even.29|$8000/$8001]], so that the original two 2 KiB CHR banks become four 1 KiB CHR banks, and the two fixed 8 KiB PRG banks become selectable:
  Register $8000 if $5xx3 bit 1 is set (Mask: $E001):
  Register $8000 if $5xx3 bit 1 is set (Mask: $E001):
Line 98: Line 131:
  ||  ||||
  ||  ||||
  ||  ++++- 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
  ||        0: Select 1 KB CHR bank at PPU $0000-$03FF (or $1000-$13FF)
  ||        $0: Select 1 KB CHR bank at PPU $0000-$03FF (or $1000-$13FF)
  ||        1: Select 1 KB CHR bank at PPU $0800-$0BFF (or $1800-$1BFF)
  ||        $1: Select 1 KB CHR bank at PPU $0800-$0BFF (or $1800-$1BFF)
  ||        2: Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF)
  ||        $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)
  ||        $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)
  ||        $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)
  ||        $5: Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF)
  ||        6: Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF)
  ||        $6: Select 8 KB PRG ROM bank at $8000-$9FFF (or $C000-$DFFF)
  ||        7: Select 8 KB PRG ROM bank at $A000-$BFFF
  ||        $7: Select 8 KB PRG ROM bank at $A000-$BFFF
  ||        8: Select 8 KB PRG ROM bank at $C000-$DFFF (or $8000-$9FFF)
  ||        $8: Select 8 KB PRG ROM bank at $C000-$DFFF (or $8000-$9FFF)
  ||        9: Select 8 KB PRG ROM bank at $E000-$FFFF
  ||        $9: Select 8 KB PRG ROM bank at $E000-$FFFF
  ||        A: Select 1 KB CHR bank at PPU $0400-$07FF (or $1400-$17FF)
  ||        $A: Select 1 KB CHR bank at PPU $0400-$07FF (or $1400-$17FF)
  ||        B: Select 1 KB CHR bank at PPU $0C00-$0FFF (or $1C00-$1FFF)
  ||        $B: Select 1 KB CHR bank at PPU $0C00-$0FFF (or $1C00-$1FFF)
  |+-------- PRG A14 inversion
  |+-------- Invert PRG A14
  +--------- CHR A12 inversion
  +--------- Invert CHR A12
 
Power-on values:
* Standard MMC3 Registers $0-$7: $00, $02, $04, $05, $06, $07, $00, $01
* Extended MMC3 Registers $8-$B: $FE, $FF, $FF, $FF
If the "Extended MMC3 Mode" bit is set, a second Mirroring bit in register $A000 becomes available, allowing single-screen mirroring to be selected in addition to Vertical and Horizontal Mirroring:
If the "Extended MMC3 Mode" bit is set, a second Mirroring bit in register $A000 becomes available, allowing single-screen mirroring to be selected in addition to Vertical and Horizontal Mirroring:
  Register $A000 if $5xx3 bit 1 is set (Mask: $E001):
  Register $A000 if $5xx3 bit 1 is set (Mask: $E001):
Line 123: Line 159:
             2: Single-screen, page 0
             2: Single-screen, page 0
             3: Single-screen, page 1
             3: Single-screen, page 1
==Variants==
Power-on value: $00
No submappers have been assigned yet for incompatible variants of the hardware.
 
===0: Normal===
=DIP Switch=
Powers up with the PRG Base Register set to $00, causing the FK23C to mimic a standard MMC3, which means that the 8 KiB bank in CPU space at $E000 is the bank that ends the first 512 KiB ($7E000), even if the ROM image is larger than that.
The address mask in the $5000-$5FFF range is determined by the DIP switch setting:
===1: Extra PRG for multicart menu===
DIP setting  Address mask
A few multicarts hold four 128 KiB PRG-ROM-bearing games with no space left in those 512 KiB for the multicart menu. The menu is then put into a separate 32 KiB PRG bank that is mapped into the full PRG address space as the end of a second 512 KiB PRG-ROM bank, the other 480 KiB of that second 512 KiB PRG-ROM bank being empty. Carts in that configuration thus boot up with the 8 KiB bank in CPU space at $E000 being the bank that ends the second 512 KiB ($FE000), by initializing the PRG Base Register to $60 (or $20). These carts can be automatically detected by the fact that they, and only they, all have 1024 KiB of PRG-ROM and 1024 KiB of CHR-ROM.
-----------  ------------
===2: Flipped MMC3 Registers $46 and $47===
0            $501F
For unknown reasons, the two very large (16 MiB of PRG-ROM) multicarts swap MMC3 registers $46 and $47, but not $06 and $07. Individual MMC3 games, such as Kage, on these multicarts were modified to account for this. These carts can be automatically detected by the fact that they contain 16384 KiB of PRG-ROM.
1            $502F
2            $504F
3            $508F
4            $510F
5            $520F
6            $540F
7            $580F
* A DIP setting of zero (address mask $5010) will produce a usable result for any ROM image.
* Some multicarts only display their menu at settings other than 0.
 
=Protection=
Later Waixing games (and re-releases of earlier games) use the RAM Configuration Register for copy-protection purposes:
* Write $A1 to $A001: Address range $5000-$5FFF to second half of 8 KiB WRAM bank 2, mapper registers there are disabled.
* Write three values to $5000, $5010 and $5013.
* Do further initialization.
* Write $E2 to $A001. Mapper registers in address range $5000-$5FFF; WRAM at CPU $6000-$7FFF points to 8 KiB WRAM bank 2.
* Copy 20 bytes from $7000 to $6000.
* Copy and XOR bytes from $6000, $6010 and $6013 to $0100-$0102.
* Execute code at CPU $0100.
Hacked ROMs can be detected by writing to $5000/$5010/$5013 but then no longer jumping to $0100.
 
=Notes=
* Multicarts without CHR-ROM have large amounts of CHR-RAM in into which an individual game's CHR data is copied when it is selected:
** 128 KiB: 10-in-1 Omake Game, 150-in-1 Real Game, 245-in-1 Real Game
** 256 KiB: 120-in-1 (Waixing)
* Waixing re-released some of their earlier games, that were published using different mappers, in the mid-2000s using their FS005 board, often without updating the serial number.
* There are about 60 multicarts and about 40 single Waixing games, including rereleases, using Mapper 176.


==Notes==
=Errata=
* The RAM Configuration Register is not just enabled by Waixing games, but also by some of the later FK23C multicarts, which does not imply however that they are actually equipped with PRG-RAM.
* Games using advanced functionalites such as Extended MMC3 Mode or 32 KiB WRAM have duplicates in some implementations of [[INES Mapper 030]] and [[INES Mapper 199]]. As these mapper numbers are also used for other boards, these games should be reassigned to Mapper 176 instead of adding Mapper 176 functionality to Mappers 30 and 199.
* If a cart has both CHR-ROM and CHR-RAM, then a NES 2.0 header must be used to specify that, as most emulators disable CHR-RAM completely if a NES 1.0 header with CHR-ROM is found.
* GoodNES 3.23b's "Mortal Kombat Trilogy - 8 People (M1274) (Ch) [!]" is actually the "KY-9005 9-in-1" multicart and runs on [[NES 2.0 Mapper 290]].
* Large multicarts with no CHR-ROM use large amounts of CHR-RAM into which an individual game's CHR data is copied when it is selected. CHR-RAM sizes range from 128 KiB (10-in-1 Omake Game, 150-in-1 Real Game, 245-in-1 Real Game) and even 256 KiB (120-in-1 Waixing Games).
* ''帝国风暴 (Dìguó Fēngbào) - Napoleon's War'' with serial number 980340 requires PAL or Dendy timing to not freeze before the main game screen is shown. Serial number 980100029 does not suffer from this problem.
* Many Waixing games in GoodNES 3.23b that correctly should be set to mapper 176 are incorrectly set to [[INES Mapper 030|Mapper 30]]. These games were converted from Waixing's proprietary (and encrypted) .WXN format; the Mapper 30 designation is the result of interpreting these .WXN files' non-iNES header as if it were an iNES header.  
* ''Five Kids'' on the ''120-in-1'' multicart writes to [[VT03|OneBus]] bank registers in its IRQ handler and glitches on normal NES/Famicom hardware.
* The ROM image that GoodNES 3.23b calls "Mortal Kombat Trilogy - 8 People (M1274) (Ch) [!].zip" is actually an earlier version of the "KY-9005 9-in-1" multicart and runs on [[NES 2.0 Mapper 290]].
* The WXN version of ''帝国风暴 (Dìguó Fēngbào) - Napoleon's War'' requires PAL or Dendy timing. On NTSC systems, the game will freeze before the main game screen is shown because of an excessively long NMI handler. The game will ''appear'' to run even in NTSC mode on some emulators that do not emulate the RAM Configuration Register and instead interpret the $E0 write to $A001 as an MMC3 to mean "deny any writes to WRAM". The game map will be empty in those emulators however, rendering the game unplayable.
* The game ''Five Kids'' on the ''120-in-1'' Waixing multicart is glitched because it writes to [[VT03|OneBus]] bank registers in its IRQ handler.
* FCEUX emulates [[INES Mapper 199]] as a duplicate of Mapper 176 behaving as if bit 2 of the RAM Configuration Register were permanently set and as if Extended MMC3 Mode were permanently active, probably because the function of those bits was not known for a long time.

Revision as of 16:14, 18 February 2018

iNES Mapper 176 is used by many multicarts as well as mid-2000 new releases and re-releases from Waixing. It consists of an MMC3 clone with greatly extended capabilities. Its UNIF board names are:

  • BMC-FK23C (no WRAM, no DIP switch)
  • BMC-FK23CA (no WRAM, no DIP switch)
  • BMC-Super24in1SC03 (functional duplicate of BMC-FK23C)
  • WAIXING-FS005 (32 KiB WRAM, 16 KiB of which battery-backed, no DIP switch)

Three incompatible subtypes exist that do not correspond to these UNIF board names. No submappers have been proposed, as the subtypes can be easily discerned heuristically by looking at ROM sizes:

  • Subtype 0, ROM size other than specified below: boot in first 512 KiB of PRG-ROM.
  • Subtype 1, 1024 KiB PRG-ROM, 1024 KiB CHR-ROM: boot in second 512 KiB of PRG-ROM.
  • Subtype 2, 16384 KiB PRG-ROM, no CHR-ROM: Like Subtype 0, but MMC3 registers $46 and $47 swapped.

Subtype 1 is used by multicarts holding four 128 KiB PRG-ROM-bearing games with no space left in those 512 KiB for the multicart menu. The menu is then put into a separate 32 KiB PRG bank that is mapped into the full PRG address space as the end of a second 512 KiB PRG-ROM bank, the other 480 KiB of that second 512 KiB PRG-ROM bank being empty.

Registers

Registers in the $5000-$5FFF range can be temporarily disabled through the RAM Configuration Register ($A001).

Mode Register ($5xx0)

Mask: $5xxF, x determined by DIP Switch setting

7654 3210
---- ----
PCTm PMMM
|||| ||||
|||| |+++- Select PRG Banking Mode
|||| |      0: MMC3 PRG Mode, 512 KiB Outer PRG Bank Size
|||| |      1: MMC3 PRG Mode, 256 KiB Outer PRG Bank Size
|||| |      2: MMC3 PRG Mode, 128 KiB Outer PRG Bank Size
|||| |      3: NROM-128 PRG Mode, 16 KiB PRG at $8000-$BFFF mirrored at $C000-$FFFF
|||| |      4: NROM-256 PRG Mode, 32 KiB PRG at $8000-$FFFF
|||| |      5-7: Never used
|||| +---- 16 KiB PRG Base bit 7
|||+------ Select Outer CHR Bank Size
|||         0: In MMC3 CHR Mode: 256 KiB
|||            In CNROM CHR Mode: 32 KiB
|||         1: In MMC3 CHR Mode: Same as Outer PRG Bank Size
|||            In CNROM CHR Mode: 16 KiB
||+------- Select CHR Memory Type
||          0: CHR-ROM
||          1: CHR-RAM
|+-------- CHR Mode
|           0: MMC3 CHR Mode
|           1: NROM/CNROM CHR Mode
+--------- 16 KiB PRG Base bit 8

Power-on value: $00
  • It is possible to use NROM mode for PRG banking and MMC3 mode for CHR banking.
  • NROM versus CNROM CHR Mode is decided in the Extended Mode Register ($5xx3).
  • Bit 5 applies to CHR Memory in its entirety, while Bit 2 of the RAM Configuration Register ($A001) selects mixed CHR-ROM/RAM mode.
  • The inner and outer bank numbers are combined ...
    • ... in MMC3 PRG/CHR modes: by masking the MMC3 bank register content according to the specified size (128 or 256 KiB) and OR'ing with the opposite-masked content of the PRG ($5xx1)/CHR ($5xx2) Base;
    • ... in NROM PRG/CHR mode: by using the PRG ($5xx1)/CHR Base ($5xx2) directly.
    • ... in CNROM CHR mode: by masking the CNROM Latch according to the selected Outer CHR Bank Size, and OR'ing with the opposite-masked content of the CHR Base ($5xx2);

PRG Base Register ($5xx1)

Mask: $5xxF, x determined by DIP Switch setting

7654 3210
---- ----
.PPP PPPP
 ||| ||||
 +++-++++- 16 KiB PRG Base bits 0-6

Power-on value: $00 (Subtypes 0 and 2), $20 (Subtype 1)

CHR Base Register ($5xx2)

Mask: $5xxF, x determined by DIP Switch setting

7654 3210
---- ----
CPCC CCCC
|||| ||||
++++-++++- 8 KiB CHR Base bits 0-7
 |
 +-------- 16 KiB PRG Base bit 9

Power-on value: $00

Writing to the CHR Base Register also resets the CNROM latch.

Extended Mode Register ($5xx3)

Mask: $5xxF, x determined by DIP Switch setting

7654 3210
---- ----
.C.. .CE.
 |    || 
 |    |+- Extended MMC3 Mode
 |    |    0: disable
 |    |    1: enable
 +----+-- Select NROM/CNROM CHR Mode
           0: NROM
           1: CNROM

Power-on value: $00

Since all games that use CNROM mode always set both bits 2 and 6 simultaneously, it's not clear which one of these bits actually triggers the CNROM mode, and what the function of the other bit would be.

RAM Configuration Register ($A001)

Mask: $E001

This register functions like MMC3 register $A001 until bit 5 is set, which turns it into the RAM Configuration Register.

7654 3210
---- ----
RFE. ?CWW
|||  ||||
|||  ||++- Select 8 KiB PRG-RAM bank at $6000-$7FFF. Ignored if Bit 5 is clear.
|||  |+--- Select the memory type in the first 8 KiB of CHR space. Ignored if Bit 5 is clear.
|||  |      0: First 8 KiB are CHR-ROM
|||  |      1: First 8 KiB are CHR-RAM
|||  +---- Set to 1 by some Waixing games, meaning unknown
||+------- RAM Configuration Register Enable
||          0: RAM Configuration Register disabled, $A001 functions as on MMC3, 8 KiB of WRAM
||          1: RAM Configuration Register enabled, 32 KiB of WRAM
|+-------- FK23C Registers Enable. Ignored if Bit 5 is clear.
|           0: FK23C Registers disabled, $5000-$5FFF maps to the second 4 KiB of the 8 KiB WRAM bank 2
|           1: FK23C Registers enabled in the $5000-$5FFF range
+--------- PRG RAM enable (0: disable, 1: enable)

Power-on value: $00

Of the four 8 KiB WRAM banks, only bank 1 and 3 are non-volatile. Games usually use bank 0 as work RAM, bank 2 for protection, and banks 1 and 3 for save game data.

CNROM latch ($8000-$9FFF, $C000-$FFFF)

In CNROM Mode, writing to these address ranges changes the inner CHR bank.

MMC3-compatible registers ($8000/$8001, $A000, $C000/$C001, $E000/$E001)

If the "Extended MMC3 Mode" bit in register $5xx3 is clear, then these registers function identically to the MMC3. If the "Extended MMC3 Mode" bit is set, four more bank registers become available at $8000/$8001, so that the original two 2 KiB CHR banks become four 1 KiB CHR banks, and the two fixed 8 KiB PRG banks become selectable:

Register $8000 if $5xx3 bit 1 is set (Mask: $E001):
7  bit  0
---- ----
CP.. RRRR
||   ||||
||   ++++- Specify which bank register to update on next write to Bank Data register
||         $0: Select 1 KB CHR bank at PPU $0000-$03FF (or $1000-$13FF)
||         $1: Select 1 KB CHR bank at PPU $0800-$0BFF (or $1800-$1BFF)
||         $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 ROM bank at $8000-$9FFF (or $C000-$DFFF)
||         $7: Select 8 KB PRG ROM bank at $A000-$BFFF
||         $8: Select 8 KB PRG ROM bank at $C000-$DFFF (or $8000-$9FFF)
||         $9: Select 8 KB PRG ROM bank at $E000-$FFFF
||         $A: Select 1 KB CHR bank at PPU $0400-$07FF (or $1400-$17FF)
||         $B: Select 1 KB CHR bank at PPU $0C00-$0FFF (or $1C00-$1FFF)
|+-------- Invert PRG A14
+--------- Invert CHR A12

Power-on values:
* Standard MMC3 Registers $0-$7: $00, $02, $04, $05, $06, $07, $00, $01
* Extended MMC3 Registers $8-$B: $FE, $FF, $FF, $FF

If the "Extended MMC3 Mode" bit is set, a second Mirroring bit in register $A000 becomes available, allowing single-screen mirroring to be selected in addition to Vertical and Horizontal Mirroring:

Register $A000 if $5xx3 bit 1 is set (Mask: $E001):
7  bit  0
---- ----
.... ..MM
       ++- Select nametable mirroring 
           0: Vertical
           1: Horizontal
           2: Single-screen, page 0
           3: Single-screen, page 1
Power-on value: $00

DIP Switch

The address mask in the $5000-$5FFF range is determined by the DIP switch setting:

DIP setting  Address mask
-----------  ------------
0            $501F
1            $502F
2            $504F
3            $508F
4            $510F
5            $520F
6            $540F
7            $580F
  • A DIP setting of zero (address mask $5010) will produce a usable result for any ROM image.
  • Some multicarts only display their menu at settings other than 0.

Protection

Later Waixing games (and re-releases of earlier games) use the RAM Configuration Register for copy-protection purposes:

  • Write $A1 to $A001: Address range $5000-$5FFF to second half of 8 KiB WRAM bank 2, mapper registers there are disabled.
  • Write three values to $5000, $5010 and $5013.
  • Do further initialization.
  • Write $E2 to $A001. Mapper registers in address range $5000-$5FFF; WRAM at CPU $6000-$7FFF points to 8 KiB WRAM bank 2.
  • Copy 20 bytes from $7000 to $6000.
  • Copy and XOR bytes from $6000, $6010 and $6013 to $0100-$0102.
  • Execute code at CPU $0100.

Hacked ROMs can be detected by writing to $5000/$5010/$5013 but then no longer jumping to $0100.

Notes

  • Multicarts without CHR-ROM have large amounts of CHR-RAM in into which an individual game's CHR data is copied when it is selected:
    • 128 KiB: 10-in-1 Omake Game, 150-in-1 Real Game, 245-in-1 Real Game
    • 256 KiB: 120-in-1 (Waixing)
  • Waixing re-released some of their earlier games, that were published using different mappers, in the mid-2000s using their FS005 board, often without updating the serial number.
  • There are about 60 multicarts and about 40 single Waixing games, including rereleases, using Mapper 176.

Errata

  • Games using advanced functionalites such as Extended MMC3 Mode or 32 KiB WRAM have duplicates in some implementations of INES Mapper 030 and INES Mapper 199. As these mapper numbers are also used for other boards, these games should be reassigned to Mapper 176 instead of adding Mapper 176 functionality to Mappers 30 and 199.
  • GoodNES 3.23b's "Mortal Kombat Trilogy - 8 People (M1274) (Ch) [!]" is actually the "KY-9005 9-in-1" multicart and runs on NES 2.0 Mapper 290.
  • 帝国风暴 (Dìguó Fēngbào) - Napoleon's War with serial number 980340 requires PAL or Dendy timing to not freeze before the main game screen is shown. Serial number 980100029 does not suffer from this problem.
  • Five Kids on the 120-in-1 multicart writes to OneBus bank registers in its IRQ handler and glitches on normal NES/Famicom hardware.