Notes on the Sega MS/GG Clone ASIC (it really needs a proper name!) by viletim Preface In late 2006 a few game consoles started to appear on the market, boasting of built-in 8-bit Sega games. Available as portable systems, plug 'n' play consoles, and built into other gadgets (DVD/MP3 players) and sold under names such as Coleco, Playpal, Fungear, British Airways. It appears they all contain a Sega Master System/Game Gear condensed onto a tiny custom chip (ASIC). I've managed to get ahold of a Coleco 20 in 1 portable system containing this chip. This document is an attempt to document how this chip works, especially the extra peripheral features not present on standard 8 bit Sega hardware. Modifying The Loader Menu Software So far the built-in games on these devices could hardly be considered to be 'best of 8-bit Sega games' compilations. Something like 'cheapest to licence plus lots of Sonic' compilations would be a more accurate description. This section should provide enough information for someone with a flash programmer and a hex editor to change the software. There are several different versions of the loader software on various different devices. This section is specifically about the software of the Coleco 20 in 1 portable (coleco_loader.bin) which I presume will work OK if loaded onto other devices (such as the Playpal). I have examined the data structure of another software variation and it appears to be very similar (though without the extra blank 'spacer' entry) The Loader's data area starts at $96E and contains information about each game such as title, size, type, and video properties (scaling, etc). It does not contain any information about the data itself so the quantity and order of the games can't be altered. The data area consists of 20 entries each containing information about a game and how it should be displayed on a TV, then a blank entry, then another 20 entries which are almost identical to the first 20 except the data designates how the game should be displayed on the internal LCD. Each entry is 50 bytes in length so the total data area is (41 entries * 50 bytes) 2050 bytes in size. Text data from the first 20 entries is used for titles regardless of whether the display is TV or LCD. One entry is made up of the following: $00-1F: Contains text which appears on the main menu. Text is restricted to alphanumeric ASCII and must end with a $00 (null). Any data in the text area which follows a null byte is ignored. $20-21: Size of the game / 1024. Little Endean byte order. For example, a 32Kbyte game would be $2000, and a 512Kbyte game $0002. $22: This byte is loaded into port $A0. Possibly related to audio sub-system? Typical value is $07 but often $02-06 is also used. $23: Port $62 is read, OR'd with this byte and written back to port $62. I'm not sure why this would ever be required. $23: Port $8C is read, OR'd with this byte and written back to port $8C. $25: If not zero it's loaded into $3FFA. Unknown purpose. $26: If not zero it's loaded into $3FFB. Unknown purpose. $27: If not zero it's loaded into $3FFC. Unknown purpose. $28: If not $FF it's loaded into $3FFE. Unknown purpose. $26: OR'd with $85 then loaded into $3FFE. Unknown purpose. $2A: Loaded into port $90. It specifies which part of the ROM the game is located. It should be $00 for programs located in $000000-1FFFFF, $08 for $200000-3FFFFF, $80 for $400000-5FFFFF, and $88 for $600000-7FFFFF. $2B: If bit 7 of this byte = 1 then port $88 is read, AND'd with this byte and written back to port $88. If bit 7 of this byte = 0 then $80 is written to port $88. Typical values are: $FF - Game Gear game, $7F - Master system game with video filter enabled (most common), $5F MS game with video filter disabled. $2C: Loaded into port $8D. Used to set up the video scaler (stretcher). Typical values are: $47 for a GG game on TV (fills ~90% of the screen), $29 for a GG game on LCD, $05 for a MS game on TV (full screen, not scaled), and $56 for a MS game on LCD. $2D: Loaded into port $8E. There's no reason for this to be anything other than $00. $2E: Loaded into port $8F. Horizontal position. Typical values: $B6 for a GG game on TV, $06 for a GG game on LCD, $80 for a MS game on TV, and $11 for a MS game on LCD. $2F: Loaded into port $63. Vertical position. Typical values: $1C for a GG game on TV, $2A for GG game on LCD, $00 for a MS game on TV, and $19 for a MS game on LCD. $30-31: Unused. Don't Touch $DF! Writes to port $DF are not allowed! Some early SMS games write to this port during the initialisation of the program. Such games must be modified by having the offending opcodes replaced with $00 (nop). Failure to do so will usually result it the system locking up. A Better Solution? Interestingly, there is a bit in port $8C (bit 7) that when set, disables all non-standard (special) ports, including $DF. It seems setting this bit has some kind of built-in delay mechanism. For example, if I was to run some software that set bit $8C/7 and immediately (or relatively shortly, as is the case in a game's initialisation routines) afterwards tried to write to $DF I would succeed and lock up the system. However, If I were to modify the software to wait for the press of a button before writing to $DF (or any other special port) then nothing would happen. The mystery of $3FF9-3FFF There is, without a doubt, something attached to this CPU address space aside from ROM. The loader has (optional) data to be loaded directly into $3FFA, $3FFB, $3FFC, and $3FFE. However, the only games which really take advantage of this are Sonic Triple Trouble, Sonic Chaos, and Ristar. My (totally wild) guess is that they have something to do with game paging IC emulation. How Banking Works (how the menu software jumps to the ROM location) It's pretty simple really, all that's required is the address loaded into ports $61, $62, and $90. Then set bit 4 of port $C8 and you're dumped at the specified address. As far as I can work out this is a 'one shot' mechanism, once you've set bit 4 of C8 there's no way to unset it without locking the system up. The way the address data is arranged into $61/$62/$90 is as follows. The address first divided by 256 then least significant byte of the result is loaded into $61. The most significant byte is split into two parts, bits 0-4 are loaded into port $62 (for some reason the loader software reads this port first and preserves the three most significant bits - perhaps they serve some other purpose?) and bits 5-6 converted for port $90. There are only four useful values than can be written to port $90, they are: $00, $08, $80, and $88, which are for address ranges $000000-1FFFFF, $200000-3FFFFF, $400000-5FFFFF, and $600000-7FFFFF respectively. The amount of available address lines limit the maximum ROM size to 64Mb. Special (those not found on MS/GG) IO Ports, Options $88: 76543210 ||||\||`- Video standard? |||| |`-- Frame rate. 0 = 60Hz 1 = 50Hz |||| `--- Black level adjust. |||`----- Sync enable. 0 = on. ||`------ Enable some kind of video filter...Possibly a luma trap? |`------- ? `-------- Colour palette and screen size. 0 = MS 1 = Game Gear. $89: 76543210 |||||||`- ? ||||||`-- ? If this bit is cleared the LCD stops working... |||||`--- ? ||||`---- ? |||`----- ? ||`------ ? |`------- 50/60 Hz palette correction? 0 = 60Hz 1 = 50Hz `-------- Video standard? Bits 0, 2-7 have no effect on the internal LCD. Video system: | 89/7 | 89/6 | 88/1 | 88/0 | | 0 | 0 | 0 | 0 | NTSC-60 | 1 | 0 | 0 | 0 | PAL-60 | 0 | 1 | 1 | 0 | PAL-50 | 1 | 1 | 1 | 0 | NTSC-50 These are just guesses based on looking at the signal with a CRO and what my TV's on-screen display tells me. Both $88/0 and $89/7 seem to play some role in setting the video standard but I don't have the equipment required to determine exactly what part of the video signal they change. I think the above table should be good enough. $8A: 76543210 ||||\__| |||| `-- Chrominance subcarrier adjustment (frequency? phase?) |||| |||| |||`----- ? ||`------ ? |`------- ? `-------- ? $8B: ? $8C: 76543210 ||||\__| |||| `- Palette adjustment? |||`----- Bank switching. Set this bit to jump to address in ||| ports $61/$62/$90. ||`------ ? Changes value read from ports $91/$DE/$DF |`------- Colour palette. 0 = MS 1 = GG (with MS screen size). `-------- When this bit is set all 'special' ports become read-only. Special Ports Related To Video Position/Scaling $63: Vertical position. $8D: Scaling/stretching. High nibble for vertical. Low nibble for horiz. $8E: Active vertical screen area. Totally useless. $8F: High nibble for horizontal position. Low nibble for horizontal screen area. Special Ports, More Of Them! $90: Writes to this port relate to banking (see above). Value read is $3F if started with TV plugged in, changes to $C0 if TV is unplugged (does not change back to $3F if reconnected to the TV). $91: ? $92: ? $93: ? Reads: bit 2 = 0 when TV plugged in, 1 when it is not. $A0: I'm still trying to work out exactly what it's for. Test with My Hero: When set to $00 the game played several times slower than normal, however the music played at normal speed. When set to $0F the game played at normal speed but many sprites looked corrupted and the game often lost/distorted the music, locked up, and restarted. Games typically write $02-07 to this port. Using My Hero as a test subject I was unable to see any difference between the values $03 and $07. $A1: Somehow related to audio system. I can hear tones and noise as I toggle the bits. $A2: ? $A3: ? $A4: ? $A5: ? $C8: ? When bit 1 is set both audio and video output are disabled. $DE: ? $DF: I don't know what is for but a write to this port usually results in lock up or something else undesirable. This is unfortunate because many early SMS games write to this port in an attempt to detect the Mark III keyboard accessory (or something like that). Change Log 2/7/07 - Released.