Code: Select all
+---v---+
CPU A14 -> | 1 28| -- VCC
CPU A13 -> | 2 27| <- M2
CPU A12 -> | 3 26| <- CPU /ROMSEL
CPU A11 -> | 4 25| <- CPU R/!W
CPU A1 -> | 5 24| <- CPU D0
CPU A0 -> | 6 23| <- CPU D1
PPU A10 -> | 7 22| <- CPU D2
PPU A11 -> | 8 21| -- GND
OR A -> | 9 20| <- CPU D3
OR B -> |10 19| <- CPU D4
PRG A16 <- |11 18| <- CPU D5
PRG A15 <- |12 17| <- CPU D6
OR Y <- |13 16| <- CPU D7
GND -- |14 15| -> CIR A10
'-------'
UNNAMED
0.6" 40-pin PDIP
* Both GND pins are connected inside chip
* There is additional "AND component" when writing at $580x (see below for the
lut_and table). I guess why the Street Fighter IV works in emu without taking it
into account, maybe it only writes $00 to $4800? (for which "AND component" is $ff)?
* PRG/Mirroring register sits only at $4800-$4fff
* $4800.0 is PRG A16 and $4800.4 is PRG A15 (but since all ROM dumps follow the
opposite convention which matches current mapper description, it does not matter
* Additional unused OR gate inside chip, just like in VRC2 and SUNSOFT-4, probably
for decoding CHR-ROM chips
Code: Select all
| A15 A14 A13 A12 A11 A1 A0 |D~[76543210]
WR 4800-4fff | 0 1 0 0 1 * * | [..MP...P] PRG + MIR register
| | || +-PRG A16
| | |+-----PRG A15
| | +------CIRAM A10: 0=PPU A10, 1=PPU A11
-------------+---------------------------+--------------------------------------------------------------------------
WR 5000-57ff | 0 1 0 1 0 * * | [IIIIIIII] protection table index
-------------+---------------------------+--------------------------------------------------------------------------
WR 5800-5fff | 0 1 0 1 1 x y | [WWWWWWWW] 4 protection data write registers
| | ++++++++- when writing, the following value will be latched:
| | RRRRRRRR <= (WWWWWWWW & lut_and[IIIIIIII]) ^ lut_xor[IIIIIIII]
-------------+---------------------------+--------------------------------------------------------------------------
RD 5800-5fff | 0 1 0 1 1 x y | [RRRRRRRR] 4 protection data read registers
| |
6000-67ff | 0 1 1 0 0 * * | [........] - no effects on the above functionality
6800-6fff | 0 1 1 0 1 * * | [........] - no effects on the above functionality
7000-77ff | 0 1 1 1 0 * * | [........] - no effects on the above functionality
7800-7fff | 0 1 1 1 1 * * | [........] - no effects on the above functionality
-------------+---------------------------+--------------------------------------------------------------------------
implement this in programming language, it might be just easier (and faster)
to hard-code those arrays.
But when doing this mapper in FPGA, the more rational way is to use the logic
formulas that generate those arrays "(in = nth bit of i)"
Code: Select all
lut_xor[i] = 0.0..00.
| || +- (i7 & !i3) | (!i7 & !i6)
| |+---- (i4 & !i3) | (!i6 & !i4)
| +----- (!i6 & !i0) | (!i3 & i0)
+------- (!i6 & !i1) | (!i3 & i1)
lut_and[i] = 1.1..11.
| || +- (!i7 & !i6 & !i5) | (i7 & !i3 & !i2) | (!i7 & i6 & i5) | (i7 & i3 & i2)
| |+---- (!i6 & !i5 & !i4) | (i6 & i5 & !i4) | (i4 & !i3 & !i2) | (i4 & i3 & i2)
| +----- (!i6 & !i5 & !i0) | (i6 & i5 & !i0) | (!i3 & !i2 & i0) | (i3 & i2 & i0)
+------- (!i6 & !i5 & !i1) | (i6 & i5 & !i1) | (!i3 & !i2 & i1) | (i3 & i2 & i1)
Code: Select all
byte[] lut_xor = new byte[256]{
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01,
0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08,
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00,
0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
byte[] lut_and = new byte[256] {
0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xbf, 0xaf, 0xff, 0xef, 0xbf, 0xaf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf7, 0xe7, 0xb7, 0xa7, 0xf7, 0xe7, 0xb7, 0xa7, 0xff, 0xff, 0xff, 0xff,
0xa6, 0xb6, 0xe6, 0xf6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xb6, 0xe6, 0xf6,
0xae, 0xbe, 0xee, 0xfe, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xae, 0xbe, 0xee, 0xfe,
0xa6, 0xb6, 0xe6, 0xf6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xb6, 0xe6, 0xf6,
0xae, 0xbe, 0xee, 0xfe, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xae, 0xbe, 0xee, 0xfe,
0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xbf, 0xaf, 0xff, 0xef, 0xbf, 0xaf, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf7, 0xe7, 0xb7, 0xa7, 0xf7, 0xe7, 0xb7, 0xa7, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0xee, 0xbe, 0xae, 0xfe, 0xee, 0xbe, 0xae, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf6, 0xe6, 0xb6, 0xa6, 0xf6, 0xe6, 0xb6, 0xa6, 0xff, 0xff, 0xff, 0xff,
0xa7, 0xb7, 0xe7, 0xf7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa7, 0xb7, 0xe7, 0xf7,
0xaf, 0xbf, 0xef, 0xff, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xaf, 0xbf, 0xef, 0xff,
0xa7, 0xb7, 0xe7, 0xf7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa7, 0xb7, 0xe7, 0xf7,
0xaf, 0xbf, 0xef, 0xff, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xaf, 0xbf, 0xef, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0xee, 0xbe, 0xae, 0xfe, 0xee, 0xbe, 0xae, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf6, 0xe6, 0xb6, 0xa6, 0xf6, 0xe6, 0xb6, 0xa6, 0xff, 0xff, 0xff, 0xff,
};