30 Aug 2017

Let's talk about bootlegs

Some may have noticed there isn't any bootleg in my repair logs.
Reason is simple, I don't repair bootlegs.


Well, first they were produced illegally and in my opinion have contributed to the demise of the arcade industry.

Second, most of the time they are poorly built (botched).
Third, and probably the most important, most aren't perfect copies of the original games. Symptoms can vary from differences in the gameplay, graphic glitches or even missing sounds (it's not rare to find an unpopulated area in the sound section to cut costs).

On the other side they have the big advantage of being custom chips and security chips free (there are few exceptions). Which means they are fully repairable with standard parts.
Other good thing is they are Fujitsu TTL free which are known to be evil.

So what do I do with bootlegs that cross my way?

I use them as donors. Especially if they are 100% fonctionnal as it eliminates the need to test the parts you pull from them.

Here's an example: Street Fighter 2 (Alpha Magic bootleg)

As you can see the board has been scavenged a lot.
From the top of my head, I've used the following parts to save the following games:
- M68000 (main CPU) => Chelnov
- Z80 (audio CPU) => Power Spikes
- YM3012 (audio DAC) => Salamander
- 3 EPROMs => Super Pang (unsuicide)
- And a lot of TTL for different games

Last thing, if you combine the individual price of all the parts you realise they are worth more than the working bootleg board.

23 Aug 2017

Aero Fighters - Video System 1992 (repair log)

Game booted with garbled graphics and only blue colour was present.

I quickly found RAM U16 (type 6264 narrow) was extremely hot. I replaced it and graphics were restored but still blue only.

Starting from the edge connector I probed the board backward: no activity on the green and red pins of the edge connector, then no activity on the resistors used as DAC, and finally no activity on the outputs of one of the two LS273 used for colours. Input pins had activity as it should, clock seemed valid so as master reset. I pulled it and installed a new one, colours were back:

Game fixed.

16 Aug 2017

Mercs - Capcom 1990 (repair log)

The game was almost 100% running ok. But here were bars across the screen visible only when background was black. Nothing noticeable in game.

I swapped the A and C boards and narrowed the fault to the B board. Then I swapped the ROMs and PALs and found the B board itself was faulty. I probed the few ICs on the board but didn't find any suspicious one. It's the third time I face this exact same issue on CPS1, two previous times it was simply a cut trace. This time made no exception. I found only one broken trace and patched it with the core of kynar wire.

Game fixed.

9 Aug 2017

Conversions on Irem M92 hardware - part 2 (Major Title 2 to R-Type Leo)

After the Major Title 2 to Mystic Riders conversion I wanted to have a look at R-Type Leo.
I used the same principles and found the conversion made by an other hacker named vxc wasn't perfect.
In fact in the sound ROMs there's an encrypted 0x3b instruction corresponding to 0x00 once decrypted (add mem, reg):

00F0F: neg     al  (E2 D8)
00F11: add     [bp+0Ch],al (3B 46 0C)
00F14: ret        (AA)

Exactly the same issue I faced with Mystic Riders as there isn't any equivalent opcode in the Major Title 2 table.
This rose the question "How did vxc managed to get a working sound program?". So I had a look and found he simply left the opcode as is, that is to say 0x3b. Luckily for him this doesn't correspond to any other valid instruction and the sound CPU considers it as a NOP:

00F0F: neg     al  (C4 D8)
00F11: nop               (3B)
00F12: nop               (46)
00F13: pop     ix          (0C)
00F14: ret        (9D)

In game this causes the fade out effect of the music before each boss to be missing and music just stops brutally before the boss' music starts.

On my side, I reused the soubroutine I created for Mystic Riders and my R-Type Leo conversion works fine in MAME [EDIT]and on real hardware as I now own a MT2 board (fade out is present):

00F0F: neg     al  (C4 D8)
00F11: call    9000h  (86 EC 80)
00F14: ret        (9D)

09000: add     al,[bp+0Ch] (27 46 0C)
09003: mov     [bp+0Ch],al (5D 46 0C)
09006: ret   (9D)

Out of curiosity I compared my files with vxc's ones and found a lot of other differences!
For instance vxc missed the vector branch @ 0x00400 but again this doesn't seem to cause any trouble.

[EDIT 29/08/2017]
Tested and reported fully working on real hardware by the member of a French forum. Many thanks to him for his feedback.

Also available:
- Gunforce
- Blade Masters
- Lethal Thunder
- Undercover Cops
- Undercover Cops Alpha Renewal
- Mystic Riders/Gun Hohki
- Major Title 2/The Irem Skins Game
- Hook
- R-Type Leo
- In The Hunt
- Ninja Baseball Batman/Yakyuu Kakutou League-Man
- Perfects Soldiers/Sky Soldiers
- Dream Soccer 94
- Gunforce 2/Geostorm

2 Aug 2017

Conversions on Irem M92 hardware (Major Title 2 to Mystic Riders)

Irem M92 hardware is composed of two boards:
- Big CPU board: identical amongst all games (except few manufacturing differences with no impact on gameplay or functionnalities, e.g. 6264 RAMs installed where 6116 are big enough).
- Smaller ROM board: different for each game and with an encrypted sound CPU code to prevent conversions.
Thus a romswap will give you a fully working game graphically but with bugged or totally absent sound.

Few other hackers have done conversions on the Irem M92 hardware, the most popular being Major Title 2 converted to R-Type Leo. Unfortunately their work isn't available anywhere online anymore...
So I had a go by myself and choose to convert a game which hasn't been converted before: Mystic Riders. (I must admit I quite like this game).
The original game I used is Major Title 2 again (probably the easiest to find and cheapest M92 game) but the principles can be applied to convert any M92 game to any other M92 game.

1) Equivalent opcodes

I've developped a simple tool to help me for the conversions.
First it creates a list of equivalent opcodes between the two games accodring to MAME tables (found in the file irem_cpu.cpp located in \src\mame\machine):

Major Title 2 table:
// majtitl2
const uint8_t majtitl2_decryption_table[256] = {
 0x87,xxxx,0x78,0xaa,xxxx,xxxx,xxxx,0x2c, 0x32,0x0a,0x0f,xxxx,0x5e,xxxx,0xc6,0x8a, /* 00 */
 0x33,xxxx,xxxx,xxxx,xxxx,0xea,xxxx,0x72, xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,0x24,0x55, /* 10 */
 xxxx,xxxx,xxxx,0x89,0xfb,xxxx,0x59,0x02, xxxx,xxxx,0x5d,xxxx,xxxx,xxxx,0x36,xxxx, /* 20 */
 xxxx,0x06,0x79,xxxx,xxxx,0x1e,0x07,xxxx, xxxx,xxxx,0x83,xxxx,xxxx,xxxx,xxxx,xxxx, /* 30 */
 0x9d,xxxx,xxxx,0x74,xxxx,xxxx,xxxx,0x0c, 0x58,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx, /* 40 */
 0x3c,xxxx,0x03,xxxx,xxxx,0xfa,0x43,xxxx, 0xbf,xxxx,xxxx,0x75,xxxx,0x88,xxxx,0x80, /* 50 */
 xxxx,0xa3,xxxx,0xfe,xxxx,xxxx,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,0x3a,xxxx,xxxx,xxxx, /* 60 */
 0x2b,xxxx,xxxx,xxxx,xxxx,0xe9,0x5f,xxxx, 0x46,xxxx,0x41,xxxx,0x18,0xb8,xxxx,xxxx, /* 70 */
 0xb4,0x5a,0xb1,xxxx,xxxx,0x50,0xe8,0x20, xxxx,0xb2,xxxx,xxxx,xxxx,xxxx,xxxx,0x51, /* 80 */
 xxxx,xxxx,xxxx,0x56,xxxx,xxxx,xxxx,xxxx, xxxx,0xcf,xxxx,xxxx,xxxx,0xc3,xxxx,xxxx, /* 90 */
 xxxx,xxxx,xxxx,xxxx,0x0b,xxxx,xxxx,0xb5, 0x57,xxxx,xxxx,0xc7,0x3b,xxxx,xxxx,xxxx, /* A0 */
 xxxx,xxxx,xxxx,xxxx,0xb6,xxxx,0xeb,xxxx, 0x38,xxxx,0xa0,0x08,xxxx,0x86,0xb0,xxxx, /* B0 */
 0x42,0x1f,0x73,xxxx,0xf6,xxxx,xxxx,xxxx, 0x53,xxxx,0x52,xxxx,0x04,0xbd,xxxx,xxxx, /* C0 */
 0x26,0xff,0x2e,xxxx,0x81,xxxx,0x47,xxxx, xxxx,xxxx,xxxx,0xd0,0x22,xxxx,xxxx,0xb9, /* D0 */
 0x23,xxxx,0xf3,xxxx,xxxx,xxxx,xxxx,xxxx, xxxx,0xd2,0x8b,0xba,xxxx,xxxx,xxxx,0x5b, /* E0 */
 xxxx,xxxx,0x9c,xxxx,xxxx,xxxx,xxxx,0xfc, 0xbc,0xa2,0x2a,xxxx,xxxx,0x8e,0xbb,xxxx, /* F0 */
// 0x7c (0x18) opcode is right but arguments could be swapped
// 0x70 (0x2b) not sure, could be 0x1b
Mystic Riders table:
/* note: mysticrib sound is identical revision to bbmanw sound code */
// mysticri
const uint8_t mysticri_decryption_table[256] = {
 xxxx,0x57,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx, 0xbf,0x43,xxxx,xxxx,0xb3,xxxx,0xfc,xxxx, /* 00 */
 xxxx,xxxx,xxxx,xxxx,xxxx,0x52,0xa3,0x26, xxxx,0xc7,xxxx,0x0f,xxxx,0x0c,xxxx,xxxx, /* 10 */
 xxxx,xxxx,0xff,xxxx,xxxx,0x02,xxxx,xxxx, 0x2e,xxxx,0x5f,xxxx,xxxx,xxxx,0x73,0x50, /* 20 */
 0xb2,0x3a,xxxx,xxxx,0xbb,xxxx,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx, /* 30 */
 xxxx,xxxx,0x8e,0x3c,0x42,xxxx,xxxx,0xb9, xxxx,xxxx,0x2a,xxxx,0x47,0xa0,0x2b,0x03, /* 40 */
 0xb5,0x1f,xxxx,0xaa,xxxx,0xfb,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,0x38,xxxx,xxxx,xxxx, /* 50 */
 0x2c,xxxx,xxxx,0xc6,xxxx,xxxx,0xb1,xxxx, xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,0xa2,xxxx, /* 60 */
 0xe9,0xe8,xxxx,xxxx,0x86,xxxx,0x8b,xxxx, xxxx,xxxx,xxxx,xxxx,0x5b,0x72,xxxx,xxxx, /* 70 */
 xxxx,xxxx,0x5d,0x0a,xxxx,xxxx,0x89,xxxx, 0xb0,0x88,xxxx,0xb7,xxxx,0x87,0x75,0xbd, /* 80 */
 xxxx,0x51,xxxx,xxxx,xxxx,xxxx,xxxx,0xbe, xxxx,xxxx,xxxx,0x5a,0x58,xxxx,xxxx,0x56, /* 90 */
 xxxx,0x8a,xxxx,0x55,xxxx,xxxx,xxxx,0xb4, 0x08,xxxx,0xf6,xxxx,xxxx,0x9d,xxxx,0xbc, /* A0 */
 0x0b,0x00,xxxx,0x5e,xxxx,xxxx,xxxx,0x22, 0x36,0x4b,0x1e,xxxx,0xb6,0xba,0x23,xxxx, /* B0 */
   /*r*/                                    /*r*/
 0x20,xxxx,xxxx,xxxx,0x59,0x53,xxxx,0x04, 0x81,xxxx,xxxx,0xf3,xxxx,xxxx,0x3b,0x06, /* C0 */
 0xe2,0x79,0x83,0x9c,xxxx,0x18,0x80,xxxx, 0xc3,xxxx,xxxx,xxxx,0x32,xxxx,0xcf,xxxx, /* D0 */
 0xeb,xxxx,xxxx,0x33,xxxx,0xfa,xxxx,xxxx, 0xd2,xxxx,0x24,xxxx,0x74,0x41,0xb8,xxxx, /* E0 */
 0x34,xxxx,0xd0,0x07,0xf8,xxxx,xxxx,xxxx, xxxx,0x46,xxxx,0xea,0xfe,0x78,xxxx,xxxx, /* F0 */
 /*r*/               /*r*/
// 0xd5 (0x18) opcode is right but arguments could be swapped
// 0x4e (0x2b) not sure, could be 0x1b
// 0x8b (0xb3) needed by mysticrib
Table of equivalence:

First column are encrypted values used by Mystic Riders, second column are unecrypted values, third column are crypted values for Major Title 2.

2) Separating code from data

Then, using MAME debugger, I played the game and used the trace function for the sound CPU (trace filename).
This gave me a huge file in which I removed duplicated lines (obviously the sound CPU executes many times the same lines of code).

3) Converting opcodes

First I read encrypted opcodes from the sound ROMs (once interleaved in one file). The address to read from is given by the MAME trace file. Most opcodes are 1 byte long but few are 2 byte long (I used the Nec V20-V30 documentation to be sure).

Then, using the list created in 1), I wrote the equivalent encrypted opcodes used by Major Title 2 to the sound CPU ROMs.

4) Tests (annoying issue spotted)

In order to force MAME to use the decryption table of Major Title 2 instead of Mystic Riders I've modified the file named m92.cpp located in \src\mame\drivers.
I've edited this section:

static MACHINE_CONFIG_DERIVED( mysticri, m92 )


static MACHINE_CONFIG_DERIVED( mysticri, m92 )

After recompiling I played the game in MAME until after beating the octopuss at the end of round 4 music stopped.
I discovered Mystic Riders uses a 0x00 instruction (add memory with register to memory) only once in its entire sound program @ 0x00E6D.
Unfortunately the MAME table for Major Title 2 doens't contain the equivalent opcode (Major Title probably doesn't use this instruction and/or MAME table is incomplete). I could have tried on the real hardware every possibility to find the corresponding encrypted opcode but:
- I don't own any M92 game [EDIT]I now own a MT2 board
- There might be no equivalent as Major Title 2 doesn't need it
- It would have required a lot of time (ROMs burning, playing the game to the problematic point, etc.)
I decided to modify slightly the code to use known opcodes instead.

As said before, the problematic instruction lies @ 0x00E6D in the sound CPU ROMs:

00E6D: add     [bp+0Ch],al (00 46 0C)

As I will need more room to fit my modified code I replaced this line by a jump to a subroutine I will create:

00E6D: call    9000h  (86 90 81)

There's a big area filled with 0xFF starting @ 0x08D70. I choosed to put my new subroutine @ 0x09000 so it's easy to find and identify.
The subroutine itself is very simple:

09000: add     al,[bp+0Ch] (27 46 0C)
09003: mov     [bp+0Ch],al (5D 46 0C)
09006: ret   (9D)

Instead of adding memory with register to memory I add memory with register to register.
This could have been a problem if the value stored in the register was reused later but this wasn't the case (value is overwritten in the next loop).
Then I move the content of the register to the expected memory location.
I played the game (in MAME as I don't own any M92 game [EDIT]and on real hardware as I now own a MT2 board) again to the end and found no other problem.

[EDIT 29/08/2017]
Tested and reported fully working on real hardware by the member of a French forum. Many thanks to him for his feedback.

Also available:
- Gunforce
- Blade Masters
- Lethal Thunder
- Undercover Cops
- Undercover Cops Alpha Renewal
- Mystic Riders/Gun Hohki
- Major Title 2/The Irem Skins Game
- Hook
- R-Type Leo
- In The Hunt
- Ninja Baseball Batman/Yakyuu Kakutou League-Man
- Perfects Soldiers/Sky Soldiers
- Dream Soccer 94
- Gunforce 2/Geostorm