summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/blockhl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/blockhl.c')
-rw-r--r--src/mame/drivers/blockhl.c360
1 files changed, 360 insertions, 0 deletions
diff --git a/src/mame/drivers/blockhl.c b/src/mame/drivers/blockhl.c
new file mode 100644
index 00000000000..fe9ea0aaba5
--- /dev/null
+++ b/src/mame/drivers/blockhl.c
@@ -0,0 +1,360 @@
+/***************************************************************************
+
+Block Hole (GX973) (c) 1989 Konami
+
+driver by Nicola Salmoria
+
+Notes:
+Quarth works, but Block Hole crashes when it reaches the title screen. An
+interrupt happens, and after rti the ROM bank is not the same as before so
+it jumps to garbage code.
+If you want to see this happen, place a breakpoint at 0x8612, and trace
+after that.
+The code is almost identical in the two versions, it looks like Quarth is
+working just because luckily the interrupt doesn't happen at that point.
+It seems that the interrupt handler trashes the selected ROM bank and forces
+it to 0. To prevent crashes, I only generate interrupts when the ROM bank is
+already 0. There might be another interrupt enable register, but I haven't
+found it.
+
+***************************************************************************/
+
+#include "driver.h"
+#include "cpu/konami/konami.h" /* for the callback and the firq irq definition */
+#include "video/konamiic.h"
+#include "sound/2151intf.h"
+
+/* prototypes */
+static MACHINE_RESET( blockhl );
+static void blockhl_banking( int lines );
+
+
+VIDEO_START( blockhl );
+VIDEO_UPDATE( blockhl );
+
+static int palette_selected;
+static UINT8 *ram;
+static int rombank;
+
+static INTERRUPT_GEN( blockhl_interrupt )
+{
+ if (K052109_is_IRQ_enabled() && rombank == 0) /* kludge to prevent crashes */
+ cpunum_set_input_line(0, KONAMI_IRQ_LINE, HOLD_LINE);
+}
+
+static READ8_HANDLER( bankedram_r )
+{
+ if (palette_selected)
+ return paletteram_r(offset);
+ else
+ return ram[offset];
+}
+
+static WRITE8_HANDLER( bankedram_w )
+{
+ if (palette_selected)
+ paletteram_xBBBBBGGGGGRRRRR_be_w(offset,data);
+ else
+ ram[offset] = data;
+}
+
+static WRITE8_HANDLER( blockhl_sh_irqtrigger_w )
+{
+ cpunum_set_input_line_and_vector(1, 0, HOLD_LINE, 0xff);
+}
+
+
+
+static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x1f94, 0x1f94) AM_READ(input_port_4_r)
+ AM_RANGE(0x1f95, 0x1f95) AM_READ(input_port_0_r)
+ AM_RANGE(0x1f96, 0x1f96) AM_READ(input_port_1_r)
+ AM_RANGE(0x1f97, 0x1f97) AM_READ(input_port_2_r)
+ AM_RANGE(0x1f98, 0x1f98) AM_READ(input_port_3_r)
+ AM_RANGE(0x0000, 0x3fff) AM_READ(K052109_051960_r)
+ AM_RANGE(0x4000, 0x57ff) AM_READ(MRA8_RAM)
+ AM_RANGE(0x5800, 0x5fff) AM_READ(bankedram_r)
+ AM_RANGE(0x6000, 0x7fff) AM_READ(MRA8_BANK1)
+ AM_RANGE(0x8000, 0xffff) AM_READ(MRA8_ROM)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x1f84, 0x1f84) AM_WRITE(soundlatch_w)
+ AM_RANGE(0x1f88, 0x1f88) AM_WRITE(blockhl_sh_irqtrigger_w)
+ AM_RANGE(0x1f8c, 0x1f8c) AM_WRITE(watchdog_reset_w)
+ AM_RANGE(0x0000, 0x3fff) AM_WRITE(K052109_051960_w)
+ AM_RANGE(0x4000, 0x57ff) AM_WRITE(MWA8_RAM)
+ AM_RANGE(0x5800, 0x5fff) AM_WRITE(bankedram_w) AM_BASE(&ram)
+ AM_RANGE(0x6000, 0x7fff) AM_WRITE(MWA8_ROM)
+ AM_RANGE(0x8000, 0xffff) AM_WRITE(MWA8_ROM)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( sound_readmem, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x0000, 0x7fff) AM_READ(MRA8_ROM)
+ AM_RANGE(0x8000, 0x87ff) AM_READ(MRA8_RAM)
+ AM_RANGE(0xa000, 0xa000) AM_READ(soundlatch_r)
+ AM_RANGE(0xc001, 0xc001) AM_READ(YM2151_status_port_0_r)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( sound_writemem, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x0000, 0x7fff) AM_WRITE(MWA8_ROM)
+ AM_RANGE(0x8000, 0x87ff) AM_WRITE(MWA8_RAM)
+ AM_RANGE(0xc000, 0xc000) AM_WRITE(YM2151_register_port_0_w)
+ AM_RANGE(0xc001, 0xc001) AM_WRITE(YM2151_data_port_0_w)
+ AM_RANGE(0xe00c, 0xe00d) AM_WRITE(MWA8_NOP) /* leftover from missing 007232? */
+ADDRESS_MAP_END
+
+/***************************************************************************
+
+ Input Ports
+
+***************************************************************************/
+
+static INPUT_PORTS_START( blockhl )
+ PORT_START /* PLAYER 1 INPUTS */
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
+
+ PORT_START /* PLAYER 2 INPUTS */
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
+
+ PORT_START /* DSW #1 */
+ PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x05, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( 3C_2C ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( 4C_3C ) )
+ PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x03, DEF_STR( 3C_4C ) )
+ PORT_DIPSETTING( 0x07, DEF_STR( 2C_3C ) )
+ PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x06, DEF_STR( 2C_5C ) )
+ PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) )
+ PORT_DIPSETTING( 0x09, DEF_STR( 1C_7C ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
+ PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x50, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( 3C_2C ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( 4C_3C ) )
+ PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x30, DEF_STR( 3C_4C ) )
+ PORT_DIPSETTING( 0x70, DEF_STR( 2C_3C ) )
+ PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x60, DEF_STR( 2C_5C ) )
+ PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0xa0, DEF_STR( 1C_6C ) )
+ PORT_DIPSETTING( 0x90, DEF_STR( 1C_7C ) )
+// PORT_DIPSETTING( 0x00, "Invalid" )
+
+ PORT_START /* DSW #2 */
+ PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) )
+ PORT_DIPSETTING( 0x01, "1" )
+ PORT_DIPSETTING( 0x00, "2" )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x60, 0x40, DEF_STR( Difficulty ) )
+ PORT_DIPSETTING( 0x60, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x20, "Difficult" )
+ PORT_DIPSETTING( 0x00, "Very Difficult" )
+ PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START /* DSW #3 */
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Flip_Screen ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_SERVICE( 0x40, IP_ACTIVE_LOW )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
+/***************************************************************************
+
+ Machine Driver
+
+***************************************************************************/
+
+static MACHINE_DRIVER_START( blockhl )
+
+ /* basic machine hardware */
+ MDRV_CPU_ADD(KONAMI,3000000) /* Konami custom 052526 */
+ MDRV_CPU_PROGRAM_MAP(readmem,writemem)
+ MDRV_CPU_VBLANK_INT(blockhl_interrupt,1)
+
+ MDRV_CPU_ADD(Z80, 3579545)
+ /* audio CPU */ /* ? */
+ MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem)
+
+ MDRV_SCREEN_REFRESH_RATE(60)
+ MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
+ MDRV_MACHINE_RESET(blockhl)
+
+ /* video hardware */
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_HAS_SHADOWS)
+ MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
+ MDRV_SCREEN_SIZE(64*8, 32*8)
+ MDRV_SCREEN_VISIBLE_AREA(14*8, (64-14)*8-1, 2*8, 30*8-1 )
+ MDRV_PALETTE_LENGTH(1024)
+
+ MDRV_VIDEO_START(blockhl)
+ MDRV_VIDEO_UPDATE(blockhl)
+
+ /* sound hardware */
+ MDRV_SPEAKER_STANDARD_MONO("mono")
+
+ MDRV_SOUND_ADD(YM2151, 3579545)
+ MDRV_SOUND_ROUTE(0, "mono", 0.60)
+ MDRV_SOUND_ROUTE(1, "mono", 0.60)
+MACHINE_DRIVER_END
+
+
+/***************************************************************************
+
+ Game ROMs
+
+***************************************************************************/
+
+ROM_START( blockhl )
+ ROM_REGION( 0x18800, REGION_CPU1, 0 ) /* code + banked roms + space for banked RAM */
+ ROM_LOAD( "973l02.e21", 0x10000, 0x08000, CRC(e14f849a) SHA1(d44cf178cc98998b72ed32c6e20b6ebdf1f97579) )
+ ROM_CONTINUE( 0x08000, 0x08000 )
+
+ ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* 64k for the sound CPU */
+ ROM_LOAD( "973d01.g6", 0x0000, 0x8000, CRC(eeee9d92) SHA1(6c6c324b1f6f4fba0aa12e0d1fc5dbab133ef669) )
+
+ ROM_REGION( 0x20000, REGION_GFX1, 0 ) /* graphics (addressable by the main CPU) */
+ ROM_LOAD16_BYTE( "973f07.k15", 0x00000, 0x08000, CRC(1a8cd9b4) SHA1(7cb7944d24ac51fa6b610542d9dec68697cacf0f) ) /* tiles */
+ ROM_LOAD16_BYTE( "973f08.k18", 0x00001, 0x08000, CRC(952b51a6) SHA1(017575738d444b688b137cad5611638d53be84f2) )
+ ROM_LOAD16_BYTE( "973f09.k20", 0x10000, 0x08000, CRC(77841594) SHA1(e1bfdc5bb598d865868d578ef7faba8078becd7a) )
+ ROM_LOAD16_BYTE( "973f10.k23", 0x10001, 0x08000, CRC(09039fab) SHA1(a9dea17aacf4484d21ef3b16470263447b51b6b5) )
+
+ ROM_REGION( 0x20000, REGION_GFX2, 0 ) /* graphics (addressable by the main CPU) */
+ ROM_LOAD16_BYTE( "973f06.k12", 0x00000, 0x08000, CRC(51acfdb6) SHA1(94d243f341b490684f5297d95d4835bd522ece35) ) /* sprites */
+ ROM_LOAD16_BYTE( "973f05.k9", 0x00001, 0x08000, CRC(4cfea298) SHA1(4772b5b99f5fd8174d8884bd84173512e1edabf4) )
+ ROM_LOAD16_BYTE( "973f04.k7", 0x10000, 0x08000, CRC(69ca41bd) SHA1(9b0b1c888efd2f2d5525f14778e18fb4a7353eb6) )
+ ROM_LOAD16_BYTE( "973f03.k4", 0x10001, 0x08000, CRC(21e98472) SHA1(8c697d369a1f57be0825c33b4e9107ce1b02a130) )
+
+ ROM_REGION( 0x0100, REGION_PROMS, 0 ) /* PROMs */
+ ROM_LOAD( "973a11.h10", 0x0000, 0x0100, CRC(46d28fe9) SHA1(9d0811a928c8907785ef483bfbee5445506b3ec8) ) /* priority encoder (not used) */
+ROM_END
+
+ROM_START( quarth )
+ ROM_REGION( 0x18800, REGION_CPU1, 0 ) /* code + banked roms + space for banked RAM */
+ ROM_LOAD( "973j02.e21", 0x10000, 0x08000, CRC(27a90118) SHA1(51309385b93db29b9277d14252166c4ea1746303) )
+ ROM_CONTINUE( 0x08000, 0x08000 )
+
+ ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* 64k for the sound CPU */
+ ROM_LOAD( "973d01.g6", 0x0000, 0x8000, CRC(eeee9d92) SHA1(6c6c324b1f6f4fba0aa12e0d1fc5dbab133ef669) )
+
+ ROM_REGION( 0x20000, REGION_GFX1, 0 ) /* graphics (addressable by the main CPU) */
+ ROM_LOAD16_BYTE( "973e07.k15", 0x00000, 0x08000, CRC(0bd6b0f8) SHA1(6c59cf637354fe2df424eaa89feb9c1bc1f66a92) ) /* tiles */
+ ROM_LOAD16_BYTE( "973e08.k18", 0x00001, 0x08000, CRC(104d0d5f) SHA1(595698911513113d01e5b565f5b073d1bd033d3f) )
+ ROM_LOAD16_BYTE( "973e09.k20", 0x10000, 0x08000, CRC(bd3a6f24) SHA1(eb45db3a6a52bb2b25df8c2dace877e59b4130a6) )
+ ROM_LOAD16_BYTE( "973e10.k23", 0x10001, 0x08000, CRC(cf5e4b86) SHA1(43348753894c1763b26dbfc70245dac92048db8f) )
+
+ ROM_REGION( 0x20000, REGION_GFX2, 0 ) /* graphics (addressable by the main CPU) */
+ ROM_LOAD16_BYTE( "973e06.k12", 0x00000, 0x08000, CRC(0d58af85) SHA1(2efd661d614fb305a14cfe1aa4fb17714f215d4f) ) /* sprites */
+ ROM_LOAD16_BYTE( "973e05.k9", 0x00001, 0x08000, CRC(15d822cb) SHA1(70ecad5e0a461df0da6e6eb23f43a7b643297f0d) )
+ ROM_LOAD16_BYTE( "973e04.k7", 0x10000, 0x08000, CRC(d70f4a2c) SHA1(25f835a17bacf2b8debb2eb8a3cff90cab3f402a) )
+ ROM_LOAD16_BYTE( "973e03.k4", 0x10001, 0x08000, CRC(2c5a4b4b) SHA1(e2991dd78b9cd96cf93ebd6de0d4e060d346ab9c) )
+
+ ROM_REGION( 0x0100, REGION_PROMS, 0 ) /* PROMs */
+ ROM_LOAD( "973a11.h10", 0x0000, 0x0100, CRC(46d28fe9) SHA1(9d0811a928c8907785ef483bfbee5445506b3ec8) ) /* priority encoder (not used) */
+ROM_END
+
+
+/***************************************************************************
+
+ Game driver(s)
+
+***************************************************************************/
+
+static void blockhl_banking( int lines )
+{
+ UINT8 *RAM = memory_region(REGION_CPU1);
+ int offs;
+
+ /* bits 0-1 = ROM bank */
+ rombank = lines & 0x03;
+ offs = 0x10000 + (lines & 0x03) * 0x2000;
+ memory_set_bankptr(1,&RAM[offs]);
+
+ /* bits 3/4 = coin counters */
+ coin_counter_w(0,lines & 0x08);
+ coin_counter_w(1,lines & 0x10);
+
+ /* bit 5 = select palette RAM or work RAM at 5800-5fff */
+ palette_selected = ~lines & 0x20;
+
+ /* bit 6 = enable char ROM reading through the video RAM */
+ K052109_set_RMRD_line( ( lines & 0x40 ) ? ASSERT_LINE : CLEAR_LINE );
+
+ /* bit 7 used but unknown */
+
+ /* other bits unknown */
+
+ if ((lines & 0x84) != 0x80) logerror("%04x: setlines %02x\n",activecpu_get_pc(),lines);
+}
+
+static MACHINE_RESET( blockhl )
+{
+ UINT8 *RAM = memory_region(REGION_CPU1);
+
+ cpunum_set_info_fct(0, CPUINFO_PTR_KONAMI_SETLINES_CALLBACK, (genf *)blockhl_banking);
+
+ paletteram = &RAM[0x18000];
+}
+
+
+static DRIVER_INIT( blockhl )
+{
+ konami_rom_deinterleave_2(REGION_GFX1);
+ konami_rom_deinterleave_2(REGION_GFX2);
+}
+
+
+
+GAME( 1989, blockhl, 0, blockhl, blockhl, blockhl, ROT0, "Konami", "Block Hole", 0 )
+GAME( 1989, quarth, blockhl, blockhl, blockhl, blockhl, ROT0, "Konami", "Quarth (Japan)", 0 )