// license:BSD-3-Clause // copyright-holders:Nicola Salmoria /*************************************************************************** Hexion (GX122) (c) 1992 Konami driver by Nicola Salmoria Notes: - The board has a 052591, which is used for protection in Thunder Cross and S.P.Y. In this game, however, the only thing it seems to do is clear the screen. This is the program for the 052591: 00: 5f 80 01 e0 08 01: df 80 00 e0 0c 02: df 90 02 e0 0c 03: df a0 03 e0 0c 04: df b0 0f e0 0c 05: df c0 ff bf 0c 06: 5c 02 00 33 0c 07: 5f 80 04 80 0c 08: 5c 0e 00 2b 0c 09: df 70 00 cb 08 0a: 5f 80 00 80 0c 0b: 5c 04 00 2b 0c 0c: df 60 00 cb 08 0d: 5c 0c 1f e9 0c 0e: 4c 0c 2d e9 08 0f: 5f 80 03 80 0c 10: 5c 04 00 2b 0c 11: 5f 00 00 cb 00 12: 5f 80 02 a0 0c 13: df d0 00 c0 04 14: 01 3a 00 f3 0a 15: 5c 08 00 b3 0c 16: 5c 0e 00 13 0c 17: 5f 80 00 a0 0c 18: 5c 00 00 13 0c 19: 5c 08 00 b3 0c 1a: 5c 00 00 13 0c 1b: 84 5a 00 b3 0c 1c: 48 0a 5b d1 0c 1d: 5f 80 00 e0 08 1e: 5f 00 1e fd 0c 1f: 5f 80 01 a0 0c 20: df 20 00 cb 08 21: 5c 08 00 b3 0c 22: 5f 80 03 00 0c 23: 5c 08 00 b3 0c 24: 5f 80 00 80 0c 25: 5c 00 00 33 0c 26: 5c 08 00 93 0c 27: 9f 91 ff cf 0e 28: 5c 84 00 20 0c 29: 84 00 00 b3 0c 2a: 49 10 69 d1 0c 2b: 5f 80 00 e0 08 2c: 5f 00 2c fd 0c 2d: 5f 80 01 a0 0c 2e: df 20 00 cb 08 2f: 5c 08 00 b3 0c 30: 5f 80 03 00 0c 31: 5c 00 00 b3 0c 32: 5f 80 01 00 0c 33: 5c 08 00 b3 0c 34: 5f 80 00 80 0c 35: 5c 00 00 33 0c 36: 5c 08 00 93 0c 37: 9f 91 ff cf 0e 38: 5c 84 00 20 0c 39: 84 00 00 b3 0c 3a: 49 10 79 d1 0c 3b: 5f 80 00 e0 08 3c: 5f 00 3c fd 0c 3d: ff ff ff ff ff 3e: ff ff ff ff ff 3f: ff ff ff ff ff ***************************************************************************/ #include "emu.h" #include "includes/hexion.h" #include "includes/konamipt.h" #include "cpu/z80/z80.h" #include "machine/watchdog.h" #include "sound/okim6295.h" #include "sound/k051649.h" #include "speaker.h" WRITE8_MEMBER(hexion_state::coincntr_w) { //logerror("%04x: coincntr_w %02x\n",m_maincpu->pc(),data); /* bits 0/1 = coin counters */ machine().bookkeeping().coin_counter_w(0,data & 0x01); machine().bookkeeping().coin_counter_w(1,data & 0x02); /* bit 5 = flip screen */ flip_screen_set(data & 0x20); /* other bit unknown */ if ((data & 0xdc) != 0x10) popmessage("coincntr %02x",data); } WRITE_LINE_MEMBER(hexion_state::irq_ack_w) { m_maincpu->set_input_line(0, CLEAR_LINE); } WRITE_LINE_MEMBER(hexion_state::nmi_ack_w) { m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); } WRITE8_MEMBER(hexion_state::ccu_int_time_w) { logerror("ccu_int_time rewritten with value of %02x\n", data); m_ccu_int_time = data; } void hexion_state::hexion_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0x9fff).bankr("bank1"); map(0xa000, 0xbfff).ram(); map(0xc000, 0xdffe).rw(this, FUNC(hexion_state::bankedram_r), FUNC(hexion_state::bankedram_w)); map(0xdfff, 0xdfff).w(this, FUNC(hexion_state::bankctrl_w)); map(0xe000, 0xe000).noprw(); map(0xe800, 0xe8ff).m("k051649", FUNC(k051649_device::scc_map)); map(0xf000, 0xf00f).rw(m_k053252, FUNC(k053252_device::read), FUNC(k053252_device::write)); map(0xf200, 0xf200).w("oki", FUNC(okim6295_device::write)); map(0xf400, 0xf400).portr("DSW1"); map(0xf401, 0xf401).portr("DSW2"); map(0xf402, 0xf402).portr("P1"); map(0xf403, 0xf403).portr("P2"); map(0xf440, 0xf440).portr("DSW3"); map(0xf441, 0xf441).portr("SYSTEM"); map(0xf480, 0xf480).w(this, FUNC(hexion_state::bankswitch_w)); map(0xf4c0, 0xf4c0).w(this, FUNC(hexion_state::coincntr_w)); map(0xf500, 0xf500).w(this, FUNC(hexion_state::gfxrom_select_w)); map(0xf540, 0xf540).r("watchdog", FUNC(watchdog_timer_device::reset_r)); } void hexion_state::hexionb_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0x9fff).bankr("bank1"); map(0xa000, 0xbfff).ram(); map(0xc000, 0xdffe).rw(this, FUNC(hexion_state::bankedram_r), FUNC(hexion_state::bankedram_w)); map(0xdfff, 0xdfff).w(this, FUNC(hexion_state::bankctrl_w)); map(0xe000, 0xe000).noprw(); map(0xe800, 0xe87f).noprw(); // all the code to use the k051649 is still present map(0xe880, 0xe889).noprw(); // but the bootleg has an additional M6295 @ 0xf5c0 instead map(0xe88a, 0xe88e).noprw(); map(0xe88f, 0xe88f).noprw(); map(0xe8e0, 0xe8ff).noprw(); map(0xf000, 0xf00f).rw(m_k053252, FUNC(k053252_device::read), FUNC(k053252_device::write)); map(0xf200, 0xf200).w("oki", FUNC(okim6295_device::write)); map(0xf400, 0xf400).portr("DSW1"); map(0xf401, 0xf401).portr("DSW2"); map(0xf402, 0xf402).portr("P1"); map(0xf403, 0xf403).portr("P2"); map(0xf440, 0xf440).portr("DSW3"); map(0xf441, 0xf441).portr("SYSTEM"); map(0xf480, 0xf480).w(this, FUNC(hexion_state::bankswitch_w)); map(0xf4c0, 0xf4c0).w(this, FUNC(hexion_state::coincntr_w)); map(0xf500, 0xf500).w(this, FUNC(hexion_state::gfxrom_select_w)); map(0xf540, 0xf540).r("watchdog", FUNC(watchdog_timer_device::reset_r)); map(0xf5c0, 0xf5c0).w("oki2", FUNC(okim6295_device::write)); } static INPUT_PORTS_START( hexion ) PORT_START("DSW1") KONAMI_COINAGE_LOC(DEF_STR( Free_Play ), DEF_STR( Free_Play ), SW1) PORT_START("DSW2") PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_DIPNAME( 0x70, 0x40, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:5,6,7") PORT_DIPSETTING( 0x70, DEF_STR( Easiest ) ) // "1" PORT_DIPSETTING( 0x60, DEF_STR( Very_Easy) ) // "2" PORT_DIPSETTING( 0x50, DEF_STR( Easy ) ) // "3" PORT_DIPSETTING( 0x40, DEF_STR( Medium ) ) // "4" PORT_DIPSETTING( 0x30, DEF_STR( Medium_Hard ) ) // "5" PORT_DIPSETTING( 0x20, DEF_STR( Hard ) ) // "6" PORT_DIPSETTING( 0x10, DEF_STR( Very_Hard ) ) // "7" PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) // "8" 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_DIPNAME( 0x01, 0x01, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW3:1") PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_BIT( 0xfa, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_SERVICE_DIPLOC( 0x04, IP_ACTIVE_LOW, "SW3:3" ) PORT_START("P1") KONAMI8_B12_START(1) PORT_START("P2") KONAMI8_B12_START(2) PORT_START("SYSTEM") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) /* 052591? game waits for it to be 0 */ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END static const gfx_layout charlayout = { 8,8, RGN_FRAC(1,2), 4, { 0, 1, 2, 3 }, { RGN_FRAC(1,2)+0*4, RGN_FRAC(1,2)+1*4, 0*4, 1*4, RGN_FRAC(1,2)+2*4, RGN_FRAC(1,2)+3*4, 2*4, 3*4 }, { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, 16*8 }; static GFXDECODE_START( gfx_hexion ) GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 16 ) GFXDECODE_END TIMER_DEVICE_CALLBACK_MEMBER(hexion_state::scanline) { int scanline = param; // z80 /IRQ is connected to the IRQ1(vblank) pin of k053252 CCU if(scanline == 256) m_maincpu->set_input_line(0, ASSERT_LINE); // z80 /NMI is connected to the IRQ2 pin of k053252 CCU // the following code is emulating INT_TIME of the k053252, this code will go away // when the new konami branch is merged. m_ccu_int_time_count--; if (m_ccu_int_time_count <= 0) { m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); m_ccu_int_time_count = m_ccu_int_time; } } MACHINE_CONFIG_START(hexion_state::hexion) /* basic machine hardware */ MCFG_DEVICE_ADD("maincpu", Z80, XTAL(24'000'000)/4) /* Z80B 6 MHz @ 17F, xtal verified, divider not verified */ MCFG_DEVICE_PROGRAM_MAP(hexion_map) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", hexion_state, scanline, "screen", 0, 1) MCFG_WATCHDOG_ADD("watchdog") MCFG_DEVICE_ADD("k053252", K053252, XTAL(24'000'000)/2) /* K053252, X0-010(?) @8D, xtal verified, divider not verified */ MCFG_K053252_INT1_ACK_CB(WRITELINE(*this, hexion_state, irq_ack_w)) MCFG_K053252_INT2_ACK_CB(WRITELINE(*this, hexion_state, nmi_ack_w)) MCFG_K053252_INT_TIME_CB(WRITE8(*this, hexion_state, ccu_int_time_w)) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MCFG_SCREEN_SIZE(64*8, 36*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 64*8-1, 0*8, 32*8-1) MCFG_SCREEN_UPDATE_DRIVER(hexion_state, screen_update) MCFG_SCREEN_PALETTE("palette") MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_hexion) MCFG_PALETTE_ADD_RRRRGGGGBBBB_PROMS("palette", "proms", 256) /* sound hardware */ SPEAKER(config, "mono").front_center(); MCFG_DEVICE_ADD("oki", OKIM6295, 1056000, okim6295_device::PIN7_HIGH) /* MSM6295GS @ 5E, clock frequency & pin 7 not verified */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MCFG_K051649_ADD("k051649", XTAL(24'000'000)/16) /* KONAMI 051649 // 2212P003 // JAPAN 8910EAJ @ 1D, xtal verified, divider not verified */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END MACHINE_CONFIG_START(hexion_state::hexionb) hexion(config); MCFG_DEVICE_MODIFY("maincpu") MCFG_DEVICE_PROGRAM_MAP(hexionb_map) MCFG_DEVICE_REMOVE("k051649") MCFG_DEVICE_ADD("oki2", OKIM6295, 1056000, okim6295_device::PIN7_LOW) // clock frequency & pin 7 not verified; this clock and pin 7 being low makes the pitch match the non-bootleg version, so is probably correct MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END /*************************************************************************** Game driver(s) ***************************************************************************/ ROM_START( hexion ) ROM_REGION( 0x34800, "maincpu", 0 ) /* ROMs + space for additional RAM */ ROM_LOAD( "122__j_a__b01.16f", 0x00000, 0x20000, CRC(eabc6dd1) SHA1(e74c1f1f2fcf8973f0741a2d544f25c8639448bf) ) /* "122 // J A // B01" @16F (27c010?) */ ROM_RELOAD( 0x10000, 0x20000 ) /* banked at 8000-9fff */ ROM_REGION( 0x80000, "gfx1", 0 ) /* addressable by the main CPU */ ROM_LOAD( "122a07.1h", 0x00000, 0x40000, CRC(22ae55e3) SHA1(41bdc990f69416b639542e2186a3610c16389063) ) /* Later pcbs have mask roms labeled: "KONAMI // 055066 // 122A07 // 233505" @1H (maybe mismarked 2H on pcb?) */ ROM_LOAD( "122a06.1g", 0x40000, 0x40000, CRC(438f4388) SHA1(9e23805c9642a237daeaf106187d1e1e0692434d) ) /* Later pcbs have mask roms labeled: "KONAMI // 055065 // 122A06 // 233506" @1G */ ROM_REGION( 0x40000, "oki", 0 ) /* OKIM6295 samples */ ROM_LOAD( "122a05.2f", 0x0000, 0x40000, CRC(bcc831bf) SHA1(c3382065dd0069a4dc0bde2d9931ec85b0bffc73) ) /* Later pcbs have mask roms labeled: "KONAMI // 055064 // 122A05 // 233507" @2F (maybe 2G? marking isn't visible in the picture I have) */ ROM_REGION( 0x0300, "proms", 0 ) ROM_LOAD( "122a04.10b", 0x0000, 0x0100, CRC(506eb8c6) SHA1(3bff7cf286942d8bdbc3998245c3de20981fbecb) ) // AMD27S21 == 82S129 ROM_LOAD( "122a03.11b", 0x0100, 0x0100, CRC(590c4f64) SHA1(db4b34f8c5fdfea034a94d65873f6fb842f123e9) ) // AMD27S21 == 82S129 ROM_LOAD( "122a02.13b", 0x0200, 0x0100, CRC(5734305c) SHA1(c72e59acf79a4db1a5a9d827eef899c0675336f2) ) // AMD27S21 == 82S129 // there are also two PALs of unknown type on the pcb: //054843 @12F //054844 @12H(12I?) ROM_END ROM_START( hexionb ) ROM_REGION( 0x34800, "maincpu", 0 ) /* ROMs + space for additional RAM */ ROM_LOAD( "hexionb.u2", 0x00000, 0x20000, CRC(93edc5d4) SHA1(d14c5be85a67eebddda9103bdf19de8c3c05d3af) ) ROM_RELOAD( 0x10000, 0x20000 ) /* banked at 8000-9fff */ ROM_REGION( 0x80000, "gfx1", 0 ) /* addressable by the main CPU */ ROM_LOAD( "hexionb.u30", 0x00000, 0x40000, CRC(22ae55e3) SHA1(41bdc990f69416b639542e2186a3610c16389063) ) // == 122a07.1h ROM_LOAD( "hexionb.u29", 0x40000, 0x40000, CRC(438f4388) SHA1(9e23805c9642a237daeaf106187d1e1e0692434d) ) // == 122a06.1g ROM_REGION( 0x40000, "oki", 0 ) /* OKIM6295 samples */ ROM_LOAD( "hexionb.u16", 0x0000, 0x40000, CRC(bcc831bf) SHA1(c3382065dd0069a4dc0bde2d9931ec85b0bffc73) ) // == 122a05.2f ROM_REGION( 0x40000, "oki2", 0 ) /* OKIM6295 samples */ ROM_LOAD( "hexionb.u18", 0x0000, 0x40000, CRC(c179d315) SHA1(b39d5ec8a90b7ae06763191b8324f32fe1d0ca9b) ) ROM_REGION( 0x0300, "proms", 0 ) ROM_LOAD( "82s129.u36", 0x0000, 0x0100, CRC(506eb8c6) SHA1(3bff7cf286942d8bdbc3998245c3de20981fbecb) ) ROM_LOAD( "82s129.u37", 0x0100, 0x0100, CRC(590c4f64) SHA1(db4b34f8c5fdfea034a94d65873f6fb842f123e9) ) ROM_LOAD( "82s129.u38", 0x0200, 0x0100, CRC(5734305c) SHA1(c72e59acf79a4db1a5a9d827eef899c0675336f2) ) // there are also two PALs on the bootleg: //PAL20L10 @U12 //PAL20L10 @U31 ROM_END GAME( 1992, hexion, 0, hexion, hexion, hexion_state, empty_init, ROT0, "Konami", "Hexion (Japan ver JAB)", 0 ) GAME( 1992, hexionb, hexion, hexionb, hexion, hexion_state, empty_init, ROT0, "bootleg (Impeuropex Corp.)", "Hexion (Asia ver AAA, bootleg)", 0 ) // we're missing an original Asia AAA