summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/galpani3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/galpani3.c')
-rw-r--r--src/mame/drivers/galpani3.c436
1 files changed, 436 insertions, 0 deletions
diff --git a/src/mame/drivers/galpani3.c b/src/mame/drivers/galpani3.c
new file mode 100644
index 00000000000..567b88fa024
--- /dev/null
+++ b/src/mame/drivers/galpani3.c
@@ -0,0 +1,436 @@
+/*
+ Gals Panic 3
+ (c) Kaneko 1995
+
+ Skeleton driver by Haze
+ WIP Driver by Sebastien Volpe
+
+Check done by main code, as part of EEPROM data:
+'Gals Panic 3 v0.96 95/08/29(Tue)'
+
+
+TODO:
+- find a working board to dump MCU provided code & data, as code is
+ involved just after initial checks; the game currently goes nowhere.
+- finish emulation, mainly backgounds
+
+What's been done lately:
+- palette, inputs, sound, backgounds 'decoded' (RLE)
+*/
+
+/*
+
+Gals Panic 3 (JPN Ver.)
+(c)1995 Kaneko
+
+CPU: 68000-16
+Sound: YMZ280B-F
+OSC: 28.6363MHz
+ 33.3333MHz
+EEPROM: 93C46
+Chips.: GRAP2 x3 <- R/G/B Chips?
+ APRIO-GL
+ BABY004 <- Sprites, see suprnova.c
+ GCNT2
+ TBSOP01 <- ToyBox NEC uPD78324 series MCU with 32K internal rom
+ CG24173 6186
+ CG24143 4181
+
+
+G3P0J1.71 prg.
+G3P1J1.102
+
+GP340000.123 chr.
+GP340100.122
+GP340200.121
+GP340300.120
+G3G0J0.101
+G3G1J0.100
+
+G3D0X0.134
+
+GP320000.1 OBJ chr.
+
+GP310000.41 sound data
+GP310100.40
+
+
+--- Team Japump!!! ---
+http://www.rainemu.com/japump/
+http://japump.i.am/
+Dumped by Uki
+10/22/2000
+
+*/
+
+#include "driver.h"
+#include "sound/ymz280b.h"
+
+extern UINT32* skns_spc_regs;
+
+/***************************************************************************
+
+ video
+
+***************************************************************************/
+
+static UINT16 *galpani3_sprregs, *galpani3_spriteram;
+
+static INTERRUPT_GEN( galpani3_vblank ) // 2, 3, 5 ?
+{
+ switch ( cpu_getiloops() )
+ {
+ case 2: cpunum_set_input_line(0, 2, HOLD_LINE); break;
+ case 1: cpunum_set_input_line(0, 3, HOLD_LINE); break;
+ case 0: cpunum_set_input_line(0, 5, HOLD_LINE); break;
+ }
+}
+
+
+
+static VIDEO_START(galpani3)
+{
+ /* so we can use suprnova.c */
+ buffered_spriteram32 = auto_malloc ( 0x4000 );
+ spriteram_size = 0x4000;
+ skns_spc_regs = auto_malloc (0x40);
+}
+
+extern void skns_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect );
+
+
+static VIDEO_UPDATE(galpani3)
+{
+ fillbitmap(bitmap, get_black_pen(machine), cliprect);
+
+ skns_draw_sprites(machine,bitmap,cliprect);
+ return 0;
+}
+
+
+static INPUT_PORTS_START( galpani3 )
+
+ PORT_START // IN0 - Player Controls
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
+ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ?
+ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START // IN1 - Player Controls
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ?
+ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START // IN2 - Coins
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
+ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
+ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2)
+ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2)
+ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_TILT )
+ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_SERVICE1 )
+ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START // IN3 - DSW provided by the MCU - $200386.b <- $400200
+ PORT_DIPNAME( 0x0100, 0x0100, "Test Mode" )
+ PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Flip_Screen ) )
+ PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) // ?
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) // unused
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) // unused
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) // unused
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) // unused
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) // unused ?
+ PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+INPUT_PORTS_END
+
+
+static WRITE16_HANDLER( galpani3_suprnova_sprite32_w )
+{
+ COMBINE_DATA(&galpani3_spriteram[offset]);
+
+ /* put in buffered_spriteram32 for suprnova.c */
+ offset>>=1;
+ buffered_spriteram32[offset]=(galpani3_spriteram[offset*2+1]<<16) | (galpani3_spriteram[offset*2]);
+}
+
+static WRITE16_HANDLER( galpani3_suprnova_sprite32regs_w )
+{
+ COMBINE_DATA(&galpani3_sprregs[offset]);
+
+ /* put in skns_spc_regs for suprnova.c */
+ offset>>=1;
+ skns_spc_regs[offset]=(galpani3_sprregs[offset*2+1]<<16) | (galpani3_sprregs[offset*2]);
+}
+
+
+
+/***************************************************************************
+
+ MCU Code Simulation
+ (follows the implementation of kaneko16.c)
+
+***************************************************************************/
+static UINT16 *mcu_ram, galpani3_mcu_com[4];
+
+static void galpani3_mcu_run(void)
+{
+ UINT16 mcu_command = mcu_ram[0x0010/2]; /* command nb */
+ UINT16 mcu_offset = mcu_ram[0x0012/2] / 2; /* offset in shared RAM where MCU will write */
+ UINT16 mcu_subcmd = mcu_ram[0x0014/2]; /* sub-command parameter, happens only for command #4 */
+
+ logerror("(PC=%06X): MCU executed command : %04X %04X\n",activecpu_get_pc(),mcu_command,mcu_offset*2);
+
+ /* the only MCU commands found in program code are:
+ 0x04: protection: provide code/data, that's exactly where we are stuck !!!
+ 0x03: read DSW
+ 0x02: load NVRAM settings \ ATMEL AT93C46 chip,
+ 0x42: save NVRAM settings / 128 bytes serial EEPROM
+ */
+ switch (mcu_command >> 8)
+ {
+ case 0x03: // DSW
+ {
+ mcu_ram[mcu_offset] = readinputport(3);
+ logerror("PC=%06X : MCU executed command: %04X %04X (read DSW)\n",activecpu_get_pc(),mcu_command,mcu_offset*2);
+ }
+ break;
+
+ case 0x02: // $38950 - load NVRAM settings
+ {
+ /* NOTE: code @ $38B46 & $38ab8 does exactly what is checked after MCU command
+ so that's what we'll mimic here... probably the initial NVRAM settings */
+ int i;
+
+ /* MCU writes 128 bytes to shared ram: last byte is the byte-sum */
+ /* first 32 bytes (header): 0x8BE08E71.L, then the string "95/06/30 Gals Panic3Ver 0.95"; */
+ mcu_ram[mcu_offset + 0] = 0x8BE0; mcu_ram[mcu_offset + 1] = 0x8E71;
+ mcu_ram[mcu_offset + 2] = 0x3935; mcu_ram[mcu_offset + 3] = 0x2F30;
+ mcu_ram[mcu_offset + 4] = 0x362F; mcu_ram[mcu_offset + 5] = 0x3330;
+ mcu_ram[mcu_offset + 6] = 0x2047; mcu_ram[mcu_offset + 7] = 0x616C;
+ mcu_ram[mcu_offset + 8] = 0x7320; mcu_ram[mcu_offset + 9] = 0x5061;
+ mcu_ram[mcu_offset + 10] = 0x6E69; mcu_ram[mcu_offset + 11] = 0x6333;
+ mcu_ram[mcu_offset + 12] = 0x5665; mcu_ram[mcu_offset + 13] = 0x7220;
+ mcu_ram[mcu_offset + 14] = 0x302E; mcu_ram[mcu_offset + 15] = 0x3935;
+ /* next 11 bytes - initial NVRAM settings */
+ mcu_ram[mcu_offset + 16] = 0x0001; mcu_ram[mcu_offset + 17] = 0x0101;
+ mcu_ram[mcu_offset + 18] = 0x0100; mcu_ram[mcu_offset + 19] = 0x0208;
+ mcu_ram[mcu_offset + 20] = 0x02FF; mcu_ram[mcu_offset + 21] = 0x0000;
+ /* rest is zeroes */
+ for (i=22;i<63;i++)
+ mcu_ram[mcu_offset + i] = 0;
+ /* and sum is $0c.b */
+ mcu_ram[mcu_offset + 63] = 0x000c;
+ }
+ break;
+
+ case 0x04: // $38842 - provides code/data
+ {
+ switch(mcu_subcmd)
+ {
+ int i;
+ case 0x00: /* $1a9c - provides code @ $40f000, length probably 0x1000 max (contains many code snippets, many 'jsr $40fxxx') */
+ for (i=0;i<0x1000/2;i++)
+ mcu_ram[mcu_offset+i] = 0x4e75; // fill 'code page' with RTS
+ //mcu_ram[mcu_offset+0x0098/2] = 0x4e91; // wrong assumption: jsr (A1) :/
+ break;
+
+ case 0x01: /* $1aa8 - provides data @ $400400, length? */
+ break;
+
+ default: /* most likely never happen, unless it's done by code provided by MCU itself */
+ logerror("- UNKNOWN PARAMETER %02X", mcu_subcmd);
+ break;
+ }
+ }
+ break;
+
+ case 0x42: // $389ee - save NVRAM settings
+ {
+ // found, TODO: trace call in code !!!
+ }
+ break;
+
+ default:
+ logerror("UNKNOWN COMMAND\n");
+ }
+}
+
+/*
+ MCU doesn't execute exactly as it is coded right know (ala jchan):
+ * com0=com1=0xFFFF -> command to execute
+ * com2=com3=0xFFFF -> status reading only
+*/
+#define GALPANI3_MCU_COM_W(_n_) \
+WRITE16_HANDLER( galpani3_mcu_com##_n_##_w ) \
+{ \
+ COMBINE_DATA(&galpani3_mcu_com[_n_]); \
+ if (galpani3_mcu_com[0] != 0xFFFF) return; \
+ if (galpani3_mcu_com[1] != 0xFFFF) return; \
+ if (galpani3_mcu_com[2] != 0xFFFF) return; \
+ if (galpani3_mcu_com[3] != 0xFFFF) return; \
+\
+ memset(galpani3_mcu_com, 0, 4 * sizeof( UINT16 ) ); \
+ galpani3_mcu_run(); \
+}
+
+GALPANI3_MCU_COM_W(0)
+GALPANI3_MCU_COM_W(1)
+GALPANI3_MCU_COM_W(2)
+GALPANI3_MCU_COM_W(3)
+
+static READ16_HANDLER( galpani3_mcu_status_r )
+{
+ logerror("cpu #%d (PC=%06X): read mcu status\n", cpu_getactivecpu(), activecpu_get_previouspc());
+ return 0;
+}
+
+
+
+
+static ADDRESS_MAP_START( galpani3_map, ADDRESS_SPACE_PROGRAM, 16 )
+ AM_RANGE(0x000000, 0x0fffff) AM_ROM
+
+ AM_RANGE(0x200000, 0x20ffff) AM_RAM // area [B] - Work RAM
+ AM_RANGE(0x280000, 0x287fff) AM_RAM AM_WRITE(paletteram16_xGGGGGRRRRRBBBBB_word_w) AM_BASE(&paletteram16) // area [A] - palette for sprites
+
+ AM_RANGE(0x300000, 0x303fff) AM_RAM AM_BASE(&galpani3_spriteram) AM_WRITE(galpani3_suprnova_sprite32_w)
+ AM_RANGE(0x380000, 0x38003f) AM_RAM AM_BASE(&galpani3_sprregs) AM_WRITE(galpani3_suprnova_sprite32regs_w)
+
+ AM_RANGE(0x400000, 0x40ffff) AM_RAM AM_BASE(&mcu_ram) // area [C]
+
+ AM_RANGE(0x580000, 0x580001) AM_WRITE(galpani3_mcu_com0_w) // ] see $387e8: these 2 locations are written (w.#$ffff)
+ AM_RANGE(0x600000, 0x600001) AM_WRITE(galpani3_mcu_com1_w) // ] then bit #0 of $780000.l is tested: 0 = OK!
+ AM_RANGE(0x680000, 0x680001) AM_WRITE(galpani3_mcu_com2_w) // ] see $387e8: these 2 locations are written (w.#$ffff)
+ AM_RANGE(0x700000, 0x700001) AM_WRITE(galpani3_mcu_com3_w) // ] then bit #0 of $780000.l is tested: 0 = OK!
+ AM_RANGE(0x780000, 0x780001) AM_READ(galpani3_mcu_status_r)
+
+ AM_RANGE(0x800c00, 0x800c1f) AM_RAM // ? R layer regs ? see subroutine $3a03e
+ AM_RANGE(0xa00c00, 0xa00c1f) AM_RAM // ? G layer regs ? see subroutine $3a03e
+ AM_RANGE(0xc00c00, 0xc00c1f) AM_RAM // ? B layer regs ? see subroutine $3a03e
+
+ AM_RANGE(0x800000, 0x8003ff) AM_RAM // ??? see subroutine $39f42 (R?)
+ AM_RANGE(0x800800, 0x800bff) AM_RAM // ??? see subroutine $39f42 (R?)
+ AM_RANGE(0xa00000, 0xa003ff) AM_RAM // ??? see subroutine $39f42 (G?)
+ AM_RANGE(0xa00800, 0xa00bff) AM_RAM // ??? see subroutine $39f42 (G?)
+ AM_RANGE(0xc00000, 0xc003ff) AM_RAM // ??? see subroutine $39f42 (B?)
+ AM_RANGE(0xc00800, 0xc00bff) AM_RAM // ??? see subroutine $39f42 (B?)
+
+ AM_RANGE(0x900000, 0x97ffff) AM_RAM // area [D] - R area ? odd bytes only, initialized 00..ff,00..ff,...
+ AM_RANGE(0xb00000, 0xb7ffff) AM_RAM // area [E] - G area ? odd bytes only, initialized 00..ff,00..ff,...
+ AM_RANGE(0xd00000, 0xd7ffff) AM_RAM // area [F] - B area ? odd bytes only, initialized 00..ff,00..ff,...
+ AM_RANGE(0xe00000, 0xe7ffff) AM_RAM // area [J] - A area ? odd bytes only, initialized 00..ff,00..ff,..., then cleared
+
+ AM_RANGE(0x880000, 0x8801ff) AM_RAM // area [G] - R area ? linescroll ?
+ AM_RANGE(0xa80000, 0xa801ff) AM_RAM // area [H] - G area ? linescroll ?
+ AM_RANGE(0xc80000, 0xc801ff) AM_RAM // area [I] - B area ? linescroll ?
+
+ AM_RANGE(0xf00000, 0xf00001) AM_NOP // ? written once (2nd opcode, $1.b)
+ AM_RANGE(0xf00050, 0xf00051) AM_NOP // ? written once (3rd opcode, $30.b)
+
+ AM_RANGE(0xf00010, 0xf00011) AM_READ(input_port_0_word_r)
+ AM_RANGE(0xf00012, 0xf00013) AM_READ(input_port_1_word_r)
+ AM_RANGE(0xf00014, 0xf00015) AM_READ(input_port_2_word_r)
+ AM_RANGE(0xf00016, 0xf00017) AM_NOP // ? read, but overwritten
+
+ AM_RANGE(0xf00020, 0xf00021) AM_WRITE(YMZ280B_register_0_lsb_w) // sound
+ AM_RANGE(0xf00022, 0xf00023) AM_WRITE(YMZ280B_data_0_lsb_w) //
+ AM_RANGE(0xf00040, 0xf00041) AM_READWRITE(watchdog_reset16_r, watchdog_reset16_w) // watchdog
+ADDRESS_MAP_END
+
+
+static struct YMZ280Binterface ymz280b_intf =
+{
+ REGION_SOUND1,
+ 0 // irq ?
+};
+
+static MACHINE_DRIVER_START( galpani3 )
+ MDRV_CPU_ADD_TAG("main", M68000, 16000000) // ? (from which clock?)
+ MDRV_CPU_PROGRAM_MAP(galpani3_map,0)
+ MDRV_CPU_VBLANK_INT(galpani3_vblank, 3)
+
+ MDRV_SCREEN_REFRESH_RATE(60)
+ MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
+
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
+ MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
+ MDRV_SCREEN_SIZE(64*8, 64*8)
+ MDRV_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 0*8, 30*8-1)
+ MDRV_PALETTE_LENGTH(0x4000)
+
+ MDRV_VIDEO_START(galpani3)
+ MDRV_VIDEO_UPDATE(galpani3)
+
+ /* sound hardware */
+ MDRV_SPEAKER_STANDARD_MONO("mono")
+
+ MDRV_SOUND_ADD(YMZ280B, 28636400 / 2)
+ MDRV_SOUND_CONFIG(ymz280b_intf)
+ MDRV_SOUND_ROUTE(0, "mono", 1.0)
+ MDRV_SOUND_ROUTE(1, "mono", 1.0)
+MACHINE_DRIVER_END
+
+
+ROM_START( galpani3 )
+ ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 Code */
+ ROM_LOAD16_BYTE( "g3p0j1.71", 0x000000, 0x080000, CRC(52893326) SHA1(78fdbf3436a4ba754d7608fedbbede5c719a4505) )
+ ROM_LOAD16_BYTE( "g3p1j1.102", 0x000001, 0x080000, CRC(05f935b4) SHA1(81e78875585bcdadad1c302614b2708e60563662) )
+
+ ROM_REGION( 0x200000, REGION_GFX1, 0 ) /* Sprites - RLE encoded */
+ ROM_LOAD( "gp320000.1", 0x000000, 0x200000, CRC(a0112827) SHA1(0a6c78d71b75a1d78215aab3104176aa1769b14f) )
+
+ ROM_REGION( 0xa00000, REGION_GFX2, 0 ) /* Backgrounds - RLE encoded */
+ ROM_LOAD( "gp340000.123", 0x000000, 0x200000, CRC(a58a26b1) SHA1(832d70cce1b4f04fa50fc221962ff6cc4287cb92) ) // 19950414GROMACap
+ ROM_LOAD( "gp340100.122", 0x200000, 0x200000, CRC(746fe4a8) SHA1(a5126ae9e83d556277d31b166296a708c311a902) ) // 19950414GROMBCap
+ ROM_LOAD( "gp340200.121", 0x400000, 0x200000, CRC(e9bc15c8) SHA1(2c6a10e768709d1937d9206970553f4101ce9016) ) // 19950414GROMCCap
+ ROM_LOAD( "gp340300.120", 0x600000, 0x200000, CRC(59062eef) SHA1(936977c20d83540c1e0f65d429c7ebea201ef991) ) // 19950414GROMDCap
+ ROM_LOAD16_BYTE( "g3g0j0.101", 0x800000, 0x040000, CRC(fbb1e0dc) SHA1(14f6377afd93054aa5dc38af235ae12b932e847f) ) // 19950523GROMECap
+ ROM_LOAD16_BYTE( "g3g1j0.100", 0x800001, 0x040000, CRC(18edb5f0) SHA1(5e2ed0105b3e6037f6116494d3b186a368824171) ) //
+
+ ROM_REGION( 0x300000, REGION_SOUND1, 0 ) /* Samples */
+ ROM_LOAD( "gp310100.40", 0x000000, 0x200000, CRC(6a0b1d12) SHA1(11fed80b96d07fddb27599743991c58c12c048e0) )
+ ROM_LOAD( "gp310000.41", 0x200000, 0x100000, CRC(641062ef) SHA1(c8902fc46319eac94b3f95d18afa24bd895078d6) )
+
+ ROM_REGION( 0x20000, REGION_USER1, 0 ) /* MCU Code? */
+ ROM_LOAD( "g3d0x0.134", 0x000000, 0x020000, CRC(4ace10f9) SHA1(d19e4540d535ce10d23cb0844be03a3239b3402e) )
+ROM_END
+
+
+static DRIVER_INIT( galpani3 )
+{
+ UINT16 *patchrom = (UINT16 *)memory_region(REGION_CPU1);
+
+ // weird checks of supposed tilemap registers
+ patchrom[0x3a0c6/2] = 0x4e71;
+ patchrom[0x3a0d6/2] = 0x4e71;
+ patchrom[0x3a0e0/2] = 0x4e71;
+
+ memset(galpani3_mcu_com, 0, 4 * sizeof( UINT16) );
+}
+
+GAME( 1995, galpani3, 0, galpani3, galpani3, galpani3, ROT90, "Kaneko", "Gals Panic 3", GAME_NOT_WORKING )