diff options
Diffstat (limited to 'src/mame/msx/sfkick.cpp')
-rw-r--r-- | src/mame/msx/sfkick.cpp | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/src/mame/msx/sfkick.cpp b/src/mame/msx/sfkick.cpp new file mode 100644 index 00000000000..f6e4a3bc414 --- /dev/null +++ b/src/mame/msx/sfkick.cpp @@ -0,0 +1,523 @@ +// license:BSD-3-Clause +// copyright-holders:Tomasz Slanina +/* + Super Free Kick / Spinkick by HEC (Haesung Enterprise Co.) + + driver by Tomasz Slanina + + Hacked MSX2 home computer hardware. Romset contains + modified ( (c) strings removed and patched boot sequence) + MSX2 bios. Yamaha VDP v9938 is hidden in huge epoxy block. + There's also an additional Z80 to drive sound. + + + 1 2 3 4 5 6 7 ++----------------------------------------------------------------+ +| | +| C1182 Y3014B YM2203C Z80A a7 | A +| | +| 1UP GL324 | B +| c7 | +| 2UP c5 | C +| | ++-+ DSW1 74139 6116 d7 | D + | 21.47727 MHz | ++-+ 74241 CN1 74244 | E +| | +| DSW2 74373 | G +| | +| 74241 4464 4464 7404 74139 h7 | H +| J CN2 | +| A 74157 4464 4464 7400 74670 | J +| M j7 | +| M 40106 74169 7404 7432 74670 | K +| A | +| 74241 74169 74138 7432 7402 l7 | L +| | ++-+ 74241 74153 74139 74138 74138 6264 | M + | | ++-+ 74241 82C55 Z80A 6264 | N +| | ++----------------------------------------------------------------+ + +Board # CBK1029 + +CN1: 40 PIN Connector (Epoxy Block ) +CN2: 8 PIN Connector (Epoxy Block) +1UP: 4 PIN Connector (Analog Controls) +2UP: 4 PIN Connector (Analog Controls) + +Z8400A (x2) +UM82C55A-PC +YM2203C + +Documentation as per manual: + + Main Jamma Connector + Solder Side | Parts Side +------------------------------------------------------------------ + GND | A | 1 | GND + GND | B | 2 | GND + +5 | C | 3 | +5 + +5 | D | 4 | +5 + | E | 5 | + +12 | F | 6 | +12 +----- KEY -----| H | 7 |----- KEY ----- + | J | 8 | + | K | 9 | + Speaker (-) | L | 10| Speaker (+) + | M | 11| + Video Green | N | 12| Video Red + Video Sync | P | 13| Video Blue + Player 1 Left | R | 14| Player 2 Right +Player 1 Right | S | 15| Player 2 Left + Coin Switch 2 | T | 16| Coin Switch 1 +Player 2 Start | U | 17| Player 1 Start + | V | 18| + | W | 19| + | X | 20| + | Y | 21| +Player 2 Shoot | Z | 22| Player 1 Shoot + | a | 23| + | b | 24| + | c | 25| + | d | 26| + GND | e | 27| GND + GND | f | 28| GND + + ____ + / \ + | Dial | + \____/ + /| |\ + / | | \ + Blue Red Black Yellow + / | | \ +Left +5v GND Right + + +DIPSW-1 +------------------------------------------------------------------ + DipSwitch Title | Function | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | +------------------------------------------------------------------ + Cabinet Style | Upright |off| | + | Cocktail |on | | +------------------------------------------------------------------ + Stage Select | Off | |off| | + | On | |on | | +------------------------------------------------------------------ + Freeze Screen | Off | |off| | + | On | |on | | +------------------------------------------------------------------ + Test / Game Mode | Game | |off| | + | Test | |on | | +------------------------------------------------------------------ + Allow Continue | Off | |off| | + | On | |on | | +------------------------------------------------------------------ + | 1cn/1cr | |off|off|off| + | 1cn/2cr | |on |off|off| + | 1cn/3cr | |off|on |off| + Coinage | 1cn/5cr | |on |on |off| + | 2cn/1cr | |off|off|on | + | 2cn/3cr | |on |off|on | + | 3cn/1cr | |off|on |on | + | 3cn/2cr | |on |on |on | +------------------------------------------------------------------ + +DIPSW-2 +------------------------------------------------------------------ + DipSwitch Title | Function | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | +------------------------------------------------------------------ + No Comment | N/A |off| | +------------------------------------------------------------------ + Demo Sounds | Yes | |off| | + | No | |on | | +------------------------------------------------------------------ + | 1 | |off|off| | + Players Count | 2 | |on |off| | + | 3 | |off|on | | + | 5 | |on |on | | +----------------------------------------------------------------- + | None | |off|off| | + Bonus |Every 20K | |on |off| | + |20K & 50K | |off|on | | + |Every 50K | |on |on | | +------------------------------------------------------------------ + | Easy | |off|off| + Difficulty | Normal | |on |off| + | Hard | |off|on | + | V.Hard | |on |on | +------------------------------------------------------------------ + +*/ + +#include "emu.h" + +#include "cpu/z80/z80.h" +#include "machine/bankdev.h" +#include "machine/gen_latch.h" +#include "machine/i8255.h" +#include "sound/ymopn.h" +#include "video/v9938.h" + +#include "screen.h" +#include "speaker.h" + + +namespace { + +class sfkick_state : public driver_device +{ +public: + sfkick_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_soundcpu(*this, "soundcpu"), + m_page(*this, "page%u", 0U), + m_bank(*this, "bank%u", 0U), + m_in0(*this, "IN0"), + m_in1(*this, "IN1"), + m_dial(*this, "DIAL"), + m_dsw1(*this, "DSW1"), + m_dsw2(*this, "DSW2") + { } + + void sfkick(machine_config &config); + +protected: + virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; + +private: + uint8_t mem_r(offs_t offset); + void mem_w(offs_t offset, uint8_t data); + void bank_w(offs_t offset, uint8_t data); + uint8_t ppi_port_b_r(); + void ppi_port_a_w(uint8_t data); + void ppi_port_c_w(uint8_t data); + void irqhandler(int state); + void sfkick_io_map(address_map &map) ATTR_COLD; + void sfkick_map(address_map &map) ATTR_COLD; + void sfkick_sound_io_map(address_map &map) ATTR_COLD; + void sfkick_sound_map(address_map &map) ATTR_COLD; + void bank_mem(address_map &map) ATTR_COLD; + + uint8_t m_primary_slot_reg = 0; + uint8_t m_input_mux = 0; + + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_soundcpu; + required_device_array<address_map_bank_device, 4> m_page; + required_memory_bank_array<8> m_bank; + required_ioport m_in0; + required_ioport m_in1; + required_ioport m_dial; + required_ioport m_dsw1; + required_ioport m_dsw2; +}; + + +#define MASTER_CLOCK XTAL(21'477'272) + +uint8_t sfkick_state::mem_r(offs_t offset) +{ + return m_page[offset >> 14 & 3]->read8(offset); +} + +void sfkick_state::mem_w(offs_t offset, uint8_t data) +{ + m_page[offset >> 14 & 3]->write8(offset, data); +} + +void sfkick_state::bank_w(offs_t offset, uint8_t data) +{ + m_bank[offset >> 13 & 7]->set_entry(data & 0xf); +} + +uint8_t sfkick_state::ppi_port_b_r() +{ + switch(m_input_mux & 0x0f) + { + case 0: return m_in0->read(); + case 1: return m_in1->read(); + case 2: return bitswap<8>(m_dial->read(), 4, 5, 6, 7, 3, 2, 1, 0); + case 3: return m_dsw1->read(); + case 4: return m_dsw2->read(); + } + return 0xff; +} + +void sfkick_state::ppi_port_a_w(uint8_t data) +{ + if (data != m_primary_slot_reg) + { + for (int i = 0; i < 4; i++) + m_page[i]->set_bank(data >> (i * 2) & 3); + + m_primary_slot_reg = data; + } +} + +void sfkick_state::sfkick_map(address_map &map) +{ + map(0x0000, 0xffff).rw(FUNC(sfkick_state::mem_r), FUNC(sfkick_state::mem_w)); // 4 pages of 16KB +} + +void sfkick_state::bank_mem(address_map &map) +{ + // slot 0, MSX BIOS + map(0x00000, 0x07fff).rom().region("bios", 0); + map(0x08000, 0x0bfff).rom().region("cartridge", 0x4000); + + // slot 1, extrom + map(0x10000, 0x13fff).rom().region("extrom", 0x4000); + + // slot 2, banked + map(0x20000, 0x21fff).bankr(m_bank[0]); + map(0x22000, 0x23fff).bankr(m_bank[1]); + map(0x24000, 0x25fff).bankr(m_bank[2]); + map(0x26000, 0x27fff).bankr(m_bank[3]); + map(0x28000, 0x29fff).bankr(m_bank[4]); + map(0x2a000, 0x2bfff).bankr(m_bank[5]); + map(0x2c000, 0x2dfff).bankr(m_bank[6]); + map(0x2e000, 0x2ffff).bankr(m_bank[7]); + map(0x20000, 0x2ffff).w(FUNC(sfkick_state::bank_w)); + + // slot 3, 16KB RAM + map(0x3c000, 0x3ffff).ram(); +} + +void sfkick_state::sfkick_io_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xff); + map(0xa0, 0xa7).w("soundlatch", FUNC(generic_latch_8_device::write)); + map(0x98, 0x9b).rw("v9938", FUNC(v9938_device::read), FUNC(v9938_device::write)); + map(0xa8, 0xab).rw("ppi8255", FUNC(i8255_device::read), FUNC(i8255_device::write)); + map(0xb4, 0xb5).ram(); // loopback ? req by sfkicka (MSX BIOS leftover) +} + +void sfkick_state::sfkick_sound_map(address_map &map) +{ + map(0x0000, 0x7fff).rom(); + map(0xc000, 0xc7ff).ram(); +} + +void sfkick_state::sfkick_sound_io_map(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x00).r("soundlatch", FUNC(generic_latch_8_device::read)); + map(0x04, 0x05).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); +} + +void sfkick_state::ppi_port_c_w(uint8_t data) +{ + m_input_mux = data; +} + +static INPUT_PORTS_START( sfkick ) + PORT_START("IN0") + PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED ) // unused ? + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + + PORT_START("IN1") + PORT_BIT( 0x71, IP_ACTIVE_LOW, IPT_UNUSED ) // unused ? + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 ) + + PORT_START("DIAL") + PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(20) PORT_REVERSE + + PORT_START("DSW1") // bitswapped at read! 76543210 -> 45673210 + PORT_DIPNAME( 0x10, 0x10, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x10, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) + PORT_DIPNAME( 0x01, 0x01, "Stage Select" ) PORT_DIPLOCATION("SW1:2") // How does this work?? + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x20, 0x20, "Freeze" ) PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x02, "Test Mode" ) PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x40, 0x00, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING( 0x40, DEF_STR( No ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x8c, 0x8c, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:6,8,7") + PORT_DIPSETTING( 0x04, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x84, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 3C_2C ) ) + PORT_DIPSETTING( 0x8c, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x80, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x88, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x0c, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) + + PORT_START("DSW2") // bitswapped at read! 76543210 -> 45673210 + PORT_DIPUNUSED_DIPLOC( 0x10, IP_ACTIVE_LOW, "SW2:1" ) // Manual states "No Comment" + PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x20, DEF_STR( On ) ) + PORT_DIPNAME( 0x41, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x41, "1" ) + PORT_DIPSETTING( 0x40, "2" ) + PORT_DIPSETTING( 0x01, "3" ) + PORT_DIPSETTING( 0x00, "5" ) + PORT_DIPNAME( 0x82, 0x02, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x80, "Every 20,000" ) + PORT_DIPSETTING( 0x02, "20,000 & 50,000" ) + PORT_DIPSETTING( 0x00, "Every 50,000" ) + PORT_DIPSETTING( 0x82, DEF_STR( None ) ) + PORT_DIPNAME( 0x0c, 0x08, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:7,8") + PORT_DIPSETTING( 0x0c, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x08, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) +INPUT_PORTS_END + +void sfkick_state::machine_start() +{ + // init banks + for (int i = 0; i < 8; i++) + m_bank[i]->configure_entries(0, 0x10, memregion("banked")->base(), 0x2000); + + save_item(NAME(m_primary_slot_reg)); + save_item(NAME(m_input_mux)); +} + +void sfkick_state::machine_reset() +{ + m_primary_slot_reg = 0; + m_input_mux = 0; + + for (int i = 0; i < 4; i++) + m_page[i]->set_bank(0); + for (int i = 0; i < 8; i++) + m_bank[i]->set_entry(i); +} + +void sfkick_state::irqhandler(int state) +{ + m_soundcpu->set_input_line_and_vector(0, state ? ASSERT_LINE : CLEAR_LINE, 0xff); // Z80 +} + +void sfkick_state::sfkick(machine_config &config) +{ + Z80(config, m_maincpu, MASTER_CLOCK/6); + m_maincpu->set_addrmap(AS_PROGRAM, &sfkick_state::sfkick_map); + m_maincpu->set_addrmap(AS_IO, &sfkick_state::sfkick_io_map); + + config.set_maximum_quantum(attotime::from_hz(60000)); + + Z80(config, m_soundcpu, MASTER_CLOCK/6); + m_soundcpu->set_addrmap(AS_PROGRAM, &sfkick_state::sfkick_sound_map); + m_soundcpu->set_addrmap(AS_IO, &sfkick_state::sfkick_sound_io_map); + + ADDRESS_MAP_BANK(config, m_page[0]).set_map(&sfkick_state::bank_mem).set_options(ENDIANNESS_LITTLE, 8, 18, 0x10000); + ADDRESS_MAP_BANK(config, m_page[1]).set_map(&sfkick_state::bank_mem).set_options(ENDIANNESS_LITTLE, 8, 18, 0x10000); + ADDRESS_MAP_BANK(config, m_page[2]).set_map(&sfkick_state::bank_mem).set_options(ENDIANNESS_LITTLE, 8, 18, 0x10000); + ADDRESS_MAP_BANK(config, m_page[3]).set_map(&sfkick_state::bank_mem).set_options(ENDIANNESS_LITTLE, 8, 18, 0x10000); + + v9938_device &v9938(V9938(config, "v9938", MASTER_CLOCK)); + v9938.set_screen_ntsc("screen"); + v9938.set_vram_size(0x80000); + v9938.int_cb().set_inputline(m_maincpu, 0); + SCREEN(config, "screen", SCREEN_TYPE_RASTER); + + i8255_device &ppi(I8255A(config, "ppi8255")); + ppi.out_pa_callback().set(FUNC(sfkick_state::ppi_port_a_w)); + ppi.in_pb_callback().set(FUNC(sfkick_state::ppi_port_b_r)); + ppi.out_pc_callback().set(FUNC(sfkick_state::ppi_port_c_w)); + + SPEAKER(config, "mono").front_center(); + + GENERIC_LATCH_8(config, "soundlatch"); + + ym2203_device &ym1(YM2203(config, "ym1", MASTER_CLOCK/6)); + ym1.irq_handler().set(FUNC(sfkick_state::irqhandler)); + ym1.add_route(0, "mono", 0.25); + ym1.add_route(1, "mono", 0.25); + ym1.add_route(2, "mono", 0.25); + ym1.add_route(3, "mono", 0.50); +} + + +ROM_START( sfkick ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + + ROM_REGION(0x20000, "banked", ROMREGION_ERASEFF) + ROM_LOAD( "sfkick2.a7", 0x00000, 0x8000, CRC(1dcaec5e) SHA1(7e063d46fb6606df2d772866cc55f207035b98c4) ) + ROM_LOAD( "sfkick3.c7", 0x08000, 0x8000, CRC(639d3cf2) SHA1(950fd28058d32e4532eb6e99454dcaef092a955e) ) + ROM_LOAD( "sfkick4.d7", 0x10000, 0x8000, CRC(ee1b344e) SHA1(d33fbad017cc4838192e9c540621537edb7e8dc4) ) + // 0x18000-0x1ffff = empty + + ROM_REGION(0x8000, "extrom", 0) + ROM_LOAD( "sfkick5.h7", 0x00000, 0x8000, CRC(8e8bd9cf) SHA1(f493de40147fdd67a48d4c90b01170fbd6ea074e) ) + + ROM_REGION(0x8000, "cartridge", 0) + ROM_LOAD( "sfkick6.j7", 0x0000, 0x8000, CRC(7a91ac4b) SHA1(afc5e2c2fe0cd108235ac6ae2775cc9a0b1c9f76) ) + + ROM_REGION(0x8000, "bios", 0) + ROM_LOAD( "sfkick7.l7", 0x00000, 0x8000, CRC(8cd94c63) SHA1(e6dba66c8716593b8ab88f79f7205211938d1598) ) + + ROM_REGION(0x10000, "soundcpu", 0) + ROM_LOAD( "sfkick1.c5", 0x00000, 0x8000, CRC(2f5e3b7a) SHA1(d2ff566b415ab10c0681fa1eb221a56e3c137ecf) ) +ROM_END + + +ROM_START( sfkicka ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + + ROM_REGION(0x20000, "banked", ROMREGION_ERASEFF) + ROM_LOAD( "c145.bin", 0x00000, 0x8000, CRC(1dcaec5e) SHA1(7e063d46fb6606df2d772866cc55f207035b98c4) ) + ROM_LOAD( "c146.bin", 0x08000, 0x8000, CRC(57afc4c6) SHA1(ee28b3f74e3175c22f542855b09f1673d048b1fa) ) + ROM_LOAD( "c147.bin", 0x10000, 0x8000, CRC(ee1b344e) SHA1(d33fbad017cc4838192e9c540621537edb7e8dc4) ) + // 0x18000-0x1ffff = empty + + ROM_REGION(0x8000, "extrom", 0) + ROM_LOAD( "c149.bin", 0x00000, 0x8000, CRC(2edbf61f) SHA1(23dcff43faf222a4b69001312ce4b1c920e2f4c2) ) + + ROM_REGION(0x8000, "cartridge", 0) + ROM_LOAD( "c150.bin", 0x0000, 0x8000, CRC(20412918) SHA1(b0fefa957b20373ffb84d9ff97a2e84a9a3af56c) ) + + ROM_REGION(0x8000, "bios", 0) + ROM_LOAD( "c151.bin", 0x00000, 0x8000, CRC(8cd94c63) SHA1(e6dba66c8716593b8ab88f79f7205211938d1598) ) + + ROM_REGION(0x10000, "soundcpu", 0) + ROM_LOAD( "c130.bin", 0x00000, 0x8000, CRC(2f5e3b7a) SHA1(d2ff566b415ab10c0681fa1eb221a56e3c137ecf) ) +ROM_END + + +ROM_START( spinkick ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + + ROM_REGION(0x20000, "banked", ROMREGION_ERASEFF) + ROM_LOAD( "spinkick.r2", 0x00000, 0x8000, CRC(1dcaec5e) SHA1(7e063d46fb6606df2d772866cc55f207035b98c4) ) + ROM_LOAD( "spinkick.r3", 0x08000, 0x8000, CRC(e86a194a) SHA1(19a02375ec463e795770403c3e948d754919458b) ) + ROM_LOAD( "spinkick.r4", 0x10000, 0x8000, CRC(ee1b344e) SHA1(d33fbad017cc4838192e9c540621537edb7e8dc4) ) + // 0x18000-0x1ffff = empty + + ROM_REGION(0x8000, "extrom", 0) + ROM_LOAD( "spinkick.r5", 0x00000, 0x8000, CRC(8e8bd9cf) SHA1(f493de40147fdd67a48d4c90b01170fbd6ea074e) ) + + ROM_REGION(0x8000, "cartridge", 0) + ROM_LOAD( "spinkick.r6", 0x0000, 0x8000, CRC(7a91ac4b) SHA1(afc5e2c2fe0cd108235ac6ae2775cc9a0b1c9f76) ) + + ROM_REGION(0x8000, "bios", 0) + ROM_LOAD( "spinkick.r7", 0x00000, 0x8000, CRC(8cd94c63) SHA1(e6dba66c8716593b8ab88f79f7205211938d1598) ) + + ROM_REGION(0x10000, "soundcpu", 0) + ROM_LOAD( "spinkick.r1", 0x00000, 0x8000, CRC(2f5e3b7a) SHA1(d2ff566b415ab10c0681fa1eb221a56e3c137ecf) ) +ROM_END + +} // anonymous namespace + + +GAME( 1988, sfkick, 0, sfkick, sfkick, sfkick_state, empty_init, ROT90, "Haesung/HJ Corp", "Super Free Kick (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 198?, sfkicka, sfkick, sfkick, sfkick, sfkick_state, empty_init, ROT90, "Haesung", "Super Free Kick (set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1988, spinkick, sfkick, sfkick, sfkick, sfkick_state, empty_init, ROT90, "Haesung/Seojin", "Hec's Spinkick", MACHINE_SUPPORTS_SAVE ) |