Professional software development, amateur BMW tinkering, old arcade game stuff


Capcom Gun.Smoke PCB repair

This is a bootleg PCB though a well made one with excellent image quality.  The problem is that the buildings have corrupt colours.  This is a rather strange fault as Gun.Smoke only has 1 layer of tiled graphics and all of the other tiles were fine.  This rules out almost all potential RAM or TTL faults (maybe with the exception of some of the palette circuitry), as those components are clearly working fine with the other tiles.  From the look of the graphics I suspected a couple of bit-planes for the tiles had disappeared – because each tile only has 4 colours per block, instead of 16.  MAME confirmed the tile ROMs were laid out as 4 pairs with each ROM contributing 2bpp and the corrupt buildings were within the first pair.


The missing 2bpp theory was confirmed when I ran the board with ROM ’13′ removed – the buildings completely disappeared – so this means that ’13′ was working and it’s partner ’9′ wasn’t contributing anything.  However all ROMS read ok in the reader and matched the MAME set exactly.  The logic probe lit up for all pins on ROM ’9′ so the socket seemed good.  Next theory was the chip enable (/CE) logic was faulty and ROM ’9′ was not being asked to output any data.  However examination of the traces showed /CE was linked for each pair of ROMs in the set (as they always output at once to give make 4bpp output) so could not be that.


I then burned a new eprom with ROM ’9′ data from MAME, placed it on the board and everything worked!  So the fault was definitely with the ROM even though it read fine on PC.  The only theory I have is that the original ROM ’9′ is more susceptible to low voltage than the others.  There is quite a bit of voltage drop from the +5V on the main board to the video board.



Time Soldiers arcade PCB repair

Bought as a non-working board for $9.99 – the most obvious problem is that no CPU was present so clearly the game wasn’t going to do much without that!  With a replacement 68000 in hand (again from Ebay for only a few $) the game booted to garbage.

IMG_1286   IMG_1285

A logic probe on the CPU address and data lines showed zero activity, so the CPU clearly wasn’t doing anything.  Power and ground tested as good.  The reset and halt lines on the CPU were pulsing, so it seemed something on the board was trying to kick the CPU into life.  Testing the CLK pin on the 68000 showed it to be stuck low.  I traced out where this pin went and it connects to the output (Q) of a LS74 next to the oscillator.   The logic probe seemed to show this chip had failed, as a CLK was pulsing on the LS74 input, but the outputs remained stuck (one output feeds back into a LS74 input, so the output should toggle hi/lo every clock in order to form the 68K clock).

Tested off-board – failed – replacement from Dragonninja parts board soldered in – board boots right up!  Quickest TTL level fix I’ve ever done.

IMG_1290 IMG_1293 IMG_1289

At first I thought there was a graphics problem as the title screen was corrupt – though it’s strange all of the other screens were perfect.  Then I remembered I’d seen this a long time ago in MAME..  If you boot the English language ROMs with the Japanese dipswitch enabled the title screen is corrupt (because it expects the Japanese character ROMs).

Unfortunately this board is stuck in Japanese – because the dip-switch isn’t being read by the software.  A previous owner has removed resistor packs for the dip and the jamma inputs, presumably to repair something else!

That shouldn’t be too hard a fix – to be continued.






Pacman arcade PCB repair

Pacman did not appear, and two of the ghosts did not appear.  Additionally the text at the top of the screen (Hi Score) and the bottom (Credit) were corrupt.  A tip on the KLOV forum suggested this was likely to be the VRAM addresser daughterboard.  Nothing looked wrong with a logic probe so I decided to remove the LS157 and LS86 chips as I have a plentiful supply from a Dragonninja parts board.


As it turns out I didn’t even get to the LS86′s as one of the 157′s tested bad when removed, and replacing it solved the problem!

IMG_1226 IMG_1228



Viper Phase 1 / Seibu SPI arcade pcb repair

Sound would go quiet after a few minutes, and it seemed like different elements of the sound would have incorrect volumes (drum track, music, explosions).  I think that’s because the sound chip outputs multiple channels which are mixed externally before the stereo amp but didn’t look too much into it.

Instead, I just swapped out all the capacitors in the audio section – I think all are 100uF, 25V.  This seemed to fix all the audio problems.

IMG_0829 IMG_0830 IMG_1122


Gauntlet Legends / Midway Vegas battery

The battery is barely mentioned in the manual, but test mode will tell you if it has failed.  Just replace the IC in the picture which is on the board with the jamma connector – it’s in a socket even though it doesn’t look like it is.  Part number is M4T28-BR12SH1.


IMG_1145 IMG_1147




Technos Renegade arcade PCB repair

Renegade is a JAMMA pcb and the predecessor to Double Dragon.  Initially it seemed the vertical sync was broken on this board – the image rolled vertically very fast.  I traced the sync line from the JAMMA connector back on the top board and found it goes to the bottom (video) board.  After cleaning up a lot of dirt and dust, a massive gouge in the bottom board became clear!  Must have been a fairly heavy impact as you can see two TTL pins are sheared clean off.

IMG_0532 IMG_0533 IMG_0528

Bridged the broken traces with wire and sync was restored but the image was cut into three pieces.

IMG_0537 IMG_0536

Re-checked the repair with a logic probe and found no activity on one of the repaired traces.  There was actually a through-hole to the other side of the pcb in the damaged area that need soldered back on the trace.  Then everything worked 100%.

IMG_0546 IMG_0543 IMG_0542




Data East Hoops 95 pcb non-repair

This is the Data East MLC package – which is a two layer pcb inside a protective plastic box.  Unfortunately this one seems 100% dead – no video or sound output at all.  Components are actually surface mounted to all 4 surfaces on the two layers – the main CPU (an encrypted ARM) actually sits on an inside surface so it’s hard to diagnose directly.

Using a logic probe with the game powered on shows that the data and address lines on the program EPROMS are pulsing – so the CPU is definitely trying to do something.  All the graphics hardware (ROMs, custom chip) probes as completely dead – that doesn’t prove for sure that it is dead – it may be the CPU is actually failing for some reason and not instructing the graphics customs to start up.  My immediate theory would be one of the main RAM chips for the CPU has failed – these are 4 Winbond chips on the main board.  The ARM is a 32 bit chip and these 8 bit chips run in parallel so a failure in any one of them would cause the CPU program to immediately fail.

Hoops isn’t that great a game, so I’ve no plans to probe further – this can wait until I find another MLC game and swap the top & bottom boards and see what happens.

IMG_0616 IMG_0618 IMG_0617IMG_0619


Namco Sky Kid pcb

Bought as a non-worker for parts – actually it works 100%!  The non-obvious catch is that who-ever made the JAMMA adaptor wired it upside down!?  The tell-tale sign is the ‘double’ +5V and GND traces are on the right instead of the left.

IMG_0613 IMG_0608 IMG_0607 IMG_0605 IMG_0604


Super Chase / Hantarex Polo

A reasonably rare/overlooked game from Taito in 1992. This was completely dead when I got it – no lights, sounds, picture. The power supply was the first problem as it wasn’t able to supply +5V to the pcb. In fact I had to try 3 (used) power supplies until I found one that could give a consistent +5. This pcb draws a lot more current than a lot of older titles (probably as it uses a 68020 CPU and two sub 68000 cpus, plus a lot of graphics and sound ic’s that were cutting edge at the time) so some power supplies can’t keep up and voltage drops.

IMG_0234 IMG_0251

This made two LED’s on the light driver board illuminate, but still nothing else. The sound board is quite unusual in it expects +13V as well as +5V and +12V. Without the +13V line connected the sound amps don’t work at all – however putting 12V there made them work well enough that I could hear game sounds – so pcb confirmed as running! [I should mention that Super Chase isn't jamma - so I couldn't just test it in another cabinet].

The monitor remained completely dead – it’s a Hantarex Polo 25″ standard resolution. No signs on physical problems (cold solder joints, blown fuses, burnt areas, broken components). I hate working on high voltage stuff, so rather than debug anything I decided just to shotgun replace the flyback, all capacitors, and the HOT (horizontal output transistor). On a 23 year old monitor it’s a good bet the capacitors need replacing, and the flyback may have failed. Internet repair logs on this monitor suggest bad flybacks can kill the HOT, so as it’s only $5 may as well replace it too.

IMG_0250 IMG_0249

And it worked! It’s quite unusual for a cap kit to bring a dead monitor back to life, but the Polo has a built in power supply (no isolation transformer needed) so bad caps there were probably the primary reason for not turning on. Monitor looks good as new now.

A cool thing about Super Chase is the flashing lights – these are just 40W incandescent bulbs, but both were blown – replaced them, and replaced a blown fuse on the driver board and all was good there. The driver board is quite a simple thing – it takes two 5V lines from the game pcb as input, a 110V mains source, and outputs two 110V lines to the bulbs. You can see the board is designed for 4 lights, but only 2 channels are populated.

IMG_0264 IMG_0262

(Main marquee light still not fixed in picture below)

IMG_0268IMG_0278 IMG_0275



Operation Wolf

Recently RetroGamer ran a feature on Operation Wolf (Taito, 1987) that mentioned the emulation in M.A.M.E. and the ‘arcade perfect’ Taito Legends (PS2, 2005) was not quite correct – missing cutscenes, a missing boss, some other details.  Unfortunately, that’s true – the reason is Operation Wolf contains copy protection that has never been properly emulated.  I was the programmer who implemented the protection emulation on Taito Legends (PS2) and then M.A.M.E. and it’s actually based on a bootleg (pirate) version of the game.  The problem was that original ‘cracker’ of the game didn’t get everything right.  The protection device is actually an 8 bit micro controller of some sort that maps into 256 bytes of the main CPU address space.  It runs a private embedded program that cannot be read out, so what exactly the controller does is somewhat of a mystery.  Memory mapping is a very effective copy protection when done right, as the main CPU can just write bytes into random locations, and then expect certain results & logic back at a later date without any obvious link as to what inputs caused what outputs.  The bootleg sheds light on the setup though – one example is the end of level detection – the main cpu constantly writes the number of enemies, tanks & helicopters remaining in the level into shared memory.  Only when all of these are zero does the protection chip write a byte that signals ‘level is complete’.  The protection is effective because without a reference it’s very hard to know the internal logic of the controller.



By chance, a prototype Japanese version of Operation Wolf was recently discovered – this was almost certainly a test unit placed on location for player feedback before the game was finished, and before the copy protection was added.  It’s fairly close to the final game though, and does contain the missing scenes and boss, so in theory it should be possible to compare the two programs, and make a guess at what the protection logic is doing compared to the unprotected reference program.  I thought some people might like to read about this process, so hence this post – be warned, it’s going to get a bit technical…


Initial Comparison

In an ideal world the two games would disassemble to near identical programs, with the only difference being a bit of protection logic replacing the original game logic from the prototype.  Unfortunately that’s not the case – what we can see is that there is a lot of code that is logically the same – but it’s assembled to different locations, and variables have moved around in memory.  Some of that is deliberate – with some variables moving into shared c-chip (protection) ram rather than main memory, but some of it is clearly just from sections being moved around in the original source and the assembler following suit.

00541E: 6100 0024 bsr $5444
005422: 3211 move.w (A1), D1
005424: 0241 8200 andi.w #$8200, D1
005428: 0C41 8000 cmpi.w #-$8000, D1
00542C: 660E bne $543c
00542E: 4251 clr.w (A1)
005430: 7200 moveq #$0, D1
005432: 1229 001F move.b ($1f,A1), D1
005436: 3F01 move.w D1, -(A7)
005438: 4E42 trap #$2
00543A: 548F addq.l #2, A7
00543C: D2C4 adda.w D4, A1
00543E: 51C8 FFE2 dbra D0, $5422
005442: 4E75 rts
006100: 6100 002C bsr $612e
006104: 3211 move.w (A1), D1
006106: 0241 8200 andi.w #$8200, D1
00610A: 0C41 8000 cmpi.w #-$8000, D1
00610E: 6616 bne $6126
006110: 48E7 8000 movem.l D0, -(A7)
006114: 4251 clr.w (A1)
006116: 7200 moveq #$0, D1
006118: 1229 001F move.b ($1f,A1), D1
00611C: 3F01 move.w D1, -(A7)
00611E: 4E42 trap #$2
006120: 548F addq.l #2, A7
006122: 4CDF 0001 movem.l (A7)+, D0
006126: D2C4 adda.w D4, A1
006128: 51C8 FFDA dbra D0, $6104
00612C: 4E75 rts
0119F8: 203C 4001 0306 move.l #$40010306, D0
0119FE: 3439 000F F036 move.w $ff036.l, D2 // current level
011A04: 0C02 0002 cmpi.b #$2, D2
011A08: 6700 0004 beq $11a0e
011A0C: 7000 moveq #$0, D0
011A0E: 3439 000F F04C move.w $ff04c.l, D2
011A14: 0242 00FF andi.w #$ff, D2
011A18: 08E9 0003 0000 bset #$3, ($0,A1)
011A1E: D5FC 0000 0010 adda.l #$10, A2
011A24: 6100 E5B8 bsr $ffde
011A28: 4E75 rts
00DD8C: 203C 4001 0306 move.l #$40010306, D0
00DD92: 0C6D 0002 0B20 cmpi.w #$2, ($b20,A5)
00DD98: 6700 0004 beq $dd9e
00DD9C: 7000 moveq #$0, D0
00DD9E: 142D 0C7D move.b ($c7d,A5), D2
00DDA2: 08E9 0003 0000 bset #$3, ($0,A1)
00DDA8: D5FC 0000 0010 adda.l #$10, A2
00DDAE: 6100 E834 bsr $c5e4
00DDB2: 4E75 rts

In the above tables the code functionally does the same thing but you can see it’s assembled to different addresses.  The original code (on the left) accesses the 8 bit c-chip shared ram for the level variable ($ffxxx), so it’s changed to byte instructions rather than word.

Software Architecture

Operation Wolf has interesting software architecture. Unlike most games of this
era which have a simple main loop and linear code flow, Operation Wolf
implements a co-operative threading model where routines run in 68K user mode
until giving up their timeslice and a supervisor mode scheduler picks the next
thread to run. There are 32 thread slots, and each enemy in game run as its
own thread/object as well as a thread for coins, scrolling the level, level
specific gameplay and so on. The code is very robust when creating threads,
for example if there are no free slots, the creating thread just spins until
a slot frees up. The rest of the game just keeps on playing in the background.
Another interesting detail is that a thread can give up it’s timeslice for more
than 1 frame – this makes it really easy to implement timed events. The ‘WARNING’
text at the end of level 2 is handled by a thread that prints to screen, then just
waits a second before spawning the boss enemy thread.


Each level in the game implements its own logic thread and often sub-threads -
this is the major difference between the protected game and the bootleg – the bootleg
mostly implements the parts that are generic between all levels rather than all of
the details. The biggest single area the bootleg did not implement revolves
around location 0x5f in the shared c-chip RAM. The original code sets up a thread
that just waits for this value to become non-zero. It then jumps to a set of
functions defined in a look-up table (that can then spawn further threads). There
are 10 non-null functions tied to this routine.
1: Enemy spawn for level 7 (first ‘Located’ cut-scene)

2: Enemy spawn for level 8 (second ‘Located’ cut-scene) – zoom in helicopters

3: Enemy spawn for level 9 (third ‘Located’ cut-scene)

4: Boss & hostage sequence for level 2

5: Enemy spawn when less than 45 enemies in level 2 (paratrooper drop-down)

6: Enemy spawn when less than 25 enemies in level 2

7: Enemy spawn when 0 men left in levels 2,4,5,6

8: Enemy spawn when 0 men left in level 3

9: Enemy spawn when 0 men left in level 1

10: Special explosion animation when level 4 (Powder Dump) is completed


The bootleg also misses some other details, for example in level 5 the c-chip
sets a flag when all men are destroyed (not vehicles) and this triggers the 68K
to scroll the screen vertically to focus on the remaining helicopter enemies.

The ‘Enemy has located you’ cut-scenes appear ‘randomly’ between levels in the
original game, but are deliberately disabled in the bootleg. The exact formula
for determining if the cut-scene appears is ‘(frameCount & levelNumber)==0′.  There are three different cutscene levels.



Source Dumps

Should you want to see what the code for an old arcade game looks like I’ve attached my annotated dumps of the original and prototype source code – it fills in some labels and some variables and the thread functions to make it easier to read!


0053EC: 322D 0B20 move.w $CURRENT_LEVEL, D1
0053F0: 0C41 0006 cmpi.w #$6, D1
0053F4: 6614 bne $540a
0053F6: 1B7C 0001 0998 move.b #$1, ($998,A5)
0053FC: 4EB9 0000 3314 jsr $3314.l
005402: 3F3C 0020 move.w #$20, -(A7)
005406: 4E46 trap #$6 (SLEEP_THREAD_FOR_N_FRAMES)
005408: 548F addq.l #2, A7
00540A: 6100 0012 bsr $541e
00540E: 3F3C 003C move.w #$3c, -(A7)
005412: 4E46 trap #$6 (SLEEP_THREAD_FOR_N_FRAMES)
005414: 548F addq.l #2, A7
005416: 1B7C 0001 0999 move.b #$1, $END_OF_LEVEL_FLAG 
00541C: 4E45 trap #$5 (KILL_THREAD)

opwolf.dasm  opwolfp.dasm