summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Luca Elia <lucaelia@mamedev.org>2017-02-06 19:36:22 +0100
committer Luca Elia <lucaelia@mamedev.org>2017-02-06 19:36:22 +0100
commita1f661cc31baf4b70115d97819e5621a1dd8d1d8 (patch)
tree220518761f9a031a86a8b30c0310fce1b54ef949
parent9bae6c46ba05213b49f3ba0143608f0b1b96a8eb (diff)
Missing galgames.cpp (nw)
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--src/mame/arcade.flt2
-rw-r--r--src/mame/drivers/galgames.cpp1161
-rw-r--r--src/mame/mame.lst8
4 files changed, 1167 insertions, 5 deletions
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index ae70c257390..0adda5e0498 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -1399,6 +1399,7 @@ files {
createMAMEProjects(_target, _subtarget, "ces")
files {
MAME_DIR .. "src/mame/drivers/cesclass.cpp",
+ MAME_DIR .. "src/mame/drivers/galgames.cpp",
}
createMAMEProjects(_target, _subtarget, "cinemat")
diff --git a/src/mame/arcade.flt b/src/mame/arcade.flt
index 960c570fbae..74b9df3d635 100644
--- a/src/mame/arcade.flt
+++ b/src/mame/arcade.flt
@@ -413,7 +413,7 @@ galaxia.cpp
galaxian.cpp
galaxold.cpp
galgame.cpp
-//galgames.cpp
+galgames.cpp
galivan.cpp
galpani2.cpp
galpani3.cpp
diff --git a/src/mame/drivers/galgames.cpp b/src/mame/drivers/galgames.cpp
new file mode 100644
index 00000000000..ac1f801a0a8
--- /dev/null
+++ b/src/mame/drivers/galgames.cpp
@@ -0,0 +1,1161 @@
+// license:BSD-3-Clause
+// copyright-holders:Luca Elia
+/***************************************************************************
+
+ -= Galaxy Games =-
+
+ driver by Luca Elia (l.elia@tin.it)
+
+
+CPU: 68000
+Video: Blitter with two layers and double buffering (Xilinx FPGA)
+Sound: OKI M6295
+Input: Trackballs and buttons
+Other: EEPROM
+Carts: EEPROM + Flash + PIC
+
+To Do:
+
+- Coin optics
+
+Notes:
+
+- 4 known game carts where produced, these are:
+
+ Star Pak 1: Seek the Peaks, 21 Thunder, Solar Solitaire, Prism Poker, Pharaoh's Tomb, Black Jack,
+ Twenty One Thunder Plus, Power Pairs, Prism Poker Plus & Have A Cow
+ Star Pak 2: Pack-Man, Ms.Pac-Man, Pharaoh's Tomb, Solar Solitaire, Power Pairs, Seek The peeks & Have A Cow
+ Star Pak 3: Centipede, Great Wall, Ker-Chunk, Diamond Derby, Word Sleuth, Pull!, Astro Blast & Sweeper
+ Star Pak 4: Berzerk, Neon Nightmare, Battle Checkers, Orbit, Deep Sea Shadow, Star Tiger & Orbit Freefall
+
+- Allegedly there is a hard lock that SP1 and the PAC-MAN games (on SP2) cannot play together. Was a licensing issue with Namco.
+ The system checks for cartridges on power up by querying the PIC parts. If the system sees SP1 & SP2 it disables SP2.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "cpu/m68000/m68000.h"
+#include "cpu/pic16c5x/pic16c5x.h"
+#include "machine/eepromser.h"
+#include "machine/watchdog.h"
+#include "sound/okim6295.h"
+#include "video/cesblit.h"
+
+/***************************************************************************
+
+ Galgames Cart Device
+
+ Each cartridge contains a PIC, that provides, among other things, a 32-byte
+ response starting with "CES1997", followed by the contents of the cart rom
+ at some fixed addresses.
+
+***************************************************************************/
+
+class galgames_slot_device;
+
+// CART declaration
+
+class galgames_cart_device : public device_t,
+ public device_rom_interface
+{
+public:
+ // construction/destruction
+ galgames_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // static configuration
+ static void static_set_cart(device_t &device, uint8_t cart) { downcast<galgames_cart_device &>(device).m_cart = cart; }
+ static void static_set_pic_bits(device_t &device, int clk, int in, int out, int dis) { downcast<galgames_cart_device &>(device).set_pic_bits(clk, in, out, dis); }
+
+ // ROM
+ DECLARE_READ16_MEMBER(rom_r) { return read_word(offset*2); }
+
+ // EEPROM
+ DECLARE_READ8_MEMBER(eeprom_r);
+ DECLARE_WRITE8_MEMBER(eeprom_w);
+ DECLARE_WRITE_LINE_MEMBER(eeprom_cs_write);
+
+ // PIC
+ DECLARE_READ8_MEMBER(pic_status_r);
+ DECLARE_WRITE8_MEMBER(pic_data_w);
+ DECLARE_READ8_MEMBER(pic_data_r);
+ void set_pic_reset_line(int state);
+
+ DECLARE_READ8_MEMBER(int_pic_data_r);
+ DECLARE_WRITE8_MEMBER(int_pic_data_w);
+ DECLARE_WRITE8_MEMBER(int_pic_bank_w);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override { }
+ virtual void device_reset() override;
+ virtual void rom_bank_updated() { }
+
+ bool is_selected();
+
+ machine_config_constructor m_mconfig_additions;
+ uint8_t m_cart;
+
+ // SLOT
+ required_device<galgames_slot_device> m_slot;
+
+ // EEPROM
+ optional_device<eeprom_serial_93cxx_device> m_eeprom;
+
+ // PIC
+ optional_device<pic16c5x_device> m_pic;
+
+ uint8_t m_pic_iobits, m_pic_data, m_pic_data_rdy, m_pic_data_bit, m_pic_data_clk;
+ uint8_t m_pic_clk_mask, m_pic_in_mask, m_pic_out_mask, m_pic_dis_mask;
+
+ void set_pic_bits(int clk, int in, int out, int dis);
+ void log_cart_comm(const char *text, uint8_t data);
+ void pic_comm_reset();
+};
+
+// device type definition
+const device_type GALGAMES_CART = &device_creator<galgames_cart_device>;
+
+#define MCFG_GALGAMES_CART_INDEX(_cart) \
+ galgames_cart_device::static_set_cart(*device, _cart);
+
+#define MCFG_GALGAMES_PIC_BITS(_clk, _in, _out, _dis) \
+ galgames_cart_device::static_set_pic_bits(*device, _clk, _in, _out, _dis);
+
+#define MCFG_GALGAMES_EMPTY_CART_ADD(_tag, _cart) \
+ MCFG_DEVICE_ADD(_tag, GALGAMES_CART, 0) \
+ MCFG_GALGAMES_CART_INDEX(_cart)
+
+
+
+// BIOS "cart"
+
+static MACHINE_CONFIG_FRAGMENT( bios )
+ MCFG_EEPROM_SERIAL_93C76_8BIT_ADD("eeprom")
+MACHINE_CONFIG_END
+
+class galgames_bios_cart_device : public galgames_cart_device
+{
+public:
+ // construction/destruction
+ galgames_bios_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ galgames_cart_device(mconfig, tag, owner, clock)
+ { }
+protected:
+ // device-level overrides
+ virtual machine_config_constructor device_mconfig_additions() const override { return MACHINE_CONFIG_NAME(bios); }
+};
+
+const device_type GALGAMES_BIOS_CART = &device_creator<galgames_bios_cart_device>;
+
+#define MCFG_GALGAMES_BIOS_CART_ADD(_tag, _cart) \
+ MCFG_DEVICE_ADD(_tag, GALGAMES_BIOS_CART, 0) \
+ MCFG_GALGAMES_CART_INDEX(_cart)
+
+
+
+// STARPAK2 cart
+
+static MACHINE_CONFIG_FRAGMENT( starpak2 )
+ MCFG_CPU_ADD("pic", PIC16C56, XTAL_4MHz) // !! PIC12C508 !! 4MHz internal RC oscillator (selected by the configuration word)
+ MCFG_PIC16C5x_READ_B_CB( READ8( galgames_cart_device, int_pic_data_r))
+ MCFG_PIC16C5x_WRITE_B_CB(WRITE8(galgames_cart_device, int_pic_data_w))
+
+ MCFG_EEPROM_SERIAL_93C76_8BIT_ADD("eeprom")
+MACHINE_CONFIG_END
+
+class galgames_starpak2_cart_device : public galgames_cart_device
+{
+public:
+ // construction/destruction
+ galgames_starpak2_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ galgames_cart_device(mconfig, tag, owner, clock)
+ { }
+protected:
+ // device-level overrides
+ virtual machine_config_constructor device_mconfig_additions() const override { return MACHINE_CONFIG_NAME(starpak2); }
+};
+
+const device_type GALGAMES_STARPAK2_CART = &device_creator<galgames_starpak2_cart_device>;
+
+#define MCFG_GALGAMES_STARPAK2_CART_ADD(_tag, _cart) \
+ MCFG_DEVICE_ADD(_tag, GALGAMES_STARPAK2_CART, 0) \
+ MCFG_GALGAMES_CART_INDEX(_cart) \
+ MCFG_GALGAMES_PIC_BITS(5, 4, 2, 1)
+
+
+
+// STARPAK3 cart
+
+static MACHINE_CONFIG_FRAGMENT( starpak3 )
+ MCFG_CPU_ADD("pic", PIC16C56, XTAL_4MHz)
+ MCFG_PIC16C5x_WRITE_A_CB(WRITE8(galgames_cart_device, int_pic_bank_w))
+ MCFG_PIC16C5x_READ_B_CB( READ8( galgames_cart_device, int_pic_data_r))
+ MCFG_PIC16C5x_WRITE_B_CB(WRITE8(galgames_cart_device, int_pic_data_w))
+
+ MCFG_EEPROM_SERIAL_93C76_8BIT_ADD("eeprom")
+MACHINE_CONFIG_END
+
+class galgames_starpak3_cart_device : public galgames_cart_device
+{
+public:
+ // construction/destruction
+ galgames_starpak3_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ galgames_cart_device(mconfig, tag, owner, clock)
+ { }
+protected:
+ // device-level overrides
+ virtual machine_config_constructor device_mconfig_additions() const override { return MACHINE_CONFIG_NAME(starpak3); }
+};
+
+const device_type GALGAMES_STARPAK3_CART = &device_creator<galgames_starpak3_cart_device>;
+
+#define MCFG_GALGAMES_STARPAK3_CART_ADD(_tag, _cart) \
+ MCFG_DEVICE_ADD(_tag, GALGAMES_STARPAK3_CART, 0) \
+ MCFG_GALGAMES_CART_INDEX(_cart) \
+ MCFG_GALGAMES_PIC_BITS(0, 2, 3, 4)
+
+
+
+/***************************************************************************
+
+ Galgames Slot Device
+
+***************************************************************************/
+
+// SLOT declaration
+
+class galgames_slot_device : public device_t,
+ public device_memory_interface
+{
+public:
+ // construction/destruction
+ galgames_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_ADDRESS_MAP(slot_map, 16);
+
+ DECLARE_READ16_MEMBER(read) { return m_space->read_word(offset * 2, mem_mask); }
+ DECLARE_WRITE16_MEMBER(write) { m_space->write_word(offset * 2, data, mem_mask); }
+
+ // SLOT
+ DECLARE_WRITE8_MEMBER(cart_sel_w);
+ DECLARE_WRITE8_MEMBER(ram_sel_w);
+
+ // ROM
+ DECLARE_READ16_MEMBER(rom0_r);
+ DECLARE_READ16_MEMBER(rom_r);
+ DECLARE_READ16_MEMBER(rom0_or_ram_r);
+ DECLARE_READ16_MEMBER(rom_or_ram_r);
+ DECLARE_WRITE16_MEMBER(ram_w);
+
+ // PIC
+ DECLARE_READ8_MEMBER(pic_status_r);
+ DECLARE_WRITE8_MEMBER(pic_data_w);
+ DECLARE_READ8_MEMBER(pic_data_r);
+ void set_pic_reset_line(int state);
+
+ // EEPROM
+ DECLARE_READ8_MEMBER(eeprom_r);
+ DECLARE_WRITE8_MEMBER(eeprom_w);
+ DECLARE_WRITE_LINE_MEMBER(eeprom_cs_write);
+
+ uint8_t get_cart() const { return m_cart; }
+
+protected:
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_PROGRAM) const override { return (spacenum == AS_PROGRAM) ? &m_space_config: nullptr; }
+
+ address_space_config m_space_config;
+ address_space *m_space;
+
+ required_shared_ptr<uint16_t> m_ram;
+
+ required_device<galgames_cart_device> m_cart0;
+
+ required_device<galgames_cart_device> m_cart1;
+ required_device<galgames_cart_device> m_cart2;
+ required_device<galgames_cart_device> m_cart3;
+ required_device<galgames_cart_device> m_cart4;
+
+ void set_cart(int cart);
+ void reset_eeproms_except(int cart);
+
+ galgames_cart_device *m_carts[1+4];
+
+ uint8_t m_cart;
+ bool m_is_ram_active;
+};
+
+// device type definition
+const device_type GALGAMES_SLOT = &device_creator<galgames_slot_device>;
+
+#define MCFG_GALGAMES_SLOT_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, GALGAMES_SLOT, 0)
+
+// CART implementation
+
+galgames_cart_device::galgames_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, GALGAMES_CART, "Galaxy Games StarPak Cartridge", tag, owner, clock, "starpak_cart", __FILE__),
+ device_rom_interface(mconfig, *this, 21, ENDIANNESS_BIG, 16),
+ m_mconfig_additions(nullptr),
+ m_cart(0),
+ m_slot(*this, "^slot"),
+ m_eeprom(*this, "eeprom"),
+ m_pic(*this, "pic")
+{
+}
+
+void galgames_cart_device::device_reset()
+{
+ pic_comm_reset();
+}
+
+bool galgames_cart_device::is_selected()
+{
+ return m_slot->get_cart() == m_cart;
+}
+
+void galgames_cart_device::set_pic_reset_line(int state)
+{
+ if (!m_pic)
+ return;
+
+// logerror("reset line = %x\n", state);
+
+ if (!m_pic->input_state(INPUT_LINE_RESET) && state)
+ pic_comm_reset();
+
+ m_pic->set_input_line(INPUT_LINE_RESET, state);
+}
+
+void galgames_cart_device::log_cart_comm(const char *text, uint8_t data)
+{
+// logerror("%s: comm %-10s %02x - data:%02x bit:%02x rdy:%x clk:%02x\n", machine().describe_context(),
+// text, data, m_pic_data, m_pic_data_bit, m_pic_data_rdy, m_pic_data_clk );
+
+// logerror("%s: comm %-10s %02x\n", machine().describe_context(), text, data );
+}
+
+void galgames_cart_device::pic_comm_reset()
+{
+ m_pic_iobits = m_pic_data = m_pic_data_rdy = m_pic_data_clk = 0;
+ m_pic_data_bit = 0xff;
+// logerror("%s: comm reset\n", machine().describe_context());
+}
+
+// External PIC status and data interface
+
+READ8_MEMBER(galgames_cart_device::pic_status_r)
+{
+ // bit 7 = data from the cart PIC can be read
+ return (is_selected() && (m_pic_data_rdy == 2)) ? 0x80 : 0;
+}
+
+READ8_MEMBER(galgames_cart_device::pic_data_r)
+{
+ if (is_selected())
+ {
+ m_pic_data_rdy = 0;
+ return m_pic_data;
+ }
+ return 0xff;
+}
+
+WRITE8_MEMBER(galgames_cart_device::pic_data_w)
+{
+ if (is_selected())
+ {
+ m_pic_data = data;
+ m_pic_data_rdy = 1;
+ m_pic_data_bit = 0xff;
+ m_pic_data_clk = 0;
+ log_cart_comm("EXT WRITE", data);
+ }
+}
+
+/*
+galgame2:
+ bit 0 = cleared at boot (never touched again)
+ bit 1 = PIC waits for it to become 0 before reading (or to become 1 when another byte is expected)
+ bit 2 = data out
+ bit 3 unused
+ bit 4 = data in
+ bit 5 = clock
+ bit 6 n.c.
+ bit 7 n.c.
+
+galgame3:
+ bit 0 = clock
+ bit 1 unused
+ bit 2 = data in
+ bit 3 = data out
+ bit 4 = PIC waits for it to become 0 before reading (or to become 1 when another byte is expected)
+ bit 5 = 0
+ bit 6 = 1
+ bit 7 unused
+*/
+void galgames_cart_device::set_pic_bits(int clk, int in, int out, int dis)
+{
+ m_pic_clk_mask = 1 << clk;
+ m_pic_in_mask = 1 << in;
+ m_pic_out_mask = 1 << out;
+ m_pic_dis_mask = 1 << dis;
+}
+
+READ8_MEMBER(galgames_cart_device::int_pic_data_r)
+{
+ // clock
+
+ uint8_t clk0 = m_pic_data_clk & 0x80;
+ m_pic_data_clk += 0x10;
+ uint8_t clk1 = m_pic_data_clk & 0x80;
+
+ m_pic_iobits = (m_pic_iobits & (~m_pic_clk_mask)) | (clk1 ? m_pic_clk_mask : 0);
+
+ // disabled
+
+ bool disabled = !is_selected();
+ m_pic_iobits = (m_pic_iobits & (~m_pic_dis_mask)) | (disabled ? m_pic_dis_mask : 0);
+
+ // The PIC waits for a falling edge before reading the new input bit.
+ // It waits for a rising edge before setting the new output bit.
+ // Hence we shift the data on the falling edge of the clock.
+
+ if (clk0 && !clk1)
+ {
+ uint8_t bit_in = 0;
+
+ if (m_pic_data_rdy == 1)
+ {
+ if (m_pic_data_bit == 0xff)
+ {
+ // first read bit must be 1 (sync)
+ bit_in = 1;
+ m_pic_data_bit = 7;
+ }
+ else
+ {
+ // read current bit and move to the next
+ bit_in = BIT(m_pic_data, m_pic_data_bit);
+ --m_pic_data_bit;
+
+ if (m_pic_data_bit == 0xff)
+ {
+ m_pic_data_rdy = 0;
+ log_cart_comm("PIC should have READ", m_pic_data);
+ }
+ }
+ }
+ else if (m_pic_data_rdy == 0)
+ {
+ uint8_t bit_out = m_pic_iobits & m_pic_out_mask;
+
+ if (m_pic_data_bit == 0xff)
+ {
+ // first written bit must be 1 (sync)
+ if (bit_out)
+ m_pic_data_bit = 7;
+ }
+ else
+ {
+ // write current bit and move to the next
+ uint8_t mask = 1 << m_pic_data_bit;
+ m_pic_data = (m_pic_data & (~mask)) | (bit_out ? mask : 0);
+ --m_pic_data_bit;
+
+ if (m_pic_data_bit == 0xff)
+ {
+ m_pic_data_rdy = 2;
+ log_cart_comm("PIC should have WRITTEN", m_pic_data);
+ }
+ }
+ }
+
+ m_pic_iobits = (m_pic_iobits & (~m_pic_in_mask)) | (bit_in ? m_pic_in_mask : 0);
+ }
+
+// log_cart_comm("PIC READ", m_pic_iobits);
+
+ return m_pic_iobits;
+}
+
+WRITE8_MEMBER(galgames_cart_device::int_pic_data_w)
+{
+ m_pic_iobits = (m_pic_iobits & (~m_pic_out_mask)) | (data & m_pic_out_mask);
+
+// log_cart_comm("PIC WRITE", data);
+}
+
+/*
+galgame3, port A:
+ bit 2 = bank lsb
+ bit 3 = bank msb
+*/
+WRITE8_MEMBER(galgames_cart_device::int_pic_bank_w)
+{
+ set_rom_bank((data >> 2) & 3);
+}
+
+
+
+// External EEPROM interface
+
+READ8_MEMBER(galgames_cart_device::eeprom_r)
+{
+ return (m_eeprom && m_eeprom->do_read()) ? 0x80 : 0x00;
+}
+
+WRITE8_MEMBER(galgames_cart_device::eeprom_w)
+{
+ if (!m_eeprom)
+ return;
+
+ if (data & ~0x03)
+ logerror("Unknown EEPROM bit written %04X\n", data);
+
+ // latch the bit
+ m_eeprom->di_write(data & 0x01);
+
+ // clock line asserted: write latch or select next bit to read
+ m_eeprom->clk_write((data & 0x02) ? ASSERT_LINE : CLEAR_LINE );
+}
+
+WRITE_LINE_MEMBER(galgames_cart_device::eeprom_cs_write)
+{
+ if (!m_eeprom)
+ return;
+
+ m_eeprom->cs_write(state);
+}
+
+
+
+
+// SLOT implementation
+
+DEVICE_ADDRESS_MAP_START( slot_map, 16, galgames_slot_device )
+ AM_RANGE( 0x000000, 0x03ffff ) AM_READWRITE(rom0_or_ram_r, ram_w) AM_SHARE("ram")
+ AM_RANGE( 0x000000, 0x1fffff ) AM_READ(rom0_r)
+ AM_RANGE( 0x200000, 0x23ffff ) AM_READWRITE(rom_or_ram_r, ram_w)
+ AM_RANGE( 0x200000, 0x3fffff ) AM_READ(rom_r)
+ADDRESS_MAP_END
+
+galgames_slot_device::galgames_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, GALGAMES_SLOT, "Galaxy Games Slot", tag, owner, clock, "galgames_slot", __FILE__),
+ device_memory_interface(mconfig, *this),
+ m_space_config("slot_space", ENDIANNESS_BIG, 16,22, 0, address_map_delegate(FUNC(slot_map), this)),
+ m_ram(*this, "ram"),
+ m_cart0(*this, "^cart0"),
+ m_cart1(*this, "^cart1"),
+ m_cart2(*this, "^cart2"),
+ m_cart3(*this, "^cart3"),
+ m_cart4(*this, "^cart4")
+{
+}
+
+void galgames_slot_device::device_start()
+{
+ m_space = &space(AS_PROGRAM);
+
+ m_carts[0] = m_cart0;
+ m_carts[1] = m_cart1;
+ m_carts[2] = m_cart2;
+ m_carts[3] = m_cart3;
+ m_carts[4] = m_cart4;
+}
+
+void galgames_slot_device::device_reset()
+{
+ m_is_ram_active = false;
+
+ set_cart(0);
+ reset_eeproms_except(-1);
+}
+
+void galgames_slot_device::set_cart(int cart)
+{
+// if (m_cart != cart)
+// logerror("%s: cart sel = %02x\n", machine().describe_context(), cart);
+
+ m_cart = cart;
+}
+
+void galgames_slot_device::reset_eeproms_except(int cart)
+{
+ // Reset all eeproms except the selected one
+ for (int i = 0; i < 5; i++)
+ m_carts[i]->eeprom_cs_write((cart == i) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+WRITE8_MEMBER(galgames_slot_device::cart_sel_w)
+{
+ // cart selection (0 1 2 3 4 7)
+
+ switch( data )
+ {
+ case 0x07: // 7 resets all
+ reset_eeproms_except(-1);
+ break;
+
+ case 0x00: // cart 0 (motherboard)
+ case 0x01: // cart 1
+ case 0x02: // cart 2
+ case 0x03: // cart 3
+ case 0x04: // cart 4
+ set_cart(data);
+ reset_eeproms_except(data);
+ break;
+
+ default:
+ set_cart(0);
+ reset_eeproms_except(0);
+ logerror("%s: unknown cart sel = %02x\n", machine().describe_context(), data);
+ break;
+ }
+}
+
+// Select RAM, reset PIC
+
+WRITE8_MEMBER(galgames_slot_device::ram_sel_w)
+{
+ // bit 3 = PIC reset (active low)
+ set_pic_reset_line(BIT(data, 3) ? CLEAR_LINE : ASSERT_LINE);
+
+ // ROM/RAM banking
+ if ((data & 0xf7) == 0x05)
+ {
+ m_is_ram_active = true;
+// logerror("%s: romram bank = %02x\n", machine().describe_context(), data);
+ }
+}
+
+// External ROM read
+
+READ16_MEMBER(galgames_slot_device::rom0_r)
+{
+ return m_carts[0]->rom_r(space, offset, mem_mask);
+}
+READ16_MEMBER(galgames_slot_device::rom_r)
+{
+ return m_carts[m_cart]->rom_r(space, offset, mem_mask);
+}
+
+READ16_MEMBER(galgames_slot_device::rom0_or_ram_r)
+{
+ return m_is_ram_active ? m_ram[offset] : m_carts[0]->rom_r(space, offset, mem_mask);
+}
+READ16_MEMBER(galgames_slot_device::rom_or_ram_r)
+{
+ return !m_is_ram_active ? m_ram[offset] : m_carts[m_cart]->rom_r(space, offset, mem_mask);
+}
+
+WRITE16_MEMBER(galgames_slot_device::ram_w)
+{
+ COMBINE_DATA(m_ram + offset);
+}
+
+// External PIC status and data interface
+
+READ8_MEMBER(galgames_slot_device::pic_status_r)
+{
+ return m_carts[m_cart]->pic_status_r(space, offset, mem_mask);
+}
+READ8_MEMBER(galgames_slot_device::pic_data_r)
+{
+ return m_carts[m_cart]->pic_data_r(space, offset, mem_mask);
+}
+WRITE8_MEMBER(galgames_slot_device::pic_data_w)
+{
+ m_carts[m_cart]->pic_data_w(space, offset, data, mem_mask);
+}
+
+void galgames_slot_device::set_pic_reset_line(int state)
+{
+ m_carts[m_cart]->set_pic_reset_line(state);
+}
+
+// External EEPROM interface
+
+READ8_MEMBER(galgames_slot_device::eeprom_r)
+{
+ return m_carts[m_cart]->eeprom_r(space, offset, mem_mask);
+}
+WRITE8_MEMBER(galgames_slot_device::eeprom_w)
+{
+ m_carts[m_cart]->eeprom_w(space, offset, data, mem_mask);
+}
+WRITE_LINE_MEMBER(galgames_slot_device::eeprom_cs_write)
+{
+ m_carts[m_cart]->eeprom_cs_write(state);
+}
+
+/***************************************************************************
+
+ General
+
+***************************************************************************/
+
+class galgames_state : public driver_device
+{
+public:
+ galgames_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_screen(*this, "screen"),
+ m_palette(*this, "palette"),
+ m_blitter(*this, "blitter"),
+ m_oki(*this, "oki"),
+ m_slot(*this, "slot")
+ { }
+
+ DECLARE_WRITE_LINE_MEMBER(blitter_irq_callback);
+
+ TIMER_DEVICE_CALLBACK_MEMBER(scanline_interrupt);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ DECLARE_WRITE16_MEMBER(galgames_palette_offset_w);
+ DECLARE_WRITE16_MEMBER(galgames_palette_data_w);
+
+ DECLARE_READ16_MEMBER(galgames_okiram_r);
+ DECLARE_WRITE16_MEMBER(galgames_okiram_w);
+
+ DECLARE_READ16_MEMBER(fpga_status_r);
+ DECLARE_WRITE16_MEMBER(outputs_w);
+
+protected:
+ required_device<cpu_device> m_maincpu;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+ required_device<cesblit_device> m_blitter;
+ required_device<okim6295_device> m_oki;
+ required_device<galgames_slot_device> m_slot;
+
+ uint32_t m_palette_offset;
+ uint8_t m_palette_index;
+ uint8_t m_palette_data[3];
+};
+
+WRITE_LINE_MEMBER(galgames_state::blitter_irq_callback)
+{
+// logerror("%s: Blitter IRQ callback state = %x\n", machine().describe_context(), state);
+ m_maincpu->set_input_line(2, state);
+}
+
+/***************************************************************************
+
+ Video
+
+***************************************************************************/
+
+uint32_t galgames_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(m_palette->black_pen(), cliprect);
+ return m_blitter->screen_update(screen, bitmap, cliprect);
+}
+
+// BT481A Palette RAMDAC
+
+WRITE16_MEMBER(galgames_state::galgames_palette_offset_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ m_palette_offset = data & 0xff;
+ m_palette_index = 0;
+ }
+}
+WRITE16_MEMBER(galgames_state::galgames_palette_data_w)
+{
+ if (ACCESSING_BITS_0_7)
+ {
+ m_palette_data[m_palette_index] = data & 0xff;
+ if (++m_palette_index == 3)
+ {
+ int palette_base;
+ for (palette_base = 0; palette_base < 0x1000; palette_base += 0x100)
+ m_palette->set_pen_color(m_palette_offset + palette_base, rgb_t(m_palette_data[0], m_palette_data[1], m_palette_data[2]));
+ m_palette_index = 0;
+ m_palette_offset++;
+ }
+ }
+}
+
+/***************************************************************************
+
+ Sound
+
+***************************************************************************/
+
+READ16_MEMBER(galgames_state::galgames_okiram_r)
+{
+ return memregion("oki")->base()[offset] | 0xff00;
+}
+
+WRITE16_MEMBER(galgames_state::galgames_okiram_w)
+{
+ if (ACCESSING_BITS_0_7)
+ memregion("oki")->base()[offset] = data & 0xff;
+}
+
+/***************************************************************************
+
+ Memory Maps
+
+***************************************************************************/
+
+// Outputs
+
+WRITE16_MEMBER(galgames_state::outputs_w)
+{
+ if (data & mem_mask & ~0x000f)
+ logerror("%s: Unknown output bit written %04X\n", machine().describe_context(), data);
+
+ if ( ACCESSING_BITS_0_7 )
+ {
+ // bit 0 & 1 : ? always on (may be trackball lights or coin lockouts)
+ // bit 2 : coin counter
+ // bit 3 : ? set after selecting a game (mostly off in-game)
+ machine().bookkeeping().coin_counter_w(0, data & 0x0004);
+ }
+
+// popmessage("OUT %02X", data & mem_mask);
+}
+
+// FPGA
+
+READ16_MEMBER(galgames_state::fpga_status_r)
+{
+ return 0x3; // Pass the check at PC = 0xfae & a later one
+}
+
+static ADDRESS_MAP_START( galgames_map, AS_PROGRAM, 16, galgames_state )
+ AM_RANGE( 0x000000, 0x3fffff ) AM_DEVREADWRITE("slot", galgames_slot_device, read, write )
+
+ AM_RANGE( 0x400000, 0x400011 ) AM_DEVWRITE("blitter", cesblit_device, regs_w )
+ AM_RANGE( 0x400012, 0x400013 ) AM_DEVWRITE("blitter", cesblit_device, addr_hi_w )
+ AM_RANGE( 0x400014, 0x400015 ) AM_DEVWRITE("blitter", cesblit_device, color_w )
+ AM_RANGE( 0x400020, 0x400021 ) AM_DEVREAD( "blitter", cesblit_device, status_r )
+
+ AM_RANGE( 0x600000, 0x600001 ) AM_READ(fpga_status_r )
+ AM_RANGE( 0x700000, 0x700001 ) AM_READ(fpga_status_r ) AM_WRITENOP
+ AM_RANGE( 0x800020, 0x80003f ) AM_NOP // ?
+ AM_RANGE( 0x900000, 0x900001 ) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w)
+
+ AM_RANGE( 0xa00000, 0xa00001 ) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff )
+ AM_RANGE( 0xb00000, 0xb7ffff ) AM_READWRITE(galgames_okiram_r, galgames_okiram_w ) // (only low bytes tested) 4x N341024SJ-15
+
+ AM_RANGE( 0xc00000, 0xc00001 ) AM_WRITE(galgames_palette_offset_w )
+ AM_RANGE( 0xc00002, 0xc00003 ) AM_WRITE(galgames_palette_data_w )
+
+ AM_RANGE( 0xd00000, 0xd00001 ) AM_READ_PORT("TRACKBALL_1_X")
+ AM_RANGE( 0xd00000, 0xd00001 ) AM_WRITENOP // bit 0: FPGA programming serial in (lsb first)
+ AM_RANGE( 0xd00002, 0xd00003 ) AM_READ_PORT("TRACKBALL_1_Y")
+ AM_RANGE( 0xd00004, 0xd00005 ) AM_READ_PORT("TRACKBALL_2_X")
+ AM_RANGE( 0xd00006, 0xd00007 ) AM_READ_PORT("TRACKBALL_2_Y")
+ AM_RANGE( 0xd00008, 0xd00009 ) AM_READ_PORT("P1")
+ AM_RANGE( 0xd0000a, 0xd0000b ) AM_READ_PORT("P2")
+ AM_RANGE( 0xd0000c, 0xd0000d ) AM_READ_PORT("SYSTEM") AM_WRITE(outputs_w )
+
+ AM_RANGE( 0xd0000e, 0xd0000f ) AM_READNOP AM_DEVWRITE8("slot", galgames_slot_device, cart_sel_w, 0x00ff )
+ AM_RANGE( 0xd00010, 0xd00011 ) AM_DEVREADWRITE8("slot", galgames_slot_device, eeprom_r, eeprom_w, 0x00ff )
+ AM_RANGE( 0xd00012, 0xd00013 ) AM_DEVREADWRITE8("slot", galgames_slot_device, pic_data_r, pic_data_w, 0x00ff )
+ AM_RANGE( 0xd00014, 0xd00015 ) AM_DEVREADWRITE8("slot", galgames_slot_device, pic_status_r, ram_sel_w, 0x00ff )
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( blitter_map, AS_PROGRAM, 16, galgames_state )
+ AM_RANGE( 0x000000, 0x1fffff ) AM_DEVREAD(":slot", galgames_slot_device, rom_r)
+ADDRESS_MAP_END
+
+/***************************************************************************
+
+ Input Ports
+
+***************************************************************************/
+
+static INPUT_PORTS_START( galgames )
+ PORT_START("P1")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) // Button A (right)
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) // Button B (left)
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("P2")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) // Button A (right)
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) // Button B (left)
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_SERVICE1) // DBA (coin)
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("SYSTEM")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) // CS 1 (coin)
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) // CS 2 (coin)
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH,IPT_OTHER ) PORT_CODE(KEYCODE_F2) PORT_NAME("Service Mode (Coin Door)") PORT_TOGGLE
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("TRACKBALL_1_X")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(25) PORT_KEYDELTA(5) PORT_PLAYER(1) PORT_RESET
+
+ PORT_START("TRACKBALL_1_Y")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(25) PORT_KEYDELTA(5) PORT_PLAYER(1) PORT_RESET
+
+ PORT_START("TRACKBALL_2_X")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(25) PORT_KEYDELTA(5) PORT_PLAYER(2) PORT_RESET
+
+ PORT_START("TRACKBALL_2_Y")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(25) PORT_KEYDELTA(5) PORT_PLAYER(2) PORT_RESET
+INPUT_PORTS_END
+
+/***************************************************************************
+
+ Machine Drivers
+
+***************************************************************************/
+
+TIMER_DEVICE_CALLBACK_MEMBER(galgames_state::scanline_interrupt)
+{
+ int scanline = param;
+
+ if (scanline == 0) // vblank, FIXME
+ m_maincpu->set_input_line(3, HOLD_LINE);
+ else if ((scanline % 16) == 0)
+ m_maincpu->set_input_line(1, HOLD_LINE);
+
+ // lev 2 triggered at the end of the blit
+}
+
+int galgames_compute_addr(uint16_t reg_low, uint16_t reg_mid, uint16_t reg_high)
+{
+ return reg_low | (reg_mid << 16);
+}
+
+static MACHINE_CONFIG_START( galgames_base, galgames_state )
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_24MHz / 2)
+ MCFG_CPU_PROGRAM_MAP(galgames_map)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", galgames_state, scanline_interrupt, "screen", 0, 1)
+ MCFG_WATCHDOG_ADD("watchdog")
+
+ MCFG_GALGAMES_SLOT_ADD("slot")
+ MCFG_GALGAMES_BIOS_CART_ADD( "cart0", 0)
+
+ // video hardware
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
+ MCFG_SCREEN_SIZE(400, 256)
+ MCFG_SCREEN_VISIBLE_AREA(0, 400-1, 0, 256-1)
+ MCFG_SCREEN_UPDATE_DRIVER(galgames_state, screen_update)
+ MCFG_SCREEN_PALETTE("palette")
+
+ MCFG_CESBLIT_ADD("blitter", "screen", XTAL_24MHz)
+ MCFG_CESBLIT_MAP(blitter_map)
+ MCFG_CESBLIT_COMPUTE_ADDR(galgames_compute_addr)
+ MCFG_CESBLIT_IRQ_CB(WRITELINE(galgames_state, blitter_irq_callback))
+
+ MCFG_PALETTE_ADD("palette", 0x1000) // only 0x100 used
+ MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
+
+ // sound hardware
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+
+ MCFG_OKIM6295_ADD("oki", XTAL_24MHz / 8, OKIM6295_PIN7_LOW) // clock frequency & pin 7 not verified
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( galgbios, galgames_base )
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart1", 1)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart2", 2)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart3", 3)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart4", 4)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( galgame2, galgames_base )
+ MCFG_GALGAMES_STARPAK2_CART_ADD("cart1", 1)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart2", 2)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart3", 3)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart4", 4)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( galgame3, galgames_base )
+ MCFG_GALGAMES_STARPAK3_CART_ADD("cart1", 1)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart2", 2)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart3", 3)
+ MCFG_GALGAMES_EMPTY_CART_ADD("cart4", 4)
+MACHINE_CONFIG_END
+
+/***************************************************************************
+
+ ROMs Loading
+
+***************************************************************************/
+
+
+/***************************************************************************
+
+Galaxy Games BIOS
+
+This is a multi-game cocktail cabinet released in 1998. Namco and Atari
+licensed their IP for some cartridges for it.
+
+Trackball-based. 'BIOS' has 7 built-in games. There are two LEDs on the PCB.
+
+More information here : http://www.cesgames.com/museum/galaxy/index.html
+
+----
+
+Board silkscreened 237-0211-00
+ REV.-D
+
+Cartridge based mother board
+Holds up to 4 cartridges
+Chips labeled
+ GALAXY U1 V1.90 12/1/98
+ GALAXY U2 V1.90 12/1/98
+
+Motorola MC68HC000FN12
+24 MHz oscillator
+Xilinx XC5206
+Xilinx XC5202
+BT481AKPJ110 (Palette RAMDAC)
+NKK N341024SJ-15 x8 (128kB RAM)
+OKI M6295 8092352-2
+
+PAL16V8H-15 @ U24 Blue dot on it
+PAL16V8H-15 @ U25 Yellow dot on it
+PAL16V8H-15 @ U26 Red dot on it
+PAL16V8H-15 @ U27 Green dot on it
+PAL16V8H-15 @ U45 Magenta dot on it
+
+Copyright notice in rom states: Creative Electronics & Software Written by Keith M. Kolmos May 29,1998
+
+***************************************************************************/
+
+#define ROM_LOAD16_BYTE_BIOS(bios,name,offset,length,hash) \
+ ROMX_LOAD(name, offset, length, hash, ROM_SKIP(1) | ROM_BIOS(bios+1)) /* Note '+1' */
+
+#define GALGAMES_BIOS_ROMS \
+ ROM_SYSTEM_BIOS( 0, "1.90", "v1.90 12/01/98" ) \
+ ROM_LOAD16_BYTE_BIOS( 0, "galaxy_u2__v1.90_12-01-98.u2", 0x000000, 0x100000, CRC(e51ff184) SHA1(aaa795f2c15ec29b3ceeb5c917b643db0dbb7083) ) \
+ ROM_LOAD16_BYTE_BIOS( 0, "galaxy_u1__v1.90_12-01-98.u1", 0x000001, 0x100000, CRC(c6d7bc6d) SHA1(93c032f9aa38cbbdda59a8a25ff9f38f7ad9c760) ) \
+ \
+ ROM_SYSTEM_BIOS( 1, "1.80", "v1.80 10/05/98" ) \
+ ROM_LOAD16_BYTE_BIOS( 1, "galaxy_u2__v1.80_10-15-98.u2", 0x000000, 0x100000, CRC(73cff284) SHA1(e6f7d92999cdb478c21c3b65a04eade84299ac12) ) \
+ ROM_LOAD16_BYTE_BIOS( 1, "galaxy_u1__v1.80_10-15-98.u1", 0x000001, 0x100000, CRC(e3ae423c) SHA1(66d1964845a99a5ed4b19b4135b55cde6b5fe295) )
+
+#define GALGAMES_MB_PALS \
+ ROM_REGION( 0xa00, "pals", 0) \
+ ROM_LOAD( "16v8h-blue.u24", 0x000, 0x117, NO_DUMP ) \
+ ROM_LOAD( "16v8h-yellow.u25", 0x200, 0x117, NO_DUMP ) \
+ ROM_LOAD( "16v8h-magenta.u26", 0x400, 0x117, NO_DUMP ) \
+ ROM_LOAD( "16v8h-green.u27", 0x600, 0x117, NO_DUMP ) \
+ ROM_LOAD( "16v8h-red.u45", 0x800, 0x117, NO_DUMP )
+
+ROM_START( galgbios )
+ ROM_REGION16_BE( 0x200000, "cart0", 0 )
+ GALGAMES_BIOS_ROMS
+
+ ROM_REGION( 0x200000, "cart1", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart2", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart3", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart4", ROMREGION_ERASEFF )
+
+ ROM_REGION( 0x40000, "oki", ROMREGION_ERASE )
+ // RAM, filled by the 68000 and fed to the OKI
+
+ GALGAMES_MB_PALS
+ROM_END
+
+/***************************************************************************
+
+Galaxy Games StarPak 2
+
+NAMCO 307 Cartridge, has surface mount Flash chips in it:
+
+.U1 AM29F800BB
+.U2 AM29F800BB
+.U3 93AA76/SN
+.U4 PIC 12C508
+.L1 Led
+
+Board silkscreened 237-0209-00
+ REV.-C
+
+***************************************************************************/
+
+ROM_START( galgame2 )
+ ROM_REGION16_BE( 0x200000, "cart0", 0 )
+ GALGAMES_BIOS_ROMS
+
+ ROM_REGION( 0x200000, "cart1", 0 )
+ ROM_LOAD16_BYTE( "am29f800bb.u2", 0x000000, 0x100000, CRC(f43c0c54) SHA1(4a13946c3d173b0e4ab25b01849574fa3302b417) )
+ ROM_LOAD16_BYTE( "am29f800bb.u1", 0x000001, 0x100000, CRC(b8c34a8b) SHA1(40d3b35f573d2bd2ae1c7d876c55fc436864fa3f) )
+
+ ROM_REGION( 0x2000, "cart1:pic", 0 )
+ ROM_LOAD( "pic12c508.u4", 0x0000, 0x2000, CRC(bb253913) SHA1(eace069344da6dda7c05673e422876d130ed5d48) ) // includes config word at fff, hence size is 2*1000
+
+ ROM_REGION( 0x200000, "cart2", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart3", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart4", ROMREGION_ERASEFF )
+
+ ROM_REGION( 0x40000, "oki", ROMREGION_ERASE )
+ // RAM, filled by the 68000 and fed to the OKI
+
+ GALGAMES_MB_PALS
+ROM_END
+
+/***************************************************************************
+
+Galaxy Games StarPak 3
+
+Cartridge with 8 games, including Atari licensed Centipede.
+
+.U1 AM29F032B
+.U2 AM29F032B
+.U5 93AA76/SN
+.U6 PIC 16C56-XT/P
+.L1 Led
+
+Board silkscreened 237-0228-00
+ REV.-B
+
+***************************************************************************/
+
+ROM_START( galgame3 )
+ ROM_REGION16_BE( 0x200000, "cart0", 0 )
+ GALGAMES_BIOS_ROMS
+
+ ROM_REGION( 0x800000, "cart1", 0 )
+ ROM_LOAD16_BYTE( "am29f032b.u2", 0x000000, 0x400000, CRC(a4ffc70a) SHA1(328c6ceef025af7ff5b7998df59a10d90c654d53) )
+ ROM_LOAD16_BYTE( "am29f032b.u1", 0x000001, 0x400000, CRC(b0876751) SHA1(487f052989e4b2df2df2293b283e8e03ffc3ddf4) )
+
+ ROM_REGION( 0x800, "cart1:pic", 0 )
+ ROM_LOAD( "pic16c56.u6", 0x000, 0x800, CRC(cf901ed8) SHA1(ebb2da0f50ba82a038f315aab7e6b20b9a1af3a1) )
+
+ ROM_REGION( 0x200000, "cart2", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart3", ROMREGION_ERASEFF )
+ ROM_REGION( 0x200000, "cart4", ROMREGION_ERASEFF )
+
+ ROM_REGION( 0x40000, "oki", ROMREGION_ERASE )
+ // RAM, filled by the 68000 and fed to the OKI
+
+ GALGAMES_MB_PALS
+ROM_END
+
+
+GAME( 1998, galgbios, 0, galgbios, galgames, driver_device, 0, ROT0, "Creative Electronics & Software", "Galaxy Games BIOS", MACHINE_IS_BIOS_ROOT )
+GAME( 1998, galgame2, galgbios, galgame2, galgames, driver_device, 0, ROT0, "Creative Electronics & Software / Namco", "Galaxy Games StarPak 2", 0 )
+GAME( 1998, galgame3, galgbios, galgame3, galgames, driver_device, 0, ROT0, "Creative Electronics & Software / Atari", "Galaxy Games StarPak 3", 0 )
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 94b5c550055..d2aaebee48b 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -12975,10 +12975,10 @@ galeb //
@source:galgame.cpp
galgame // (c) 1971 Computer Recreations, Inc
-//@source:galgames.cpp
-//galgame2 // (c) 1998 Creative Electronics & Software (CES) / Namco
-//galgame3 // (c) 1998 Creative Electronics & Software (CES) / Atari
-//galgbios // (c) 1998 Creative Electronics & Software (CES)
+@source:galgames.cpp
+galgame2 // (c) 1998 Creative Electronics & Software (CES) / Namco
+galgame3 // (c) 1998 Creative Electronics & Software (CES) / Atari
+galgbios // (c) 1998 Creative Electronics & Software (CES)
@source:galivan.cpp
dangar // (c) 1986