diff options
Diffstat (limited to 'trunk/src/mame/drivers/blockhl.c')
-rw-r--r-- | trunk/src/mame/drivers/blockhl.c | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/trunk/src/mame/drivers/blockhl.c b/trunk/src/mame/drivers/blockhl.c new file mode 100644 index 00000000000..b328ca335ac --- /dev/null +++ b/trunk/src/mame/drivers/blockhl.c @@ -0,0 +1,349 @@ +/******************************************************************************* + + 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 "emu.h" +#include "cpu/z80/z80.h" +#include "cpu/konami/konami.h" /* for the callback and the firq irq definition */ +#include "video/konicdev.h" +#include "sound/2151intf.h" +#include "includes/konamipt.h" +#include "includes/blockhl.h" + +/* prototypes */ +static KONAMI_SETLINES_CALLBACK( blockhl_banking ); + +static INTERRUPT_GEN( blockhl_interrupt ) +{ + blockhl_state *state = device->machine().driver_data<blockhl_state>(); + + if (k052109_is_irq_enabled(state->m_k052109) && state->m_rombank == 0) /* kludge to prevent crashes */ + device_set_input_line(device, KONAMI_IRQ_LINE, HOLD_LINE); +} + +static READ8_HANDLER( bankedram_r ) +{ + blockhl_state *state = space->machine().driver_data<blockhl_state>(); + + if (state->m_palette_selected) + return space->machine().generic.paletteram.u8[offset]; + else + return state->m_ram[offset]; +} + +static WRITE8_HANDLER( bankedram_w ) +{ + blockhl_state *state = space->machine().driver_data<blockhl_state>(); + + if (state->m_palette_selected) + paletteram_xBBBBBGGGGGRRRRR_be_w(space, offset, data); + else + state->m_ram[offset] = data; +} + +static WRITE8_HANDLER( blockhl_sh_irqtrigger_w ) +{ + blockhl_state *state = space->machine().driver_data<blockhl_state>(); + device_set_input_line_and_vector(state->m_audiocpu, 0, HOLD_LINE, 0xff); +} + + +/* special handlers to combine 052109 & 051960 */ +static READ8_HANDLER( k052109_051960_r ) +{ + blockhl_state *state = space->machine().driver_data<blockhl_state>(); + + if (k052109_get_rmrd_line(state->m_k052109) == CLEAR_LINE) + { + if (offset >= 0x3800 && offset < 0x3808) + return k051937_r(state->m_k051960, offset - 0x3800); + else if (offset < 0x3c00) + return k052109_r(state->m_k052109, offset); + else + return k051960_r(state->m_k051960, offset - 0x3c00); + } + else + return k052109_r(state->m_k052109, offset); +} + +static WRITE8_HANDLER( k052109_051960_w ) +{ + blockhl_state *state = space->machine().driver_data<blockhl_state>(); + + if (offset >= 0x3800 && offset < 0x3808) + k051937_w(state->m_k051960, offset - 0x3800, data); + else if (offset < 0x3c00) + k052109_w(state->m_k052109, offset, data); + else + k051960_w(state->m_k051960, offset - 0x3c00, data); +} + + +static ADDRESS_MAP_START( main_map, AS_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(0x1f94, 0x1f94) AM_READ_PORT("DSW3") + AM_RANGE(0x1f95, 0x1f95) AM_READ_PORT("P1") + AM_RANGE(0x1f96, 0x1f96) AM_READ_PORT("P2") + AM_RANGE(0x1f97, 0x1f97) AM_READ_PORT("DSW1") + AM_RANGE(0x1f98, 0x1f98) AM_READ_PORT("DSW2") + AM_RANGE(0x0000, 0x3fff) AM_READWRITE(k052109_051960_r, k052109_051960_w) + AM_RANGE(0x4000, 0x57ff) AM_RAM + AM_RANGE(0x5800, 0x5fff) AM_READWRITE(bankedram_r, bankedram_w) AM_BASE_MEMBER(blockhl_state, m_ram) + AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank1") + AM_RANGE(0x8000, 0xffff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( audio_map, AS_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x7fff) AM_ROM + AM_RANGE(0x8000, 0x87ff) AM_RAM + AM_RANGE(0xa000, 0xa000) AM_READ(soundlatch_r) + AM_RANGE(0xc000, 0xc001) AM_DEVREADWRITE("ymsnd", ym2151_r, ym2151_w) + AM_RANGE(0xe00c, 0xe00d) AM_WRITENOP /* leftover from missing 007232? */ +ADDRESS_MAP_END + + +/*************************************************************************** + + Input Ports + +***************************************************************************/ + +static INPUT_PORTS_START( blockhl ) + PORT_START("P1") + KONAMI8_B123_START(1) + + PORT_START("P2") + KONAMI8_B123_START(2) + + PORT_START("DSW1") + KONAMI_COINAGE_LOC(DEF_STR( Free_Play ), "No Coin B", SW1) + /* "No Coin B" = coins produce sound, but no effect on coin counter */ + + PORT_START("DSW2") + PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING( 0x01, "1" ) + PORT_DIPSETTING( 0x00, "2" ) + PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "SW2:2" ) /* Listed as "Unused" */ + PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW2:3" ) /* Listed as "Unused" */ + PORT_DIPUNUSED_DIPLOC( 0x08, 0x08, "SW2:4" ) /* Listed as "Unused" */ + PORT_DIPUNUSED_DIPLOC( 0x10, 0x10, "SW2:5" ) /* Listed as "Unused" */ + PORT_DIPNAME( 0x60, 0x40, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:6,7") + PORT_DIPSETTING( 0x60, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x40, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x20, DEF_STR( Difficult ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Very_Difficult ) ) + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + + PORT_START("DSW3") + 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_DIPLOCATION("SW3:1") + PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "SW3:2" ) /* Listed as "Unused" */ + PORT_SERVICE_DIPLOC(0x40, IP_ACTIVE_LOW, "SW3:3" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW3:4" ) /* Listed as "Unused" */ +INPUT_PORTS_END + + +/*************************************************************************** + + Machine Driver + +***************************************************************************/ + +static const k052109_interface blockhl_k052109_intf = +{ + "gfx1", 0, + NORMAL_PLANE_ORDER, + KONAMI_ROM_DEINTERLEAVE_2, + blockhl_tile_callback +}; + +static const k051960_interface blockhl_k051960_intf = +{ + "gfx2", 1, + NORMAL_PLANE_ORDER, + KONAMI_ROM_DEINTERLEAVE_2, + blockhl_sprite_callback +}; + +static MACHINE_START( blockhl ) +{ + blockhl_state *state = machine.driver_data<blockhl_state>(); + UINT8 *ROM = machine.region("maincpu")->base(); + + memory_configure_bank(machine, "bank1", 0, 4, &ROM[0x10000], 0x2000); + + state->m_maincpu = machine.device("maincpu"); + state->m_audiocpu = machine.device("audiocpu"); + state->m_k052109 = machine.device("k052109"); + state->m_k051960 = machine.device("k051960"); + + state->save_item(NAME(state->m_palette_selected)); + state->save_item(NAME(state->m_rombank)); +} + +static MACHINE_RESET( blockhl ) +{ + blockhl_state *state = machine.driver_data<blockhl_state>(); + + konami_configure_set_lines(machine.device("maincpu"), blockhl_banking); + + state->m_palette_selected = 0; + state->m_rombank = 0; +} + +static MACHINE_CONFIG_START( blockhl, blockhl_state ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", KONAMI,3000000) /* Konami custom 052526 */ + MCFG_CPU_PROGRAM_MAP(main_map) + MCFG_CPU_VBLANK_INT("screen", blockhl_interrupt) + + MCFG_CPU_ADD("audiocpu", Z80, 3579545) + MCFG_CPU_PROGRAM_MAP(audio_map) + + MCFG_MACHINE_START(blockhl) + MCFG_MACHINE_RESET(blockhl) + + /* video hardware */ + MCFG_VIDEO_ATTRIBUTES(VIDEO_HAS_SHADOWS) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MCFG_SCREEN_SIZE(64*8, 32*8) + MCFG_SCREEN_VISIBLE_AREA(14*8, (64-14)*8-1, 2*8, 30*8-1 ) + MCFG_SCREEN_UPDATE(blockhl) + + MCFG_PALETTE_LENGTH(1024) + + MCFG_VIDEO_START(blockhl) + + MCFG_K052109_ADD("k052109", blockhl_k052109_intf) + MCFG_K051960_ADD("k051960", blockhl_k051960_intf) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + + MCFG_SOUND_ADD("ymsnd", YM2151, 3579545) + MCFG_SOUND_ROUTE(0, "mono", 0.60) + MCFG_SOUND_ROUTE(1, "mono", 0.60) +MACHINE_CONFIG_END + + +/*************************************************************************** + + Game ROMs + +***************************************************************************/ + +ROM_START( blockhl ) + ROM_REGION( 0x18000, "maincpu", 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, "audiocpu", 0 ) /* 64k for the sound CPU */ + ROM_LOAD( "973d01.g6", 0x0000, 0x8000, CRC(eeee9d92) SHA1(6c6c324b1f6f4fba0aa12e0d1fc5dbab133ef669) ) + + ROM_REGION( 0x20000, "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, "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, "proms", 0 ) /* PROMs */ + ROM_LOAD( "973a11.h10", 0x0000, 0x0100, CRC(46d28fe9) SHA1(9d0811a928c8907785ef483bfbee5445506b3ec8) ) /* priority encoder (not used) */ +ROM_END + +ROM_START( quarth ) + ROM_REGION( 0x18000, "maincpu", 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, "audiocpu", 0 ) /* 64k for the sound CPU */ + ROM_LOAD( "973d01.g6", 0x0000, 0x8000, CRC(eeee9d92) SHA1(6c6c324b1f6f4fba0aa12e0d1fc5dbab133ef669) ) + + ROM_REGION( 0x20000, "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, "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, "proms", 0 ) /* PROMs */ + ROM_LOAD( "973a11.h10", 0x0000, 0x0100, CRC(46d28fe9) SHA1(9d0811a928c8907785ef483bfbee5445506b3ec8) ) /* priority encoder (not used) */ +ROM_END + + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + +static KONAMI_SETLINES_CALLBACK( blockhl_banking ) +{ + blockhl_state *state = device->machine().driver_data<blockhl_state>(); + + /* bits 0-1 = ROM bank */ + state->m_rombank = lines & 0x03; + memory_set_bank(device->machine(), "bank1", state->m_rombank); + + /* bits 3/4 = coin counters */ + coin_counter_w(device->machine(), 0, lines & 0x08); + coin_counter_w(device->machine(), 1, lines & 0x10); + + /* bit 5 = select palette RAM or work RAM at 5800-5fff */ + state->m_palette_selected = ~lines & 0x20; + + /* bit 6 = enable char ROM reading through the video RAM */ + k052109_set_rmrd_line(state->m_k052109, (lines & 0x40) ? ASSERT_LINE : CLEAR_LINE); + + /* bit 7 used but unknown */ + + /* other bits unknown */ + + if ((lines & 0x84) != 0x80) + logerror("%04x: setlines %02x\n", cpu_get_pc(device), lines); +} + + +GAME( 1989, blockhl, 0, blockhl, blockhl, 0, ROT0, "Konami", "Block Hole", GAME_SUPPORTS_SAVE ) +GAME( 1989, quarth, blockhl, blockhl, blockhl, 0, ROT0, "Konami", "Quarth (Japan)", GAME_SUPPORTS_SAVE ) |