Team CAPS0ff recently devised a way to dump the internal EPROM from the Taito ‘c-chip’ protection modules
The TC0030CMD aka ‘c-chip’ is a custom Taito module which integrates a UPD78C11, RAM, ROM and a custom ASIC into a single package and was used to protect a number of Taito games in the late 80s / early 90s. It was, to my knowledge, the only time Taito used a custom package like this rather than simply using an off-the-shelf MCU directly.
CAPS0ff had previously managed to dump the UPD78C11 part of the c-chip (which is a common kernel shared by all the c-chips) using optical techniques, basically decapping the chip, imaging the ROM area (which could be done because the internal ROM of the UPD78C11 is a MASK rom) and entering the data manually. That was done some months ago, and to the best of our knowledge was correctly dumped as the internal checksum it does at least matches without any special fudging being needed.
Dumping of the EPROM part required more thought, it couldn’t be done with the same technique as it isn’t a MASK rom so in the end a new way was found, hooking up the ROM die directly and dumping it after some very fine / delicate work. You can read all about that on the Team CAPS0ff blog.
The c-chip does several things for the games on which it is used. Firstly it manages the player inputs and some of the other system inputs, reading them and putting them in a shared RAM area for the 68k-side game code to read. One slightly odd quirk is that one of the digital ports is read through the ADC (Analog to Digital) port of the UPD78C11 which is an incredibly inefficient way of doing things. In most cases this port is used for the Player 2 cocktail mode controls.
The most important function of the c-chip, as with any good protection scheme is providing per-game protection functions that are tightly integrated with the actual game logic. Taito made use of this to varying extents across the games using it.
Bonze Adventure has had issues in MAME for the entire time it has been emulated, with all of these coming due to various inaccuracies in the c-chip simulation. One of the main things the c-chip handles comes in the form of the restart positions when the player dies. The game code passes in the current co-ordinates and expects to get back the correct restart position for those co-ordinates. Failure to return the correct values results in the game crashing.
While the return values used by the simulation in MAME had been extracted from a running PCB there was still something clearly wrong with the simulation, like some coordinates had been missed, or there were flaws in the algorithm. Maybe this isn’t too surprising as the game is full of secret locations, and the actual restart positions are sometimes slightly illogical (sometimes skipping ahead, rather than backwards – depending more on which restart position you’re closest too, rather than which one you’ve passed)
Either way, this left MAME users with a choice of using an older version of MAME with guessed / inaccurate restart positions that didn’t outright crash, but could be glitched quite easily, or a newer version, with verified coordinates that for other reasons didn’t work (or hacked up builds that partially restored the old behavior) None of the emulated solutions were actually correct, even the PS2 Taito Legends port was incorrect because that was based off the same knowledge MAME had at the time.
Using the correct dump of the original c-chip all these problems go away, and the game now has correct restart points, and won’t crash if you die in the secret locations etc.
Due to historical significance of the game as part of the Bubble Bobble series, this was possibly one of the most important c-chips so having it dumped is a huge milestone even if end users might not notice a huge difference here.
Rainbow Islands is one of the most extensively protected c-chip games but also one where the simulation was already very good thanks to tireless work by a couple of people who were big fans of the game. Having extensively studied the behavior of the chip over the years, and extracted the various data tables from it already it’s fair to say the game was already very well emulated.
Very well emulated isn’t the same thing as correctly emulated however. Even with the extensive studies of the c-chip responses that had been done there was still some guesswork, of note in the generation of the y coordinates at goal-in where the random number generation was not understood and a simple table of observed values substituted for the real algorithm.
By running the real c-chip code the need to understand this goes away (although it would now be possible to analyze the c-chip program and work out what the real algorithm was) The beauty of hooking up the real protection MCUs in cases like this is that things ‘just work’ because you’re simply running the correct code, not having to simulate anything. This also allows for extensive cleanups of the MAME code as simulations of complex ‘black-box’ style protection devices inevitably end up being large and unwieldy as a well programmed MCU can do a lot of work for the game. Being able to simply delete those simulations and know the original code is being emulated instead is a big boost for the project, and for preservation in general.
Rainbow Islands is an interesting case because it did spawn a bootleg, Jumping, on which some of the earlier protection simulations in MAME (and RAINE) were based prior to the more extensive studies that I previously mentioned. While the bootleggers had managed to work around the protection, they hadn’t got it right as beyond surface level there were many, many problems with the hacks the bootleggers had used to work around the protection in Jumping making it a much less desirable product. Despite this bootleg existing, it shows what a good job Taito did of the protection.
Rainbow Islands Extra
This semi-sequel of Rainbow Islands uses a different c-chip to Rainbow Islands. This c-chip isn’t actually dumped yet (and needs to be) but in the meantime I’ve applied the differences in the simulation code to the Rainbow Islands MCU so that it still runs using a fake c-chip ROM. Maybe the real one actually holds more secrets, maybe the real one has the actual MCU code tidied up a bit (as it looked to me like there were some unused tables in the Rainbow Islands MCU) In the meantime there’s not much to say about this, it’s the same basic protection Rainbow Islands but with different data due to the rearranged levels.
Personally I’ve never really seen the point of Rainbow Islands Extra, it feels more like a cheap hack, none of the remixed levels really make any sense and it loses most of the charm of the original by starting you off on a very dull looking level.
This one was dumped by CAPS0ff, allowing the real behavior to be studied, and differences between the simulation and proper emulation to be observed.
While Superman is not the best protected of the C-Chip games, and doesn’t tie any critical game logic to c-chip responses it does make the c-chip responsible for passing a chunk of 68k code back to the main CPU, this code is used to manage the sound command buffers in the game.
The previous simulation of the c-chip returned this code for the 68k CPU, it was accompanied in the MAME source by the comment “This code for sound communication is a hack, it will not be identical to the code derived from the real c-chip”
F01B20: 48E7 8080 movem.l D0/A0, -(A7)
F01B24: 206D 1C40 movea.l ($1c40,A5), A0
F01B28: 302F 000C move.w ($c,A7), D0
F01B2C: 1080 move.b D0, (A0)
F01B2E: 5288 addq.l #1, A0
F01B30: 203C 00F0 1C40 move.l #$f01c40, D0
F01B36: B1C0 cmpa.l D0, A0
F01B38: 6604 bne $f01b3e
F01B3A: 41ED 1C20 lea ($1c20,A5), A0
F01B3E: 2B48 1C40 move.l A0, ($1c40,A5)
F01B42: 4CDF 0101 movem.l (A7)+, D0/A0
F01B46: 4E75 rts
With the real c-chip emulated we can see that the above statement if indeed true, because the actual 68k routine supplied by the original c-chip looks like this.
F01B20: 4E56 0000 link A6, #$0
F01B24: 48E7 0100 movem.l D7, -(A7)
F01B28: 3E2E 0008 move.w ($8,A6), D7
F01B2C: 0C07 00FF cmpi.b #-$1, D7
F01B30: 6742 beq $f01b74
F01B32: 0C6D 0003 1CCA cmpi.w #$3, ($1cca,A5)
F01B38: 660E bne $f01b48
F01B3A: 082D 0003 1C4B btst #$3, ($1c4b,A5)
F01B40: 6606 bne $f01b48
F01B42: 0C07 0019 cmpi.b #$19, D7
F01B46: 662C bne $f01b74
F01B48: 48E7 0080 movem.l A0, -(A7)
F01B4C: 206D 1C40 movea.l ($1c40,A5), A0
F01B50: 10C7 move.b D7, (A0)+
F01B52: 2E3C 00F0 1C40 move.l #$f01c40, D7
F01B58: B1C7 cmpa.l D7, A0
F01B5A: 6606 bne $f01b62
F01B5C: 41ED 1C20 lea ($1c20,A5), A0
F01B60: 600A bra $f01b6c
F01B62: 2E2D 1C44 move.l ($1c44,A5), D7
F01B66: B1C7 cmpa.l D7, A0
F01B68: 6602 bne $f01b6c
F01B6A: 5388 subq.l #1, A0
F01B6C: 2B48 1C40 move.l A0, ($1c40,A5)
F01B70: 4CDF 0100 movem.l (A7)+, A0
F01B74: 4CDF 0080 movem.l (A7)+, D7
F01B78: 4E5E unlk A6
F01B7A: 4E75 rts
Superman also has a second block of 68k code supplied by the C-Chip, but from what I can tell there are no jumps to it from the main code, so it is probably a leftover from development.
F01B80: 4E56 0000 link A6, #$0
F01B84: 3F3C 0007 move.w #$7, -(A7)
F01B88: 4EBA FF32 jsr (-$ce,PC) ; ($f01abc)
F01B8C: DFFC 0000 0002 adda.l #$2, A7
F01B92: 48E7 80C0 movem.l D0/A0-A1, -(A7)
F01B96: 41F9 0090 0001 lea $900001.l, A0
F01B9C: 302E 0008 move.w ($8,A6), D0
F01BA0: 1140 0000 move.b D0, ($0,A0)
F01BA4: 4228 0002 clr.b ($2,A0)
F01BA8: 302E 000A move.w ($a,A6), D0
F01BAC: 1140 0004 move.b D0, ($4,A0)
F01BB0: 4E45 trap #$5
F01BB2: 3F3C 0007 move.w #$7, -(A7)
F01BB6: 4EBA FF04 jsr (-$fc,PC) ; ($f01abc)
F01BBA: DFFC 0000 0002 adda.l #$2, A7
F01BC0: 4A28 0002 tst.b ($2,A0)
F01BC4: 67EA beq $f01bb0
F01BC6: 3F2E 0008 move.w ($8,A6), -(A7)
F01BCA: 4EBA FEF0 jsr (-$110,PC) ; ($f01abc)
F01BCE: DFFC 0000 0002 adda.l #$2, A7
F01BD4: 1E28 0000 move.b ($0,A0), D7
F01BD8: E14F lsl.w #8, D7
F01BDA: 1E28 0002 move.b ($2,A0), D7
F01BDE: 41E8 0004 lea ($4,A0), A0
F01BE2: 226E 000C movea.l ($c,A6), A1
F01BE6: 1010 move.b (A0), D0
F01BE8: 12C0 move.b D0, (A1)+
F01BEA: D0FC 0002 adda.w #$2, A0
F01BEE: 51CF FFF6 dbra D7, $f01be6
F01BF2: 4CDF 0301 movem.l (A7)+, D0/A0-A1
F01BF6: 4E75 rts
As you can see, the real sound communication code is somewhat more complex than the fake code that was being used. Of note, it actually checks the status of the Demo Sound dipswitch (stored in RAM) and doesn’t pass on sound commands in attract mode if Demo Sounds are disabled, the fake code completely ignored that. The check of ‘
F01B3A: 082D 0003 1C4B btst #$3, ($1c4b,A5)‘ is where the real code is checking the dipswitch value in RAM while ‘
cmpi.w #$3, ($1cca,A5)‘ is checking if the game is in gameplay or attract mode (4 is gameplay, 3 is attract mode) There are also other subtle differences in the way the sound commands are handled. Maybe having the Demo Sound dipswitch behave the same as real hardware isn’t the biggest piece of news but it’s one of those small accuracy things that is good to know is now correct. I haven’t tried to work out the point of the apparently unused code, or when it would be called.
Like all the other games the c-chip is also directly responsible for handling inputs and putting them in shared RAM. The previous simulation just shoved them directly into RAM.
This is another one that has been dumped by CAPS0ff and is now fully emulated. The Volfied protection sits somewhere in the middle of the others, supplying palette data for enemies, and managing a few counters (eg for ensuring an enemy attacks you when your shield runs out) It isn’t an especially interesting protection, but some of the behavior it has wasn’t 100% obvious or trusted prior to having the proper c-chip dump.
The Volfied emulation still seems to have some other timing issues even with the c-chip emulated, because the 2nd attract mode how to play sequence does not appear to complete correctly, there are unused messages telling the player that the enemy gets smaller as you box it in which aren’t triggered because the player dies too early. The actual behavior needs verifying on the PCB and I suspect is related to some video flags, not the c-chip. Having the real c-chip dump and emulation at least allows us to 100% rule out that being some kind of subtle c-chip related behavior.
The Operation Wolf c-chip is not yet dumped. Bryan McPhail has sent one for processing, and considering the amount of research he has done over the years to improve the simulation of it I’m sure he’ll be very interested in seeing what the real code has to offer. Operation Wolf appears to be the first, and most heavily protected of the c-chip games with many small details of the game logic being tied to protection functions. It took many, many years for the simulation to be any good at all, I definitely suggest reading Bryan’s blog for more information about that. Once this one is dumped all that simulation code can be cleaned up. Chances are Bryan will be the one to hook this up when it gets dumped because given the amount of work he’s put in over the years, and also it being his chip being sent for processing, it just kinda makes sense if he is the first one to look at it.
I guess the interesting sub-note for Operation Wolf so far is that the UPD78C11 part of the dump we have actually came from an Operation Wolf c-chip, and we do have a partial dump of the EPROM from another Operation Wolf c-chip (missing half the code / data) but both of those were casualties in the process of figuring out how to dump these properly.
Operation Wolf is also historically significant because it was bootlegged back in the day, however the bootleggers chose to use a Z80 to simulate the behavior of the c-chip. This resulted in a lot of incorrect assumptions that the original c-chips were Z80s and the bootleggers had managed to extract the code. Truth be told the bootleggers had simply tried their best to analyze the protection behavior and recreate it, much as the emulation developers had. The Z80 code, one studied actually turned out to be full of bugs and incorrect behaviors. Rumours did however still persist that the c-chip was a Z80 due to this until the very day it was actually decapped and proven not to be.
The Mega Blast c-chip is also not dumped yet, although it might well be blank or recycled from another game. It would be fair to say that the C-Chip on Mega Blast exists for decoration, it isn’t used beyond the startup check. Once the command to jump out of the MASK rom area of the UPD78C11 and into the EPROM has been sent no further commands are sent to the C-chip, and no accesses are done to the shared region, the game doesn’t even read the inputs through the c-chip. As long as the c-chip RAM works, and it returns the correct value for having passed the UPD78C11 MASK rom checksum the game will run. It’s literally used for nothing. CAPS0ff do currently have a Mega Blast chip, and will eventually dump it, at which point we’ll see if it is indeed blank, from another game, or maybe even contains protection code that Taito never got around to hooking up, or that might have been used on an earlier / unreleased version of the game but ultimately ended up being disabled because there were problems with it. It’s definitely the least interesting of the c-chip games on the surface (because it doesn’t even make use of it) but if it holds some secrets / tells a forgotten story of development it does still have the potential to be one of the more interesting ones for the arcade archaeologist.
Even with all this done there are a few things we don’t fully understand about the c-chip, but as far as the protection functions go they’re not important. One thing of note is that the internal UPD78C11 code actually includes an additional mode of operation not triggered by any of the games. This mode includes various diagnosis features that we were hoping could be used to dump the EPROMs without having to resort to the physical attack CAPS0ff needed in the end. Unfortunately upon sending the correct command to enter this mode we found the 68k was locked out of all responses from the c-chip. This is presumably due to a port write to ‘PORT F’ that only happens when triggering that mode. There might be some way to get the 68k to see the responses again, but we couldn’t find it, the chip simply stopped responding at that point. None of the games use that port, so it was clearly something intended for development / debugging of the original c-chips only, I guess it’s possible the code is non-functional on the retail modules. If somebody else did want to independently research the c-chips beyond the work done here there’s definitely a lot more to work with now than there was prior to the work done by CAPS0ff, and I imagine at some point it will become necessary to start building replacement c-chips as they do seem to be a source of failure with these boards.