summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Nicola Salmoria <nicola@mamedev.org>2008-05-10 18:09:15 +0000
committer Nicola Salmoria <nicola@mamedev.org>2008-05-10 18:09:15 +0000
commit384388cf6f2ffe4c4e71509d5820e4d86e069850 (patch)
tree14f52020a84b935fa3f94e07b5515d8039f42c3b
parentc5511b65fbb570d217e2b13a4bb4821fff954be2 (diff)
Rewrote the Gaelco video ram encryption, which finally makes sense.
The key observation was that when decryptiong the second word, both encrypted and decrypted bits of the first word are used. Many thanks to Javier Valero for the detailed information that made this possible.
-rw-r--r--.gitattributes2
-rw-r--r--src/mame/drivers/gaelco.c400
-rw-r--r--src/mame/includes/gaelcrpt.h2
-rw-r--r--src/mame/machine/gaelcrpt.c151
-rw-r--r--src/mame/mame.mak2
5 files changed, 165 insertions, 392 deletions
diff --git a/.gitattributes b/.gitattributes
index 035cc548a83..a6dfce2255b 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2195,6 +2195,7 @@ src/mame/includes/firetrk.h svneol=native#text/plain
src/mame/includes/foodf.h svneol=native#text/plain
src/mame/includes/fromance.h svneol=native#text/plain
src/mame/includes/gaelco3d.h svneol=native#text/plain
+src/mame/includes/gaelcrpt.h svneol=native#text/plain
src/mame/includes/galaga.h svneol=native#text/plain
src/mame/includes/galaxian.h svneol=native#text/plain
src/mame/includes/galaxold.h svneol=native#text/plain
@@ -2450,6 +2451,7 @@ src/mame/machine/fd1094.h svneol=native#text/plain
src/mame/machine/fddebug.c svneol=native#text/plain
src/mame/machine/flstory.c svneol=native#text/plain
src/mame/machine/gaelco2.c svneol=native#text/plain
+src/mame/machine/gaelcrpt.c svneol=native#text/plain
src/mame/machine/galaxold.c svneol=native#text/plain
src/mame/machine/gaplus.c svneol=native#text/plain
src/mame/machine/harddriv.c svneol=native#text/plain
diff --git a/src/mame/drivers/gaelco.c b/src/mame/drivers/gaelco.c
index 55223394722..d75f43fc884 100644
--- a/src/mame/drivers/gaelco.c
+++ b/src/mame/drivers/gaelco.c
@@ -11,6 +11,7 @@
#include "cpu/m68000/m68000.h"
#include "sound/okim6295.h"
#include "sound/3812intf.h"
+#include "gaelcrpt.h"
extern UINT16 *gaelco_vregs;
extern UINT16 *gaelco_videoram;
@@ -655,395 +656,12 @@ static INPUT_PORTS_START( squash )
INPUT_PORTS_END
-static int lastpc=0;
-static int lastword=0;
-static int lastoffset=0;
-
-
-#define CARRY(bit) {carry[bit] = (dst[bit]>>1); dst[bit]&=1;}
-
-static int decrypt(int game, int key, int high_word, int low_word)
-{
- static const int swaps[4][16] =
- {
- { 5,7,9,12,2,14,13,15,3,6,8,11,4,10,0,1 },
- { 11,2,5,14,8,13,10,4,7,12,0,6,15,9,1,3 },
- { 7,0,11,12,13,1,6,8,9,5,4,10,14,3,15,2 },
- { 3,0,2,1,10,15,8,6,9,13,11,7,12,5,4,14 },
- };
-
- int dst[16],carry[16];
- int i;
- const int *s = swaps[key & 3];
- int flag1 = BIT(high_word, 9) ^ BIT(high_word, 12) ^ 1;
- int flag2 = game ? BIT(high_word, 10) : (BIT(high_word, 9) ^ BIT(high_word, 10));
-
- if (game)
- flag2 = -flag2;
-
- for (i = 0; i < 16; i++)
- dst[i] = BIT(low_word, s[15-i]);
- for (i = 0; i < 16; i++)
- carry[i] = 0;
-
- if (flag1 && flag2)
- {
- dst[13] += game ? 0 : 1; CARRY(13)
- dst[2] += carry[13]; CARRY(2)
- dst[15] += 1 + carry[2]; CARRY(15)
- dst[4] += - carry[15]; CARRY(4)
- dst[6] += 1 - carry[4]; CARRY(6)
- dst[7] += carry[6]; CARRY(7)
-
- dst[14] += game ? BIT(low_word, 9) : BIT(~low_word, 9); CARRY(14)
- dst[12] += game ? BIT(low_word, 9) : BIT(~low_word, 9); CARRY(12)
-
- dst[9] += dst[15] + carry[14]; CARRY(9)
- dst[10] += dst[15] + carry[12]; CARRY(10)
-
- dst[5] += BIT(~low_word, 5) + carry[9]; CARRY(5)
- dst[1] += BIT(~low_word, 5) + carry[10]; CARRY(1)
-
- dst[3] += 1 + dst[7] - carry[5]; CARRY(3)
- dst[11] += 1 + dst[7] - carry[1]; CARRY(11)
-
- dst[8] += 1 + dst[6] + carry[3];
- dst[0] += 1 + dst[6] + carry[11];
- }
- else
- {
- dst[13] += BIT(key,2); CARRY(13)
- dst[2] += BIT(key,3) + carry[13]; CARRY(2)
- dst[15] += BIT(key,4) + carry[2]; CARRY(15)
- dst[4] += BIT(key,5) - carry[15]; CARRY(4)
- dst[6] += BIT(key,6) - carry[4]; CARRY(6)
- dst[7] += BIT(key,7) + carry[6]; CARRY(7)
-
- dst[14] += BIT(key,8); CARRY(14)
- dst[12] += BIT(key,8); CARRY(12)
-
- dst[9] += BIT(key,9) + carry[14]; CARRY(9)
- dst[10] += BIT(key,9) + carry[12]; CARRY(10)
-
- dst[5] += BIT(key,10) + carry[9]; CARRY(5)
- dst[1] += BIT(key,10) + carry[10]; CARRY(1)
-
- dst[3] += BIT(key,11) - flag1*dst[2] - flag2*dst[13] - carry[5]; CARRY(3)
- dst[11] += BIT(key,11) - flag1*dst[2] - flag2*dst[13] - carry[1]; CARRY(11)
-
- dst[8] += BIT(key,12) + carry[3];
- dst[0] += BIT(key,12) + carry[11];
- }
-
- low_word = 0;
- for (i = 0; i < 16; i++)
- low_word |= (dst[i] & 1) << i;
-
- switch (game)
- {
- default:
- case 0:
- return low_word ^ 0xf626;
- case 1:
- return low_word ^ 0x8626;
- }
-}
-
-
-static int get_key(int game, int high_word)
-{
- int src[16],dst[16],carry[16];
- int i;
- int flag1 = BIT(high_word, 9) ^ BIT(high_word, 12) ^ 1;
- int flag2 = game ? BIT(high_word, 10) : (BIT(high_word, 9) ^ BIT(high_word, 10));
- int temp;
-
- for (i = 0; i < 16; i++)
- {
- src[i] = BIT(high_word,i);
- dst[i] = 0;
- carry[i] = 0;
- }
-
-
- dst[10] = flag1 ? (src[7] ^ src[12]) : src[5];
-
- dst[8] = flag2 ? (1 ^ src[6]) : 0;
-
- dst[5] = (flag1 ^ flag2) ? (1 ^ src[3]) : (1 ^ (src[5] | src[10]) ^ src[11]);
-
- if (flag1 == 0 && flag2 == 0)
- dst[6] = dst[5] + src[2]; CARRY(6);
- if (flag1 == 1 && flag2 == 0)
- dst[6] = dst[5] + src[8]; CARRY(6);
- if (flag1 == 0 && flag2 == 1)
- dst[6] = dst[5] + src[13]; CARRY(6);
-
- if (game == 0)
- {
- if (flag1 == 0 && flag2 == 0)
- {
- dst[7] = src[3];
- dst[7] ^= (1^src[12]) & (1^src[5]) & src[0];
- dst[7] ^= src[14] & src[5] & src[0];
- dst[7] ^= ((1^src[12]) ^ src[11]) & (1^src[2]);
- dst[7] ^= src[11] & src[6];
- dst[7] ^= src[12] & src[5] & (1^src[2]);
- dst[7] ^= src[12] & (1^src[11]) & (1^src[5]) & (1^src[6]);
- }
- if (flag1 == 1 && flag2 == 0)
- dst[7] = 1 ^ src[15] ^ carry[6] ^ (src[8] & (1^src[3]));
- if (flag1 == 0 && flag2 == 1)
- dst[7] = 1 ^ src[14] ^ carry[6];
- }
- else
- {
- if (flag1 == 0 && flag2 == 0)
- {
- dst[7] = src[3];
- dst[7] ^= ((1^src[14]) & (1^src[5])) & src[0];
- dst[7] ^= src[6] ^ (src[14] & (1^src[11]));
- dst[7] ^= src[5] & (1^src[6]^src[14]) & (1^src[11]);
- dst[7] ^= (src[11] ^ src[5]) & src[2];
- dst[7] ^= src[14] & (src[11] & (1^src[5]));
- }
- if (flag1 == 1 && flag2 == 0)
- dst[7] = 1 ^ src[15] ^ carry[6] ^ (src[8] & (1^src[3]));
- if (flag1 == 0 && flag2 == 1)
- dst[7] = 1 ^ src[14] ^ carry[6];
- }
-
- if (game == 0)
- {
- temp = (src[5] | (src[9] & src[10]));
- }
- else
- {
- temp = src[5];
- }
-
- dst[0] = src[3] ^ (src[6] | ((1^src[11]) & temp));
-
- if (game == 0)
- {
- dst[1] = src[15]
- ^ (temp & src[4] & src[3])
- ^ (temp & (src[11] ? (src[6] | src[4]) : (1^src[6])))
- ^ (src[13] ?
- (src[6] & (1^temp) & src[4]) ^ ((1^temp) & (1^src[4]) & src[3])
- ^ (src[7] & src[8] & (1^src[9]) & temp & (src[6] ^ src[4] ^ src[3]))
- ^ ((1^src[11]) & (1^src[6]) & temp & src[7] & src[8] & (1^src[9]))
- ^ (src[10] & src[9] & src[8] & (1 ^ src[4] ^ src[3]))
- ^ (src[11] & src[10] & src[9] & src[8] & (1^src[6]))
- :
- (src[6] & (1^temp) & (1 ^ src[4] ^ src[8]))
- ^ ((1^temp) & (src[4] ? ((1^src[3]) & (1^src[8])) : (src[3] & src[8])))
- ^ (src[7] & (1^src[8]) & (1^src[9]) & (1^temp) & (src[6] ^ src[4] ^ src[3]))
- ^ (src[10] & src[9] & src[8] & (1 ^ src[4] ^ src[3]) & (1^src[5]))
- ^ (src[11] & src[10] & src[9] & src[8] & (1^src[6]) & (1^src[5]))
- )
- ;
- }
- else
- {
- dst[1] = src[15]
- ^ (temp & src[4] & src[3])
- ^ (temp & (src[11] ? (src[6] | src[4]) : (1^src[6])))
- ^ (src[13] ?
- (src[6] & (1^temp) & src[4]) ^ ((1^temp) & (1^src[4]) & src[3])
- ^ (src[7] & src[8] & src[9] & temp & (src[6] ^ src[4] ^ src[3]))
- ^ ((1^src[11]) & (1^src[6]) & temp & src[7] & src[8] & src[9])
- :
- (src[6] & (1^temp) & (1 ^ src[4] ^ src[8]))
- ^ ((1^temp) & (src[4] ? ((1^src[3]) & (1^src[8])) : (src[3] & src[8])))
- ^ (src[7] & (1^src[8]) & src[9] & (1^temp) & (src[6] ^ src[4] ^ src[3]))
- );
- }
-
- if (game == 0)
- {
- if (flag1 == 0 && flag2 == 0)
- dst[11] = src[0] ^ (src[5] ? src[14] : src[10]);
- if (flag1 == 1 && flag2 == 0)
- dst[11] = 0;
- if (flag1 == 0 && flag2 == 1)
- dst[11] = 0;
- }
- else
- {
- if (flag1 == 0 && flag2 == 0)
- dst[11] = src[0] ^ (src[5] ? src[10] : (1^src[14])); // note src[10] == 0
- if (flag1 == 1 && flag2 == 0)
- dst[11] = 0;
- if (flag1 == 0 && flag2 == 1)
- dst[11] = 1;
- }
-
- dst[12] = dst[11];
- if (flag1 == 0 && flag2 == 0)
- dst[12] ^= src[10];
- if (flag1 == 1 && flag2 == 0)
- dst[12] ^= 0;
- if (flag1 == 0 && flag2 == 1)
- dst[12] ^= src[3] ^ (src[11] ? src[6] : (src[6] | src[5]));
-
- if (game == 0)
- {
- if (flag1 == 0 && flag2 == 0)
- dst[4] = src[6];
- if (flag1 == 1 && flag2 == 0)
- dst[4] = src[0] ^ (src[14] ? (1^src[12]) : src[5]);
- if (flag1 == 0 && flag2 == 1)
- dst[4] = src[7];
- }
- else
- {
- if (flag1 == 0 && flag2 == 0)
- dst[4] = src[6];
- if (flag1 == 1 && flag2 == 0)
- dst[4] = src[0] ^ (src[14] ? ((1^src[12]) | (1^src[5])) : (src[12] | src[5]));
- if (flag1 == 0 && flag2 == 1)
- dst[4] = src[7];
- }
-
- if (game == 0)
- {
- if (flag1 == 0 && flag2 == 0)
- dst[9] = src[5] ^ (src[12] & (1^src[7])) ^ src[13];
- if (flag1 == 1 && flag2 == 0)
- dst[9] = 1 ^ src[4];
- if (flag1 == 0 && flag2 == 1)
- dst[9] = src[6] ^ ((1^src[11]) & src[5]);
- }
- else
- {
- if (flag1 == 0 && flag2 == 0)
- dst[9] = 1 ^ src[5] ^ ((1^src[12]) & src[7]) ^ src[13];
- if (flag1 == 1 && flag2 == 0)
- dst[9] = 1 ^ src[4];
- if (flag1 == 0 && flag2 == 1)
- dst[9] = src[6] ^ ((1^src[11]) & src[5]);
- }
-
- if (game == 0)
- {
- if (flag1 == 0 && flag2 == 0)
- dst[3] = src[12];
- if (flag1 == 1 && flag2 == 0)
- dst[3] = src[0] ^ (src[14] ? src[12] : (1^src[5]));
- if (flag1 == 0 && flag2 == 1)
- dst[3] = src[8] ^ ((1^src[13]) & (1^src[12]) & (1^src[5])) ^ (src[12] & (src[13] ? (src[7] & src[5]) : ((1^src[7]) & (1^src[5]))));
- }
- else
- {
- if (flag1 == 0 && flag2 == 0)
- dst[3] = src[12];
- if (flag1 == 1 && flag2 == 0)
- dst[3] = src[0] ^ (src[14] ? (src[5] & src[12]) : ((1^src[5]) & (1^src[12])));
- if (flag1 == 0 && flag2 == 1)
- dst[3] = src[8] ^ ((1^src[13]) & (src[12]) & (1^src[5])) ^ ((1^src[12]) & (src[13] ? (src[7] & src[5]) : ((1^src[7]) & (1^src[5]))));
- }
-
- if (game == 0)
- {
- if (flag1 == 0 && flag2 == 0)
- dst[2] = src[0];
- if (flag1 == 1 && flag2 == 0)
- dst[2] = src[1]
- ^ (src[3] & (1^src[2]))
- ^ ((1^src[11]) & src[6] & src[5])
- ^ ((1^src[12]) & (1^src[5]) & src[0] & (1^src[14]) & (src[6] ^ src[2] ^ src[3]))
- ^ (src[12] & (1^src[6]) & (1^src[5]) & src[3])
- ^ (src[2] & (1^src[5]) & (1^src[6]) & (1^src[12]))
- ^ (src[2] & src[5] & (1^src[6]) & src[11])
- ^ ((1 ^ src[2] ^ src[3]) & (1^src[5]) & src[6] & src[12])
- ^ (src[14] & (1^src[12]) & (src[2] ^ src[3] ^ src[6]) & (1^src[5]))
- ^ (src[14] & src[12] & src[5] & (1 ^ src[3] ^ src[2] ^ src[11]) & src[0])
- ^ (src[14] & src[12] & src[11] & src[6] & src[5] & src[0])
- ^ (src[12] & (1^src[5]) & src[3])
- ^ (src[12] & (1^src[5]) & src[0] & (1 ^ src[3] ^ src[2] ^ (src[11] & (1^src[6]))))
- ^ (src[12] & (1^src[5]) & (1^src[11]) & src[6] & src[2])
- ^ (src[12] & (1^src[5]) & src[11] & (src[6] ^ src[2]))
- ;
- if (flag1 == 0 && flag2 == 1)
- dst[2] = src[5];
- }
- else
- {
- if (flag1 == 0 && flag2 == 0)
- dst[2] = src[0];
- if (flag1 == 1 && flag2 == 0)
- dst[2] = src[1]
- ^ (src[3] & (1^src[2]))
- ^ ((1^src[11]) & src[6] & src[5])
- ^ ((1^src[12]) & (1^src[5]) & src[0] & (1^src[14]) & (src[6] ^ src[2] ^ src[3]))
- ^ (src[12] & (1^src[6]) & (1^src[5]) & src[3])
- ^ (src[2] & (1^src[5]) & (1^src[6]) & (1^src[12]))
- ^ (src[2] & src[5] & (1^src[6]) & src[11])
- ^ ((1 ^ src[2] ^ src[3]) & (1^src[5]) & src[6] & src[12])
- ^ (src[14] & (1^src[12]) & (src[2] ^ src[3] ^ src[6]) & (1^src[5]))
- ^ (src[14] & src[12] & src[5] & (1 ^ src[3] ^ src[2] ^ src[11]) & src[0])
- ^ (src[14] & src[12] & src[11] & src[6] & src[5] & src[0]);
- if (flag1 == 0 && flag2 == 1)
- dst[2] = src[5];
- }
-
- if (game == 0)
- {
- dst[10] ^= 1;
- dst[4] ^= 1;
- dst[2] ^= 1;
- }
- else
- {
- dst[10] ^= 1;
- dst[8] ^= 1;
- dst[4] ^= 1;
- }
-
-
- high_word = 0;
- for (i = 0; i < 16; i++)
- high_word |= (dst[i] & 1) << i;
-
- if (flag1 == 1 && flag2 == 1)
- high_word &= 3;
-
- return high_word;
-}
-
-
-static UINT16 squash_encrypt(int offset, int data, int game)
-{
- int thispc = activecpu_get_pc();
- int savedata = data;
-
- /* check if 2nd half of 32 bit */
- if(lastpc == thispc && offset == lastoffset + 1)
- {
- lastpc = 0;
- data = decrypt(game, get_key(game, lastword), lastword, data);
- }
- else
- {
- /* code as 1st word */
- lastword = data;
- lastpc = thispc;
- lastoffset = offset;
-
- /* high word returned */
- data = decrypt(game, 0x0000, 0x0400, lastword);
-
- logerror("%8x : data1 = %4x > %4x @ %8x\n",activecpu_get_pc(),savedata,data,lastoffset);
- }
- return data;
-}
static WRITE16_HANDLER( gaelco_vram_encrypted_w )
{
// mame_printf_debug("gaelco_vram_encrypted_w!!\n");
- data = squash_encrypt(offset,data,0);
+ data = gaelco_decrypt(offset, data, 0x0f, 0x4228);
COMBINE_DATA(&gaelco_videoram[offset]);
tilemap_mark_tile_dirty(gaelco_tilemap[offset >> 11],((offset << 1) & 0x0fff) >> 2);
@@ -1054,15 +672,15 @@ static WRITE16_HANDLER(gaelco_encrypted_w)
{
// mame_printf_debug("gaelco_encrypted_w!!\n");
- data = squash_encrypt(offset,data,0);
- COMBINE_DATA(&gaelco_screen[offset]);
+ data = gaelco_decrypt(offset, data, 0x0f, 0x4228);
+ COMBINE_DATA(&gaelco_screen[offset]);
}
static WRITE16_HANDLER( thoop_vram_encrypted_w )
{
// mame_printf_debug("gaelco_vram_encrypted_w!!\n");
- data = squash_encrypt(offset,data,1);
+ data = gaelco_decrypt(offset, data, 0x0e, 0x4228);
COMBINE_DATA(&gaelco_videoram[offset]);
tilemap_mark_tile_dirty(gaelco_tilemap[offset >> 11],((offset << 1) & 0x0fff) >> 2);
@@ -1072,8 +690,8 @@ static WRITE16_HANDLER(thoop_encrypted_w)
{
// mame_printf_debug("gaelco_encrypted_w!!\n");
- data = squash_encrypt(offset,data,1);
- COMBINE_DATA(&gaelco_screen[offset]);
+ data = gaelco_decrypt(offset, data, 0x0e, 0x4228);
+ COMBINE_DATA(&gaelco_screen[offset]);
}
@@ -1336,5 +954,5 @@ ROM_END
GAME( 1991, bigkarnk, 0, bigkarnk, bigkarnk, 0, ROT0, "Gaelco", "Big Karnak", 0 )
GAME( 1995, biomtoy, 0, maniacsq, biomtoy, 0, ROT0, "Gaelco", "Biomechanical Toy (unprotected)", 0 )
GAME( 1996, maniacsp, maniacsq, maniacsq, maniacsq, 0, ROT0, "Gaelco", "Maniac Square (prototype)", 0 )
-GAME( 1992, squash, 0, squash, squash, 0, ROT0, "Gaelco", "Squash (Ver. 1.0)", 0 )
-GAME( 1992, thoop, 0, thoop, thoop, 0, ROT0, "Gaelco", "Thunder Hoop (Ver. 1)", 0 )
+GAME( 1992, squash, 0, squash, squash, 0, ROT0, "Gaelco", "Squash (Ver. 1.0)", 0 )
+GAME( 1992, thoop, 0, thoop, thoop, 0, ROT0, "Gaelco", "Thunder Hoop (Ver. 1)", 0 )
diff --git a/src/mame/includes/gaelcrpt.h b/src/mame/includes/gaelcrpt.h
new file mode 100644
index 00000000000..168412dbdf3
--- /dev/null
+++ b/src/mame/includes/gaelcrpt.h
@@ -0,0 +1,2 @@
+UINT16 gaelco_decrypt(int offset, int data, int param1, int param2);
+
diff --git a/src/mame/machine/gaelcrpt.c b/src/mame/machine/gaelcrpt.c
new file mode 100644
index 00000000000..5b1567e69f6
--- /dev/null
+++ b/src/mame/machine/gaelcrpt.c
@@ -0,0 +1,151 @@
+/*
+
+Gaelco video RAM encryption
+
+Thanks to Javier Valero for information on the algorithm.
+
+*/
+
+#include "driver.h"
+
+static int decrypt(int const param1, int const param2, int const enc_prev_word, int const dec_prev_word, int const enc_word)
+{
+ int const swap = (BIT(dec_prev_word, 8) << 1) | BIT(dec_prev_word, 7);
+ int const type = (BIT(dec_prev_word,12) << 1) | BIT(dec_prev_word, 2);
+ int res=0;
+ int k=0;
+
+ switch (swap)
+ {
+ case 0: res = BITSWAP16(enc_word, 1, 2, 0,14,12,15, 4, 8,13, 7, 3, 6,11, 5,10, 9); break;
+ case 1: res = BITSWAP16(enc_word, 14,10, 4,15, 1, 6,12,11, 8, 0, 9,13, 7, 3, 5, 2); break;
+ case 2: res = BITSWAP16(enc_word, 2,13,15, 1,12, 8,14, 4, 6, 0, 9, 5,10, 7, 3,11); break;
+ case 3: res = BITSWAP16(enc_word, 3, 8, 1,13,14, 4,15, 0,10, 2, 7,12, 6,11, 9, 5); break;
+ }
+
+ res ^= param2;
+
+ switch (type)
+ {
+ case 0:
+ k = (0 << 0) |
+ (1 << 1) |
+ (0 << 2) |
+ (1 << 3) |
+ (1 << 4) |
+ (1 << 5);
+ break;
+
+ case 1:
+ k = (BIT(dec_prev_word, 0) << 0) |
+ (BIT(dec_prev_word, 1) << 1) |
+ (BIT(dec_prev_word, 1) << 2) |
+ (BIT(enc_prev_word, 3) << 3) |
+ (BIT(enc_prev_word, 8) << 4) |
+ (BIT(enc_prev_word,15) << 5);
+ break;
+
+ case 2:
+ k = (BIT(enc_prev_word, 5) << 0) |
+ (BIT(dec_prev_word, 5) << 1) |
+ (BIT(enc_prev_word, 7) << 2) |
+ (BIT(enc_prev_word, 3) << 3) |
+ (BIT(enc_prev_word,13) << 4) |
+ (BIT(enc_prev_word,14) << 5);
+ break;
+
+ case 3:
+ k = (BIT(enc_prev_word, 0) << 0) |
+ (BIT(enc_prev_word, 9) << 1) |
+ (BIT(enc_prev_word, 6) << 2) |
+ (BIT(dec_prev_word, 4) << 3) |
+ (BIT(enc_prev_word, 2) << 4) |
+ (BIT(dec_prev_word,11) << 5);
+ break;
+ }
+
+ k ^= param1;
+
+ res = (res & 0xffc0) | ((res + k) & 0x003f);
+
+ res ^= param1;
+
+ switch (type)
+ {
+ case 0:
+ k = (BIT(enc_word, 9) << 0) |
+ (BIT(res,2) << 1) |
+ (BIT(enc_word, 5) << 2) |
+ (BIT(res,5) << 3) |
+ (BIT(res,4) << 4);
+ break;
+
+ case 1:
+ k = (BIT(dec_prev_word, 2) << 0) | // always 1
+ (BIT(enc_prev_word, 4) << 1) |
+ (BIT(dec_prev_word,14) << 2) |
+ (BIT(res, 1) << 3) |
+ (BIT(dec_prev_word,12) << 4); // always 0
+ break;
+
+ case 2:
+ k = (BIT(enc_prev_word, 6) << 0) |
+ (BIT(dec_prev_word, 6) << 1) |
+ (BIT(dec_prev_word,15) << 2) |
+ (BIT(res,0) << 3) |
+ (BIT(dec_prev_word, 7) << 4);
+ break;
+
+ case 3:
+ k = (BIT(dec_prev_word, 2) << 0) | // always 1
+ (BIT(dec_prev_word, 9) << 1) |
+ (BIT(enc_prev_word, 5) << 2) |
+ (BIT(dec_prev_word, 1) << 3) |
+ (BIT(enc_prev_word,10) << 4);
+
+ break;
+ }
+
+ k ^= param1;
+
+ res = (res & 0x003f) |
+ ((res + (k << 6)) & 0x07c0) |
+ ((res + (k << 11)) & 0xf800);
+
+ res ^= (param1 << 6) | (param1 << 11);
+
+ return BITSWAP16(res, 2,6,0,11,14,12,7,10,5,4,8,3,9,1,13,15);
+}
+
+
+
+UINT16 gaelco_decrypt(int offset, int data, int param1, int param2)
+{
+ static int lastpc, lastoffset, lastencword, lastdecword;
+
+ int thispc = activecpu_get_pc();
+// int savedata = data;
+
+ /* check if 2nd half of 32 bit */
+ if(lastpc == thispc && offset == lastoffset + 1)
+ {
+ lastpc = 0;
+ data = decrypt(param1, param2, lastencword, lastdecword, data);
+ }
+ else
+ {
+ /* code as 1st word */
+
+ lastpc = thispc;
+ lastoffset = offset;
+ lastencword = data;
+
+ /* high word returned */
+ data = decrypt(param1, param2, 0, 0, data);
+
+ lastdecword = data;
+
+// logerror("%8x : data1 = %4x > %4x @ %8x\n",activecpu_get_pc(),savedata,data,lastoffset);
+ }
+ return data;
+}
diff --git a/src/mame/mame.mak b/src/mame/mame.mak
index b42f820a88a..2f5b86b9107 100644
--- a/src/mame/mame.mak
+++ b/src/mame/mame.mak
@@ -710,7 +710,7 @@ $(MAMEOBJ)/fuuki.a: \
$(DRIVERS)/fuukifg3.o $(VIDEO)/fuukifg3.o \
$(MAMEOBJ)/gaelco.a: \
- $(DRIVERS)/gaelco.o $(VIDEO)/gaelco.o \
+ $(DRIVERS)/gaelco.o $(VIDEO)/gaelco.o $(MACHINE)/gaelcrpt.o \
$(DRIVERS)/gaelco2.o $(MACHINE)/gaelco2.o $(VIDEO)/gaelco2.o \
$(DRIVERS)/gaelco3d.o $(VIDEO)/gaelco3d.o \
$(DRIVERS)/glass.o $(VIDEO)/glass.o \