Soccer 6 in 1
Elements:
Chip signature:
27F080+27F080+AX5202P(MMC3)+16L8+7400 (not soldered)(7400)
PCB top:
PCB bottom:
Shell top:
Shell bottom:
Screenshoots:
Extra info:
JY-014 Soccer 6 in 1: Awkward cartridge
[url=https://obrazki.elektroda.pl/6688217100_1540473137.png][img]https://obrazki.elektroda.pl/6688217100_1540473137_thumb.jpg[/img][/url] [url=https://obrazki.elektroda.pl/1283810000_1564250837.jpg][img]https://obrazki.elektroda.pl/1283810000_1564250837_thumb.jpg[/img][/url] [url=https://obrazki.elektroda.pl/2697430600_1564250841.jpg][img]https://obrazki.elektroda.pl/2697430600_1564250841_thumb.jpg[/img][/url] [url=https://obrazki.elektroda.pl/2430508300_1564250845.jpg][img]https://obrazki.elektroda.pl/2430508300_1564250845_thumb.jpg[/img][/url] [url=https://obrazki.elektroda.pl/8977730400_1564250873.png][img]https://obrazki.elektroda.pl/8977730400_1564250873_thumb.jpg[/img][/url]
I got this one from MLX quite long time ago. I was trying to analyze it but the mapper seems to be strange and I did not get satisfying results.
It has 512kB PRG + 512kB CHR on-board, blob MMC3, PAL16L8, unpopulated 7400 and consists of the following games:
[code]
Game [original title] | MPR | PRG | CHR
-----------------------------------------------------------------+-------+------+-----
1. Tecmo Cup - Soccer Game | MMC1 | 128k | 128k
2. Goal 3 [Kunio Kun no Nekketsu Soccer League hack] | MMC3 | 128k | 128k
3. Goal 5 Soccer (Unl) | MMC3 | 64k | 64k
4. Heroes Soccer [Nekketsu Koukou Dodgeball Bu - Soccer Hen (J)] | MMC3 | 128k | 128k
5. Power Soccer | CNROM | 32k | 32k
6. Soccer | NROM | 32k | 8k
[/code]
* PRG-ROM's A13/A15/A16/A17/A18 and CHR-ROMS's A17/A18 are controlled by PAL
* PRG-ROM's A14 and CHR-ROM's A10-A16 are controlled by MMC3
* MMC3's_CPU_A14 is controlled by PAL which can change its behavior in certain mode
(for example - map something other than -2/-1 at $c000-$ffff)
[b]I desoldered the PAL for analysis and dumped the contents of the ROM, directly
providing values for the PRG address lines, so the dump is complete. However I am
unable to find out how exactly the mapper works.[/b]
https://anonymousfiles.io/r0sym6ml/
Here are my notes:
[code]
PAL16L8
,---v---.
CPU-!ROMSEL -> |01 20| -- VCC
MMC3-PRG-A15 -> |02 19| -> PRG-A15
MMC3-PRG-A16 -> |03 18| -> PRG-A16
CPU-A4 -> |04 17| -> PRG-A17
CPU-A5 -> |05 16| -> PRG-A18
MMC3-PRG-A13 -> |06 15| -> O3 (fedback)
CPU-A8 -> |07 14| -> PRG-A13
CPU-A13 -> |08 13| -> PRG-!OE
CPU-A14 -> |09 12| -> MMC3-CPU-A14
GND -- |10 11| <- CPU-R/!W
+-------+
Analyzing combinatorial outputs:
PRG_nOE <= (!CPU_A13 & CPU_nROMSEL) | (!CPU_A14 & CPU_nROMSEL) | (!CPU_RnW);
shows that PRG-ROM is enabled also at $6000 (no single game needs that,
but the menu code is ran from that region).
Because PAL does not take M2 into account so the PRG-/OE can be enabled when
M2 is low (when CPU address is not valid), ROM-/CE was meant to be inverted M2
(solder jumper selects between /ME and GND and because there is no 7400, it is choosen to be GND)
Analyzing latched outputs:
O3 <= '0' when (!CPU_RnW & !CPU_A13 & CPU_A8 & !CPU_nROMSEL) else
'1' when (!CPU_RnW & CPU_A13 & CPU_A8 & !CPU_nROMSEL);
PRG_A17 <= '0' when (!CPU_RnW & CPU_A8 & !CPU_A4 & !CPU_nROMSEL) else
'1' when (!CPU_RnW & CPU_A8 & CPU_A4 & !CPU_nROMSEL);
PRG_A18 <= '0' when (!CPU_RnW & CPU_A8 & !CPU_A5 & !CPU_nROMSEL) else
'1' when (!CPU_RnW & CPU_A8 & CPU_A5 & !CPU_nROMSEL);
shows that there are 3 bits being lathed, whose address overlap with mirrors
of the the regular MMC3 registers
fedc ba98 7654 3210
A~[1.u. ...1 ..vw ....]
| ||
| |+-- PRG-A17 = CHR-A17
| +--- PRG-A18 = CHR-A18
+------------- O3
---
Analyzing combinatorial outputs with feedback (PRG_A13)
PRG_A13 = (PRG_A17 & PRG_A18 & CPU_A13) |
(!PRG_A18 & MMC3_PRG_A13) |
(!PRG_A17 & MMC3_PRG_A13);
PRG_A18 PRG_A17 | PRG_A13
----------------+---------------
0 0 | = MMC_PRG_A13
0 1 | = MMC_PRG_A13
1 0 | = MMC_PRG_A13
1 1 | = CPU_A13
---
Analyzing combinatorial outputs with feedback (PRG_A14)
MMC3_CPU_A14 = (PRG_A17 & PRG_A18 & CPU_RnW & !CPU_A14 & !CPU_nROMSEL) |
(!CPU_RnW & CPU_A14) |
(!PRG_A18 & CPU_A14) |
(!PRG_A17 & CPU_A14) |
(CPU_A14 & CPU_nROMSEL);
shows that selection of outer bank (PRG_A18/PRG_A17) affects MMC3 behaviour:
behaviour for writes:
MMC3_CPU_A14 = CPU_A14 (that is all MMC3 regs are written normally)
behaviour for reads:
PRG_A18 PRG_A17 CPU_A14 CPU_!ROMSEL | MMC3_CPU_A14
------------------------------------+---------------
1 1 0 0 | 1
1 1 1 0 | 0
----------- otherwise ------------- | CPU_A14
so the standard MMC3 mapping
| $8000 | $a000 | $c000 | $e000 |
| $8001.R6 | $8001.R7 | -2 | -1 | (when $8000.6=0)
| -2 | $8001.R7 | $8001.R6 | -1 | (when $8000.6=1)
becomes
| -2 | -1 | $8001.R6 | $8001.R7 | (when $8000.6=0)
| $8001.R6 | -1 | -2 | $8001.R7 | (when $8000.6=1)
I was not able to automatically check PRG_A15/PRG_A16 behavior so I analyzed them manually:
Formula for PRG_A15
PRG_A18 PRG_A17 O3 |$6000 |$8000 |$a000 |$c000 |$e000 |
0 0 0 |0 |0 |0 |0 |0 |
0 0 1 |1 |1 |1 |1 |1 |
-------else------- |MMC3_PRG_A15|MMC3_PRG_A15|MMC3_PRG_A15|MMC3_PRG_A15|MMC3_PRG_A15|
(So O3 seems to be PRG_A15 when PRG_A18=0 and PRG_A17=0)
---
Formula for PRG_A16
PRG_A18 PRG_A17 O3 |$6000 |$8000 |$a000 |$c000 |$e000 |
0 0 * |- |MMC3_PRG_A16|MMC3_PRG_A16|- |- | (only reads latches)
------else-------- |MMC3_PRG_A16|MMC3_PRG_A16|MMC3_PRG_A16|MMC3_PRG_A16|MMC3_PRG_A16|
This is the only thing that I do not understand - the value of PAL output (PRG_A16)
is in fact a latch, which latches the MMC3_PRG_A16 when CPU_A14=0 and /ROMSEL edge falls
(when read from $8000-$bfff occurs) - I don't even know how to emulate that.
* All latched bits are set to 0 on powerup
[/code]
[url=https://obrazki.elektroda.pl/7430717400_1564250460.png][img]https://obrazki.elektroda.pl/7430717400_1564250460_thumb.jpg[/img][/url]
Suming up:
pppp - value set in MMC3 PRG bank0 ($8001.R6)
qqqq - value set in MMC3 PRG bank1 ($8001.R7)
u,v,w - additional latched bits:
fedc ba98 7654 3210
A~[1.u. ...1 ..vw ....]
L - either P
PRG:
------when mmc3's $8000.6 = 0-------- --$8000.6 = 1 --
vw $6000 $8000 $a000 $c000 $e000 | $8000 $c000
00 vwLu11 vwpupp vwquqq vwLu10 vwLu11 | vw1u10 vw*upp
01/10 vw1111 vwpppp vwqqqq vw1110 vw1111 | vw1110 vwpppp
11 vw1111 vw1110 vw1111 vwppp0 vwqqq1 | vwppp0 vw1110
CHR:
works normally, just vw select outer 128kb block
PRG_A16 <= MMC3_PRG_A16 when CPU_NROMSEL=0 and CPU_RNW=1 and CPU_A14 = 0 and PRG_A18 = 0 and PRG_A17 = 0 else --latch
MMC3_PRG_A16 when PRG_A18 = 0 and PRG_A17 = 1 else
MMC3_PRG_A16 when PRG_A18 = 1 and PRG_A17 = 0 else
MMC3_PRG_A16 when PRG_A18 = 1 and PRG_A17 = 1
PRG_A15 <= 0 when PRG_A18 = 0 and PRG_A17 = 0 and O3 = 0 else
0 when PRG_A18 = 0 and PRG_A17 = 0 and O3 = 1 and CPU_NROMSEL = 1 and CPU_A14 = 1 and CPU_A13 = 1 and CPU_rNW = 1 else
1 when PRG_A18 = 0 and PRG_A17 = 0 and O3 = 1 and CPU_NROMSEL = 0 and cpu_rNW = 1 else
O3 PRG-A18 PRG-A17 MMC3_PRG_A16 !ROMSEL CPU-A14 CPU-A13 | PRG_A16
0 0 0 0 x x x | 0
0 0 0 1 x x x | 1
PRG_A18 | PRG_A17 | PRG_A13
--------+---------+--------
0 0 = MMC3_PRG_A13
0 1 = MMC3_PRG_A13
1 0 = MMC3_PRG_A13
1 1 = CPU_A13
What is left to do is
PRG_A15 = (!PRG_A17 & !PRG_A18 & O3 & CPU_A14 & !CPU_nROMSEL) |
(!PRG_A17 & !PRG_A18 & O3 & !CPU_A14 & !MMC3_PRG_A16) |
(!PRG_A17 & !PRG_A18 & O3 & CPU_A14 & !CPU_A13) |
(PRG_A17 & MMC3_PRG_A15 & !CPU_nROMSEL) |
(PRG_A18 & MMC3_PRG_A15 & !CPU_nROMSEL) |
(PRG_A17 & !CPU_A13 & MMC3_PRG_A15) |
(PRG_A18 & !CPU_A13 & MMC3_PRG_A15) |
(PRG_A17 & !CPU_A14 & MMC3_PRG_A15) |
(PRG_A18 & !CPU_A14 & MMC3_PRG_A15) |
(!CPU_A14 & MMC3_PRG_A16 & MMC3_PRG_A15);
PRG_A15 = (!PRG_A17 & !PRG_A18 & O3 & CPU_A14 & !CPU_nROMSEL) |
(!PRG_A17 & !PRG_A18 & O3 & !CPU_A14 & !MMC3_PRG_A16) |
(!PRG_A17 & !PRG_A18 & O3 & !CPU_RnW) |
(!PRG_A17 & !PRG_A18 & O3 & CPU_A14 & !CPU_A13) |
(PRG_A17 & MMC3_PRG_A15 & !CPU_nROMSEL) |
(PRG_A18 & MMC3_PRG_A15 & !CPU_nROMSEL) |
(PRG_A17 & !CPU_A13 & MMC3_PRG_A15) |
(PRG_A18 & !CPU_A13 & MMC3_PRG_A15) |
(PRG_A17 & !CPU_A14 & MMC3_PRG_A15) |
(PRG_A18 & !CPU_A14 & MMC3_PRG_A15) |
(PRG_A17 & !CPU_RnW & MMC3_PRG_A15) |
(PRG_A18 & !CPU_RnW & MMC3_PRG_A15) |
(CPU_RnW & !CPU_A14 & MMC3_PRG_A16 & MMC3_PRG_A15);
;manual analysis
PRG_A15 <= '0' when (PRG_A17 | PRG_A18) & RnW & CPU_nROMSEL & CPU_A13 & CPU_A14 else
MMC5_PRG_A15 when (PRG_A17 | PRG_A18) & (!RnW | !CPU_nROMSEL | !CPU_A13 & !CPU_A14)) else
'0' when !PRG_A17 & !PRG_A18 & O3 & CPU_A13 & CPU_A14 & CPU_RnW & CPU_nROMSEL else
'1' when !PRG_A17 & !PRG_A18 & O3 & (!CPU_A13 | !CPU_A14 | !CPU_RnW | !CPU_nROMSEL)
;analyze as feedb with r/w=1
PRG_A16 = (!CPU_A14 & MMC3_PRG_A16) |
(PRG_A17 & MMC3_PRG_A16) |
(PRG_A18 & MMC3_PRG_A16);
;analyze as feedb with a8=0
PRG_A16 = (CPU_RnW & !CPU_A14 & MMC3_PRG_A16) |
(PRG_A17 & MMC3_PRG_A16) |
(PRG_A18 & MMC3_PRG_A16);
;correct
PRG_A16 = MMC_PRG_A16 when PRG_A17 = '1' else
MMC_PRG_A16 when PRG_A18 = '1' else
MMC_PRG_A16 when PRG_A17 = '0' and PRG_A18 = '0' and CPU_nROMSEl = '0' & RnW = '1' & A14='0'
--------------------analysis--------------------------------------------------
CPU_RnW CPU_nROMSEL CPU_A14 CPU_A13 | PRG_nOE
0 x x x | 1
1 0 x x | 0
1 1 0 0 | 1
1 1 0 1 | 1
1 1 1 0 | 1
1 1 1 1 | 0
CPU_RnW CPU_nROMSEL CPU_A14 CPU_A13 CPU_A8 CPU_A5 CPU_A4 | comment adr
0 0 x 0/1 1 x x | O3 <= 0/1 $8100/$A100 (mask: $A100)
0 0 x x 1 x 0/1 | PRG_A17 <= 0/1 $8100/$8110 (mask: $8110)
0 0 x x 1 0/1 x | PRG_A18 <= 0/1 $8100/$8120 (mask: $8120)
PRG_A18 PRG_A17 O3 CPU_nROMSEL CPU_A14 CPU_A13 |
0 0 x x 1 x PRG_A16 <= 0 (else controlled by MMC3)
1 1 x x x 0/1 PRG_A13 <= CPU_A13 (else controlled by MMC3)
It is regular MMC3 (with PRG-ROM at $6000-$7fff) and a few exceptions:
On powerup: PRG0=$f, PRG1=$f, OUTMODE=$0
OUTMODE| $6000 | $8000 | $a000 | $c000 | $e000 |
-------+---------+---------+---------+---------+---------+
0| $3 | f1(PRG0)| f1(PRG1)| $2 | $3 |
1| $b | PRG0 | PRG1 | $e | $f |
2| $b | PRG0 | PRG1 | $e | $f |
3| $b | $e | $f | f2(PRG0)| f3(PRG1)|
4| $3 | f4(PRG0)| f4(PRG1)| $6 | $7 |
5| $b | PRG0 | PRG1 | $e | $f |
6| $b | PRG0 | PRG1 | $e | $f |
7| $b | $e | $f | f2(PRG0)| f3(PRG1)|
0| $3 | $e | f1(PRG1)| f5(PRG0)| $3 |
1| $b | $e | PRG1 | PRG0 | $f |
2| $b | $e | PRG1 | PRG0 | $f |
3| $b | f2(PRG0)| $f | $e | f3(PRG1)|
4| $3 | $e | f4(PRG1)| f6(PRG0)| $7 |
5| $b | $e | PRG1 | PRG0 | $f |
6| $b | $e | PRG1 | PRG0 | $f |
7| $b | f2(PRG0)| $f | $e | f3(PRG1)|
first half is when PRG swapping in MMC is disabled, second when enabled
f1 = 0=>0 1=>1 2=>2 3=>3 4=>0 5=>1 6=>2 7=>3 8=>8 9=>9 a=>a b=>b c=>c d=>d e=>e f=>f
f2 = 0=>0 1=>0 2=>2 3=>2 4=>4 5=>4 6=>6 7=>6 8=>8 9=>8 a=>a b=>a c=>c d=>c e=>e f=>e
f3 = 0=>1 1=>1 2=>3 3=>3 4=>5 5=>5 6=>7 7=>7 8=>9 9=>9 a=>b b=>b c=>d d=>d e=>f f=>f
f4 = 0=>4 1=>5 2=>6 3=>7 4=>4 5=>5 6=>6 7=>7 8=>8 9=>9 a=>a b=>b c=>c d=>d e=>e f=>f
f5 = 0=>0 1=>1 2=>2 3=>3 4=>0 5=>1 6=>2 7=>3 8=>0 9=>1 a=>2 b=>3 c=>0 d=>1 e=>2 f=>3
f6 = 0=>4 1=>5 2=>6 3=>7 4=>4 5=>5 6=>6 7=>7 8=>4 9=>5 a=>6 b=>7 c=>4 d=>5 e=>6 f=>7
Comments:
Want to leave a comment?