Action 53 mapper
This is a sketch of a mapper that allows making a multicart of games that use multiple discrete mappers. As a random sample, it'd support 1943: The Battle of Midway/Valhalla (UNROM), 3-D Battles of Worldrunner (UNROM), Battle City (NROM-128), Battle Kid: Fortress of Peril (UOROM), Battle Tank (CNROM), Battleship (CNROM), Battletoads (AOROM), and Gekitotsu Yonku Battle (UNROM). iNES Mapper 028 has been preliminarily assigned.
Registers
- $5000-$5FFF
- Register select
- $8000-$FFFF
- Register value
$5000: Register select
7654 3210 S R | +- Select register +--------- 0: User registers; 1: Supervisor registers
In a multicart, registers $00 and $01 change the bank within a game, and registers $80 and $81 remain constant throughout a given game's execution.
$00: CHR bank
7654 3210 M BB | ++- Set CHR RAM A14-A13 +------ Set CIRAM A10 if H/V mirroring is disabled
$01: Inner bank
7654 3210 M BBBB | ++++- Set current PRG ROM bank +------ Set CIRAM A10 if H/V mirroring is disabled
$80: Mode
7654 3210 SS PPMM || ||++- Nametable mirroring mode || ++--- PRG bank mode ++------ PRG outer bank size
Mode | Effect |
---|---|
0 | 1-screen lower bank |
1 | 1-screen upper bank |
2 | Vertical (and ignore writes to bit 4 of registers $00 and $01) |
3 | Horizontal (and ignore writes to bit 4 of registers $00 and $01) |
Mode | Effect |
---|---|
0, 1 | Current 32 KiB bank in $8000-$FFFF |
2 | Fixed bottom half of outer bank in $8000-$BFFF and current bank in $C000-$FFFF |
3 | Current bank in $8000-$BFFF and fixed top half of outer bank in $C000-$FFFF |
When the fixed bank ($8000-$BFFF in mode 2 or $C000-$FFFF in mode 3) is accessed, it treats accesses to the fixed bank the same way as accesses in mode 0 with 32K: the outer bank bits are passed straight through. For example, this would allow the fixed $C000 bank in mode 3 128K to be set to 16K bank 7 (as in mapper 2) or 1, 3, or 5. In mode 2 128K, the fixed $8000 bank could be configured as 16K bank 0 (as in mapper 180) or 2, 4, or 6.
Mode | Effect |
---|---|
0 | A20-A15 controlled by outer bank (32 KiB) |
1 | A20-A16 controlled by outer bank (64 KiB) |
2 | A20-A17 controlled by outer bank (128 KiB) |
3 | A20-A18 controlled by outer bank (256 KiB) |
Here are some examples of how bank modes work, assuming the outer bank is set to $12 and inner bank is $07, along with which bits from the inner bank are used:
Mode value | PRG bank mode | Outer bank size | Bank in $8000-$BFFF | Bank in $C000-$FFFF |
---|---|---|---|---|
$00-$07 | 32 KiB | 32 KiB | $12 bottom (xxxx) | $12 top (xxxx) |
$08-$0B | Fixed $8000 | 32 KiB | $12 bottom (xxxx) | $12 top (xxx1) |
$0C-$0F | Fixed $C000 | 32 KiB | $12 top (xxx1) | $12 top (xxxx) |
$10-$17 | 32 KiB | 64 KiB | $13 bottom (xxx1) | $13 top (xxx1) |
$18-$1B | Fixed $8000 | 64 KiB | $12 bottom (xxxx) | $13 top (xx11) |
$1C-$1F | Fixed $C000 | 64 KiB | $13 top (xx11) | $12 top (xxxx) |
$20-$27 | 32 KiB | 128 KiB | $13 bottom (xx11) | $13 top (xx11) |
$28-$2B | Fixed $8000 | 128 KiB | $12 bottom (xxxx) | $13 top (x111) |
$2C-$2F | Fixed $C000 | 128 KiB | $13 top (x111) | $12 top (xxxx) |
$30-$37 | 32 KiB | 256 KiB | $17 bottom (x111) | $17 top (x111) |
$38-$3B | Fixed $8000 | 256 KiB | $12 bottom (xxxx) | $13 top (0111) |
$3C-$3F | Fixed $C000 | 256 KiB | $13 top (0111) | $12 top (xxxx) |
$81: Outer bank
7654 3210 BB BBBB ++-++++- Set outer PRG ROM bank
Power up state
At power on, the last 16 KiB of the ROM is mapped into $C000-$FFFF. The rest of the state is unspecified. One possible init sequence involves setting reg $81 = $FF and reg $80 = $02 to get into oversize-BNROM mode.
Currently, the mapper state is unchanged on reset.
Configurations
- NROM-128 (#0)
- Outer bank size 0, PRG mode 2 or 3, mirroring H or V, select $01
- NROM-256 (#0)
- Outer bank size 0, PRG mode 0, mirroring H or V, select $01
- CNROM (#3)
- Outer bank size 0, PRG mode 0, mirroring H or V, select $00
- BNROM (#34)
- Outer bank size 1-3, PRG mode 0, mirroring H or V, select $01
- BNROM oversize (#34 as emulated)
- Outer bank size 0, PRG mode 0, mirroring H or V, select $81, and modify bus-conflict-avoidance table for position within multicart
- UNROM (common) (#2)
- Outer bank size 1-3, PRG mode 3, mirroring H or V, select $01
- UNROM (Crazy Climber and MGC 2011) (#180)
- Outer bank size 1-3, PRG mode 2, mirroring H or V, select $01
- AOROM (#7)
- Outer bank size 1-3, PRG mode 0, mirroring 1-screen, select $01
Reference implementations
See /Reference implementations for functions in Python and 6502 assembly language that calculate the bank number output to PRG ROM A20-A14 as described above. These may be used to verify emulator or hardware implementations.
Verilog Code
- See /Verilog for an implementation designed for a CPLD.
Implementation notes
Input pins: 2 power, 16 signal
- Power and ground
- CPU D7, D5-D0 (D6 not currently used but may be used in future oversize versions)
- CPU A14-A12, /PRGSEL, M2, R/W
- PPU A12-A10
Output pins: 12 signal
- CHR RAM A14-A13
- CIRAM A10
- PRG ROM A20-A14, /CE
- Optional PRG RAM enable ($6000-$7FFF)
A CPLD requires at least one macrocell per bit of state, plus more macrocells for more complex operations. This mapper requires 20 bits of state, which leaves plenty of breathing room in a 36-cell CPLD for mapper logic.
- Register select: 2 bits
- Register $00: 2 bits (D4 is directed to register $80)
- Register $01: 4 bits (D4 is directed to register $80)
- Register $80: 6 bits
- Register $81: 6 bits
After synthesizing and laying fitting within a XC9536XL CPLD 27/36 Macrocells were consumed (75%). Additionally this design requires 25/34 available pins on the XC9536XL.
Adding WRAM control requires 2 Macrocells and 2 pins.
Lowering to 1MB by shaving off PRG ROM A20 would save 1 Macrocell and 1 pin, if desired.