summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/g627.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/g627.cpp')
-rw-r--r--src/mame/drivers/g627.cpp335
1 files changed, 335 insertions, 0 deletions
diff --git a/src/mame/drivers/g627.cpp b/src/mame/drivers/g627.cpp
new file mode 100644
index 00000000000..c3b19d87b6c
--- /dev/null
+++ b/src/mame/drivers/g627.cpp
@@ -0,0 +1,335 @@
+// license:BSD-3-Clause
+// copyright-holders:Robbbert
+/******************************************************************************
+
+ PINBALL
+ Midway A084-91313-G627
+ A080-91313-G627
+ A082-91320-C000
+
+ Only one of its kind
+
+ This is a cocktail pinball game, for up to 4 players. The board is round.
+ When it is another player's turn, the playboard will turn around to face
+ him. And so, the system has a motor and an infrared shaft-locating system.
+ If this system does not return the expected data, the machine will refuse
+ to start.
+
+ Schematic and PinMAME used as references
+ System made working in Sept 2012 [Robbbert]
+
+Machine Operation:
+1. Press .(period key) (this sets up nvram and the displays will flash 400000)
+2. Insert a coin, credit will be registered
+3. Hold X and start game. When 00 is flashing, release X
+4. Press any of QWERYUIOASDFGHJKLZ-='; to simulate scoring shots (T will tilt)
+5. Press and hold X to simulate losing the ball
+6. When score starts flashing, release X and go to step 4 to play next ball
+
+Note: You can start play at any of the 4 stations, and the table will rotate
+ as needed. Multiplayer works as well.
+
+The manual explains the tests available, and also how to set number of balls,
+high score, etc., with the diagnostic keyboard.
+
+ToDo:
+- Lamp outputs
+- Possibility of a rom missing (most likely it is optional)
+
+*******************************************************************************/
+
+
+#include "machine/genpin.h"
+#include "cpu/z80/z80.h"
+#include "machine/i8155.h"
+#include "sound/astrocde.h"
+#include "g627.lh"
+
+
+class g627_state : public genpin_class
+{
+public:
+ g627_state(const machine_config &mconfig, device_type type, const char *tag)
+ : genpin_class(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_switch(*this, "SWITCH")
+ , m_testipt(*this, "TEST")
+ { }
+
+ DECLARE_DRIVER_INIT(v115);
+ DECLARE_DRIVER_INIT(v117);
+ DECLARE_READ8_MEMBER(porta_r);
+ DECLARE_READ8_MEMBER(portb_r);
+ DECLARE_WRITE8_MEMBER(portc_w);
+ DECLARE_WRITE8_MEMBER(disp_w);
+ DECLARE_WRITE8_MEMBER(lamp_w);
+private:
+ UINT8 m_seg[6];
+ UINT8 m_portc;
+ UINT8 m_motor;
+ bool m_type;
+ required_device<cpu_device> m_maincpu;
+ required_ioport_array<7> m_switch;
+ required_ioport_array<6> m_testipt;
+};
+
+
+static ADDRESS_MAP_START( g627_map, AS_PROGRAM, 8, g627_state )
+ AM_RANGE(0x0000, 0x1fff) AM_ROM
+ AM_RANGE(0xc000, 0xc0ff) AM_DEVREADWRITE("i8156", i8155_device, memory_r, memory_w)
+ AM_RANGE(0xe000, 0xe0ff) AM_RAM AM_SHARE("nvram") // battery backed
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( g627_io, AS_IO, 8, g627_state )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x02) AM_WRITE(disp_w)
+ AM_RANGE(0x03, 0x07) AM_WRITE(lamp_w)
+ AM_RANGE(0x10, 0x17) AM_DEVWRITE("astrocade", astrocade_device, astrocade_sound_w)
+ AM_RANGE(0x20, 0x27) AM_DEVREADWRITE("i8156", i8155_device, io_r, io_w)
+ADDRESS_MAP_END
+
+static INPUT_PORTS_START( g627 )
+ PORT_START("SWITCH.0")
+ //bits 0,1 : optical encoder for precise table alignment. Correct position = 3.
+ //bit2-7 : position of table as it turns, using Gray code.
+ PORT_START("SWITCH.1")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Centre TB") PORT_CODE(KEYCODE_Q)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Bank Shot Outlane") PORT_CODE(KEYCODE_W)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Spinner") PORT_CODE(KEYCODE_E)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("8 Ball Target") PORT_CODE(KEYCODE_R)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_START3) PORT_NAME("Call East")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_START2) PORT_NAME("Call South")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_START1) PORT_NAME("Call North")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_START4) PORT_NAME("Call West")
+ PORT_START("SWITCH.2")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Bottom TB") PORT_CODE(KEYCODE_Y)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Left Flipper Return") PORT_CODE(KEYCODE_U)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3/11 Target") PORT_CODE(KEYCODE_I)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1/9 Target") PORT_CODE(KEYCODE_O)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("North Slam")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("North Test") PORT_CODE(KEYCODE_9)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN1) PORT_NAME("North Coin")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_TILT) PORT_NAME("North Tilt")
+ PORT_START("SWITCH.3")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Top Slingshot") PORT_CODE(KEYCODE_O)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Bank Shot Advance") PORT_CODE(KEYCODE_A)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4/12 Target") PORT_CODE(KEYCODE_S)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2/10 Target") PORT_CODE(KEYCODE_D)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("South Slam")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("South Test") PORT_CODE(KEYCODE_0)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN2) PORT_NAME("South Coin")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("South Tilt")
+ PORT_START("SWITCH.4")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Right Slingshot") PORT_CODE(KEYCODE_F)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("OutHole") PORT_CODE(KEYCODE_X)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("5/13 Target") PORT_CODE(KEYCODE_G)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4/16 Target") PORT_CODE(KEYCODE_H)
+ PORT_START("SWITCH.5")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Left Slingshot") PORT_CODE(KEYCODE_J)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Right Flipper Return") PORT_CODE(KEYCODE_K)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Right Out Lane") PORT_CODE(KEYCODE_L)
+ PORT_START("SWITCH.6")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Top TB") PORT_CODE(KEYCODE_COLON)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("7/15 Target") PORT_CODE(KEYCODE_QUOTE)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("10 Points") PORT_CODE(KEYCODE_EQUALS)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Break Shot Hole") PORT_CODE(KEYCODE_Z)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Left Out Lane") PORT_CODE(KEYCODE_MINUS)
+
+ // Diagnostic Keyboard: Press GAME then END then TEST#. Press GAME etc for more tests.
+ // Pressing test 8 at any time will instantly reset the NVRAM.
+ PORT_START("TEST.0")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3") PORT_CODE(KEYCODE_3_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD)
+ PORT_START("TEST.1")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("7") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("6") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("5") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD)
+ PORT_START("TEST.2")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("SET") PORT_CODE(KEYCODE_PLUS_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME(".") PORT_CODE(KEYCODE_DEL_PAD)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("9") PORT_CODE(KEYCODE_9_PAD)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("8") PORT_CODE(KEYCODE_8_PAD)
+ PORT_START("TEST.3")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 3") PORT_CODE(KEYCODE_B)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 2") PORT_CODE(KEYCODE_V)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 1") PORT_CODE(KEYCODE_C)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("GAME") PORT_CODE(KEYCODE_ENTER_PAD)
+ PORT_START("TEST.4")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 7")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 6") PORT_CODE(KEYCODE_COMMA)
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 5") PORT_CODE(KEYCODE_M)
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 4") PORT_CODE(KEYCODE_N)
+ PORT_START("TEST.5")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("END") PORT_CODE(KEYCODE_END)
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 10")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 9")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Test 8") PORT_CODE(KEYCODE_STOP)
+INPUT_PORTS_END
+
+DRIVER_INIT_MEMBER( g627_state, v115 )
+{
+ m_type = 0;
+}
+
+DRIVER_INIT_MEMBER( g627_state, v117 )
+{
+ m_type = 1;
+}
+
+// inputs
+READ8_MEMBER( g627_state::porta_r )
+{
+ if (!m_portc)
+ return ((m_motor >> 1)^m_motor) | 3; // convert to Gray Code
+ else if (m_portc < 7)
+ return m_switch[m_portc]->read();
+
+ return 0;
+}
+
+// diagnostic keyboard
+READ8_MEMBER( g627_state::portb_r )
+{
+ if (m_portc < 6)
+ return m_testipt[m_portc]->read();
+
+ return 0;
+}
+
+// display digits
+WRITE8_MEMBER( g627_state::portc_w )
+{
+ m_portc = data;
+ if ((m_type) && (data < 6))
+ {
+ output_set_digit_value(data, m_seg[0]);
+ output_set_digit_value(10 + data, m_seg[1]);
+ output_set_digit_value(20 + data, m_seg[2]);
+ output_set_digit_value(30 + data, m_seg[3]);
+ output_set_digit_value(50 + data, m_seg[5]);
+ }
+ else
+ if ((!m_type) && (data))
+ {
+ data--;
+
+ output_set_digit_value(data, m_seg[0]);
+ output_set_digit_value(10 + data, m_seg[1]);
+ output_set_digit_value(20 + data, m_seg[2]);
+ output_set_digit_value(30 + data, m_seg[3]);
+ output_set_digit_value(50 + data, m_seg[5]);
+ }
+}
+
+// save segments until we can write the digits
+WRITE8_MEMBER( g627_state::disp_w )
+{
+ static const UINT8 patterns[16] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x67,0x58,0x4c,0x62,0x69,0x78,0 }; // 7448
+ offset <<= 1;
+ m_seg[offset] = patterns[data>>4];
+ m_seg[++offset] = patterns[data&15];
+}
+
+// lamps and solenoids
+WRITE8_MEMBER( g627_state::lamp_w )
+{
+/* offset 0 together with m_portc activates the lamps.
+ offset 1 and 2 are solenoids.
+ offset 1:
+ d0 = Outhole
+ d1 = Bank shot
+ d2-4 = Bumper : centre, Bottom, Top
+ d5-7 = Sling Shot : Top, Right, Left
+ offset 2:
+ d0 = Break Shot
+ d1 = Motor clockwise*
+ d2 = Motor anti-clockwise*
+ d3 = 3 flippers
+ d4 = unknown*
+
+ * = undocumented
+
+ */
+
+ UINT16 solenoid = (offset << 8) | data;
+ switch (solenoid)
+ {
+ case 0x0101:
+ case 0x0120:
+ case 0x0140:
+ case 0x0180:
+ case 0x0201:
+ m_samples->start(0, 5);
+ break;
+ case 0x0104:
+ case 0x0108:
+ case 0x0110:
+ m_samples->start(1, 0);
+ break;
+ case 0x0202:
+ case 0x0212:
+ m_motor++;
+ break;
+ case 0x0204:
+ case 0x0214:
+ m_motor--;
+ break;
+ default:
+ break;
+ }
+}
+
+static MACHINE_CONFIG_START( g627, g627_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", Z80, 14138000/8)
+ MCFG_CPU_PROGRAM_MAP(g627_map)
+ MCFG_CPU_IO_MAP(g627_io)
+
+ MCFG_DEVICE_ADD("i8156", I8156, 14138000/8)
+ MCFG_I8155_IN_PORTA_CB(READ8(g627_state, porta_r))
+ MCFG_I8155_IN_PORTB_CB(READ8(g627_state, portb_r))
+ MCFG_I8155_OUT_PORTC_CB(WRITE8(g627_state, portc_w))
+ MCFG_I8155_OUT_TIMEROUT_CB(INPUTLINE("maincpu", INPUT_LINE_NMI))
+
+ MCFG_NVRAM_ADD_0FILL("nvram")
+
+ /* Sound */
+ MCFG_FRAGMENT_ADD( genpin_audio )
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("astrocade", ASTROCADE, 14138000/8) // 0066-117XX audio chip
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+
+ /* Video */
+ MCFG_DEFAULT_LAYOUT(layout_g627)
+MACHINE_CONFIG_END
+
+/*-------------------------------------------------------------------
+/ Rotation VIII (09/1978)
+/-------------------------------------------------------------------*/
+ROM_START(rotation)
+ ROM_REGION(0x10000, "maincpu", ROMREGION_ERASEFF)
+ ROM_LOAD("rot-a117.dat", 0x0000, 0x0800, CRC(7bb6beb3) SHA1(5ee62246032158c68d426c11a4a9a889ee7655d7))
+ ROM_LOAD("rot-b117.dat", 0x0800, 0x0800, CRC(538e37b2) SHA1(d283ac4d0024388b92b6494fcde63957b705bf48))
+ ROM_LOAD("rot-c117.dat", 0x1000, 0x0800, CRC(3321ff08) SHA1(d6d94fea27ef58ca648b2829b32d62fcec108c9b))
+ROM_END
+
+ROM_START(rota_115)
+ ROM_REGION(0x10000, "maincpu", ROMREGION_ERASEFF)
+ ROM_LOAD("v115-a.bin", 0x0000, 0x0800, CRC(474884b3) SHA1(b7919bf2e3a3897c1180373cccf88240c57b5645))
+ ROM_LOAD("v115-b.bin", 0x0800, 0x0800, CRC(8779fc6c) SHA1(df00f58d38b4eca68603247ae69009e13cfa31fb))
+ ROM_LOAD("v115-c.bin", 0x1000, 0x0800, CRC(54b420f9) SHA1(597bb9f8ad0b20babc696175e9fbcecf2d5d799d))
+ROM_END
+
+ROM_START(rota_101)
+ ROM_REGION(0x10000, "maincpu", ROMREGION_ERASEFF)
+ ROM_LOAD("v101-a.bin", 0x0000, 0x0800, CRC(e89f3de6) SHA1(0b62220a24e176f2d7838da080b447a3df9ce05d))
+ ROM_LOAD("v101-b.bin", 0x0800, 0x0800, CRC(0690670b) SHA1(6399a7df707d644d0b7fe7b4fea6fb5091a9883d))
+ ROM_LOAD("v101-c.bin", 0x1000, 0x0800, CRC(c7e85638) SHA1(b59805d8b558ab8f5ea5b4b9261e862afca4b9d3))
+ROM_END
+
+GAME(1978, rotation, 0, g627, g627, g627_state, v117, ROT0, "Midway", "Rotation VIII (v. 1.17)", MACHINE_MECHANICAL )
+GAME(1978, rota_115, rotation, g627, g627, g627_state, v115, ROT0, "Midway", "Rotation VIII (v. 1.15)", MACHINE_MECHANICAL )
+GAME(1978, rota_101, rotation, g627, g627, g627_state, v115, ROT0, "Midway", "Rotation VIII (v. 1.01)", MACHINE_MECHANICAL )