Here are some of my notes from adding a "Free Play" option to Soccer Kings.
If you read my notes on Farfalla, this is a continuation of that effort.
Again, the first step is figuring out where everyhing is. Unlike the 2 x 2764, for this I had to go back to the schematics. Fortunately, it doesn't take long to work through the possible addresses and figure out which device is at what address.
Start Address | End Address | Device | Bank |
---|---|---|---|
0x0000 | 0x07FF | ROM1 | Bank 1 |
0x0800 | 0x0FFF | ROM2 | Bank 1 |
0x1000 | 0x17FF | ROM3 | Bank 1 |
0x1800 | 0x1FFF | RAM | (Mine) |
0x2000 | 0x27FF | ROM1 | Bank 2 |
0x2800 | 0x2FFF | ROM2 | Bank 2 |
0x3000 | 0x37FF | ROM3 | Bank 2 |
0x3800 | 0x3FFF | RAM | (Theirs) |
ROM 1 Bank 1 |
ROM 2 Bank 1 |
ROM 3 Bank 1 |
RAM (Mine) |
ROM 1 Bank 1 |
ROM 2 Bank 1 |
ROM 3 Bank 1 |
RAM (Theirs) |
0x0000 0x07FF |
0x0800 0x0FFF |
0x1000 0x17FF |
0x1800 0x1FFF |
0x2000 0x27FF |
0x2800 0x2FFF |
0x3000 0x37FF |
0x3800 0x3FFF |
The addresses 0x1800 0x1C00 0x3800 and 0x3C00 are all equivalent. In the hardware, they all end up at the same location (RAM). I'm used to using 0x1800 for the base of RAM.
dd bs=2048 count=1 if=cpurom1.bin of=Rom1Bank1 skip=0 dd bs=2048 count=1 if=cpurom1.bin of=Rom1Bank2 skip=1 dd bs=2048 count=1 if=cpurom2.bin of=Rom2Bank1 skip=0 dd bs=2048 count=1 if=cpurom2.bin of=Rom2Bank2 skip=1 dd bs=2048 count=1 if=cpurom3.bin of=Rom3Bank1 skip=0 dd bs=2048 count=1 if=cpurom3.bin of=Rom3Bank2 skip=1 dd bs=2048 count=1 if=/dev/zero of=RAM skip=0 cat Rom1Bank1 Rom2Bank1 Rom3Bank1 RAM Rom1Bank2 Rom2Bank2 Rom3Bank2 RAM > SoccerKings.bin
Hex dump of images does not reveal any free space.
Possibility: conversion to a 2x2764 setup. Re-arrange the image blocks to fit. If possible, this would also provide free space in the ROMs for hacking.
ROM 1 Bank 1 |
ROM 2 Bank 1 |
ROM 2 Bank 2 |
RAM (Mine) |
ROM 1 Bank 2 |
ROM 2 Bank 3 |
ROM 2 Bank 4 |
RAM (Theirs) |
ROM 1 Bank 3 |
Hole | ROM 1 Bank 4 |
Hole |
0x0000 0x07FF |
0x0800 0x0FFF |
0x1000 0x17FF |
0x1800 0x1FFF |
0x2000 0x27FF |
0x2800 0x2FFF |
0x3000 0x37FF |
0x3800 0x3FFF |
0x4000 0x47FF |
0x4800 0x4FFF |
0x6000 0x67FF |
0x6800 0x6FFF |
ROM 1 Bank 1 |
ROM 2 Bank 1 |
ROM 3 Bank 1 |
RAM (Mine) |
ROM 1 Bank 1 |
ROM 2 Bank 1 |
ROM 3 Bank 1 |
RAM (Theirs) |
0x0000 0x07FF |
0x0800 0x0FFF |
0x1000 0x17FF |
0x1800 0x1FFF |
0x2000 0x27FF |
0x2800 0x2FFF |
0x3000 0x37FF |
0x3800 0x3FFF |
ROM1 Bank1 - Stays the same (ROM1 Bank1)
ROM2 Bank1 - Stays the same (ROM2 Bank1)
ROM3 Bank1 - Moves to ROM2 Bank2
ROM1 Bank2 - Stays the same (ROM1 Bank2)
ROM2 Bank2 - Moves to ROM2 Bank3
ROM3 Bank2 - Moves to ROM2 Bank4
RAM - Stays at 1800 / 3800
Holes @ 4000 - 47FF, 4800 - 4FFF, 5000 - 57FF, 5800 - 5FFF, 6000 - 67FF, 6800 - 6FFF
ROM1 has free space.
ROM2 is full.
Put hacking code @ 6000, 6040 (ROM1 Bank4)
Credits are stored @ 0x1F22 in RAM (0x18)
Credits are also stored bit-flipped @ 0x1F4D (0xE7)
Setting 30 is stored @ 0x1F98 in RAM (0x00)
Setting 30 is also stored bit-flipped @ 0x1FC8 (0xFF)
Does not work. Game does not boot.
Have not figured out why the 3 x 2532 to 2 x 2764 image rearranging won't work. After two-pass disassembly of the ROMs, nothing is standing out as being a problem. RAM is being accessed at 0x1C00 in this game, but that maps down to the same as 0x1800 or 0x3800 as far as the hardware is concerned.
After several attempts to make sense of this, I abandoned the idea of making a 2 x 2764 Soccer Kings, at least for now. I may re-visit this idea later.
Some minor source code changes to the patches to shrink them slightly get them down to a total of 48 bytes of code + data.
There are 50 bytes of data at 0x2000 (0x0800 in ROM1) in the hex dump, most likely only used for the never-used feature of printing the audits on a serial printer.
00002000 43 4f 49 4e 53 20 23 20 50 4c 41 59 45 44 20 47 |COINS # PLAYED G| 00002010 57 49 4e 4e 45 44 20 47 53 4f 43 43 45 52 20 4b |WINNED GSOCCER K| 00002020 49 4e 47 20 53 53 45 52 49 41 4c 20 4e 20 30 37 |ING SSERIAL N 07| 00002030 33 30 20 cc 1c a7 05 00 3f 10 92 18 03 3f 24 3d |30 .....?....?$=| |
Using this space for code loses the ability to have a custom serial number and glamour space to put a URL in the image, but it might make for a much faster effort to get a Free Play ROM image that works, since it eliminates the need to rearrange the images in to larger ROMs to make space. Also might make this easier to do to other games in the future, since all of them have this same block of text.
Found credit decrement code. Is somewhat obscured in this ROM, unlike the simple plain code in Farfalla.
1154 : C8 FA strr,r0 *X1150 ; Credit decrement happens here. *1150 contains 0x1F22 credits address in RAM 12EC: loda r0 [0x1f22] ; Load credits value from RAM ... 12F6: A4 01 sub, r0 0x01 ; Credit decrement 12F8: 3F 11 54 bsta, 0x1154 ; Store updated credits |
Disables "Coin Meter" check
Patch [07 FF] to [07 00] @0x2B56 (ROM2 Bank2) 0x0B56 in ROM2 image
Disable credit = 0? check
Patch [0C 1F 22] to [1F 20 00] @0x12CA (ROM3 Bank1) 0x02CA in ROM3 image
Prevent credit decrement less than 0
Patch [A4 01] to [C0 C0] @0x12F6 (ROM3 Bank1) 0x02F6 in ROM3 image
Patch to [0C 1F 22] to [1F 20 18] @0x12EC (ROM3 Bank1) 0x02EC in ROM3 image
Patch1: ; (24 bytes) loda r0,[Setting30] ; Get value of setting 30 andi r0,#0x0F ; Strip off high order bits comi r0,#0x00 ; Is Setting 30 =?= 0 bctr .eq.,Patch1Done ; Yes: continue with original code lodi r0,#0x01 ; No: disable credit check bctr .un.,[Patch1Return] ; Return from patch Patch1Done: loda r0,[Credits] ; Original code bctr .un.,[Patch1Return] Patch1Return: .dw #0x12CD ; Return from patch Credits: .dw #0x3f22 ; Credits in RAM Setting30: .dw #0x1f98 ; Setting 30 in RAM |
Patch2: ; (25 bytes) loda r0,[Setting30] ; Get value of setting 30 andi r0,#0x0F ; Strip off high order bits comi r0,#0x00 ; Is Setting 30 =?= 0 bctr .eq.,Patch2Done ; Yes: continue with original code loda r0,[Credits] ; No: disable credit decrement below 0 bctr .gt.,Patch2Done ; Credit=0? – allow credit decrement bctr .un.,[Patch2Return] ; Return from patch Patch2Done: loda r0,[Credits] subi r0,#0x01 ; Decrement credits bctr .un.,[Patch2Return] ; Return from patch Patch2Return: .dw #0x12EF ; Return from patch |
Patch code in ROM1 @ 0x0800
00002000 0c 80 16 44 0f e4 00 18 04 04 01 1b 85 0c 80 14 |...D............| 00002010 1b 80 12 cd 3f 22 1f 0c 80 16 44 0f e4 00 18 07 |....?"....D.....| 00002020 0c 80 14 19 02 1b 87 0c 80 14 a4 01 1b 80 12 ef |................| |
Testing (PinMAME)
Disable of Coin Meter - patch works.
Credit Increment / Decrement - works.
Start (Credits > 0) - works
Start (Credits == 0) - does not work, game does not start
Bug found. In the FreePlay.asm source, the second patch ".org" statement was off by one byte. This overwrote the last byte of the first patch. The missing byte was the second half of the address of Setting 30 in RAM. So instead of reading the value for Setting 30, some other address was read, leading to wrong behaviour.
PinMAME tested - OK 12 February 2011
Game tested - OK 12 February 2011
David Gersic
Copyright © 2011. All rights reserved.
This document may be freely distributed so long as the content is not modified.