summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Fabio Priuli <etabeta78@users.noreply.github.com>2014-10-07 09:27:32 +0000
committer Fabio Priuli <etabeta78@users.noreply.github.com>2014-10-07 09:27:32 +0000
commit238c2e9e1d71b23ded5f6db98ef27c5b7ca8efcd (patch)
tree0b514f3d30b201e8be4a7709dcd092c2deedaa5f /src
parentb83b6a0f33727dc26c129d0e43ebb6d95f39ba5b (diff)
(MESS) odyssey2: converted the driver to use slot devices for
cartridges, removed The Voice add-on from the main system and emulated it as a passthru cart instead. Now, if you want to enjoy speech in odyssey/videopac games, you must launch emulation with mess.exe odyssey2 -cart voice -cart2 gamename (the -cart2 switch becomes available when "voice" is mounted in the first cartslot) [Fabio Priuli]
Diffstat (limited to 'src')
-rw-r--r--src/emu/bus/bus.mak14
-rw-r--r--src/emu/bus/odyssey2/chess.c58
-rw-r--r--src/emu/bus/odyssey2/chess.h31
-rw-r--r--src/emu/bus/odyssey2/rom.c95
-rw-r--r--src/emu/bus/odyssey2/rom.h65
-rw-r--r--src/emu/bus/odyssey2/slot.c279
-rw-r--r--src/emu/bus/odyssey2/slot.h120
-rw-r--r--src/emu/bus/odyssey2/voice.c101
-rw-r--r--src/emu/bus/odyssey2/voice.h48
-rw-r--r--src/mess/drivers/odyssey2.c179
-rw-r--r--src/mess/mess.mak1
11 files changed, 837 insertions, 154 deletions
diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak
index d3f7c3b7cab..a6cd026c0a8 100644
--- a/src/emu/bus/bus.mak
+++ b/src/emu/bus/bus.mak
@@ -545,6 +545,20 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/odyssey2/slot.h,BUSES += O2
+#-------------------------------------------------
+
+ifneq ($(filter O2,$(BUSES)),)
+OBJDIRS += $(BUSOBJ)/odyssey2
+BUSOBJS += $(BUSOBJ)/odyssey2/slot.o
+BUSOBJS += $(BUSOBJ)/odyssey2/rom.o
+BUSOBJS += $(BUSOBJ)/odyssey2/chess.o
+BUSOBJS += $(BUSOBJ)/odyssey2/voice.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/pc_joy/pc_joy.h,BUSES += PC_JOY
#-------------------------------------------------
diff --git a/src/emu/bus/odyssey2/chess.c b/src/emu/bus/odyssey2/chess.c
new file mode 100644
index 00000000000..6150e5f5a59
--- /dev/null
+++ b/src/emu/bus/odyssey2/chess.c
@@ -0,0 +1,58 @@
+/***********************************************************************************************************
+
+
+ Videopac Chess Module emulation
+
+ TODO:
+ - this code is just a stub... hence, almost everything is still to do!
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "chess.h"
+
+
+//-------------------------------------------------
+// o2_chess_device - constructor
+//-------------------------------------------------
+
+const device_type O2_ROM_CHESS = &device_creator<o2_chess_device>;
+
+
+o2_chess_device::o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : o2_rom_device(mconfig, O2_ROM_CHESS, "Odyssey 2 BASIC Carts", tag, owner, clock, "o2_chess", __FILE__),
+ m_cpu(*this, "subcpu")
+{
+}
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( o2chess )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START(chess_mem, AS_PROGRAM, 8, o2_chess_device)
+ AM_RANGE(0x0000, 0x07ff) AM_READ(read_rom04)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(chess_io, AS_IO, 8, o2_chess_device)
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ADDRESS_MAP_END
+
+static MACHINE_CONFIG_FRAGMENT( o2chess )
+ MCFG_CPU_ADD("subcpu", NSC800, XTAL_4MHz)
+ MCFG_CPU_PROGRAM_MAP(chess_mem)
+ MCFG_CPU_IO_MAP(chess_io)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor o2_chess_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( o2chess );
+}
diff --git a/src/emu/bus/odyssey2/chess.h b/src/emu/bus/odyssey2/chess.h
new file mode 100644
index 00000000000..622392d13a4
--- /dev/null
+++ b/src/emu/bus/odyssey2/chess.h
@@ -0,0 +1,31 @@
+#ifndef __O2_CHESS_H
+#define __O2_CHESS_H
+
+#include "slot.h"
+#include "rom.h"
+#include "cpu/z80/z80.h"
+
+
+// ======================> o2_chess_device
+
+class o2_chess_device : public o2_rom_device
+{
+
+ virtual machine_config_constructor device_mconfig_additions() const;
+// virtual const rom_entry *device_rom_region() const;
+
+public:
+ // construction/destruction
+ o2_chess_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+private:
+ required_device<nsc800_device> m_cpu;
+};
+
+
+
+// device type definition
+extern const device_type O2_ROM_CHESS;
+
+
+#endif
diff --git a/src/emu/bus/odyssey2/rom.c b/src/emu/bus/odyssey2/rom.c
new file mode 100644
index 00000000000..1406129eabc
--- /dev/null
+++ b/src/emu/bus/odyssey2/rom.c
@@ -0,0 +1,95 @@
+/***********************************************************************************************************
+
+
+ Magnavox Odyssey cart emulation
+
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "rom.h"
+
+
+//-------------------------------------------------
+// o2_rom_device - constructor
+//-------------------------------------------------
+
+const device_type O2_ROM_STD = &device_creator<o2_rom_device>;
+const device_type O2_ROM_12K = &device_creator<o2_rom12_device>;
+const device_type O2_ROM_16K = &device_creator<o2_rom16_device>;
+
+
+o2_rom_device::o2_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ device_o2_cart_interface( mconfig, *this )
+{
+}
+
+o2_rom_device::o2_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, O2_ROM_STD, "Odyssey 2 Standard Carts", tag, owner, clock, "o2_rom", __FILE__),
+ device_o2_cart_interface( mconfig, *this )
+{
+}
+
+o2_rom12_device::o2_rom12_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : o2_rom_device(mconfig, O2_ROM_12K, "Odyssey 2 12K Carts", tag, owner, clock, "o2_rom12", __FILE__)
+{
+}
+
+o2_rom16_device::o2_rom16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : o2_rom_device(mconfig, O2_ROM_16K, "Odyssey 2 16K Carts", tag, owner, clock, "o2_rom16", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_start/device_reset - device-specific startup
+//-------------------------------------------------
+
+void o2_rom_device::device_start()
+{
+ save_item(NAME(m_bank_base));
+}
+
+void o2_rom_device::device_reset()
+{
+ m_bank_base = 0;
+}
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+void o2_rom_device::write_bank(int bank)
+{
+ m_bank_base = bank;
+}
+
+READ8_MEMBER(o2_rom_device::read_rom04)
+{
+ return m_rom[(offset + (m_bank_base & 0x03) * 0x800) & (m_rom_size - 1)];
+}
+READ8_MEMBER(o2_rom_device::read_rom0c)
+{
+ return m_rom[(offset + (m_bank_base & 0x03) * 0x800) & (m_rom_size - 1)];
+}
+
+READ8_MEMBER(o2_rom12_device::read_rom04)
+{
+ return m_rom[offset + (m_bank_base & 0x03) * 0xc00];
+}
+READ8_MEMBER(o2_rom12_device::read_rom0c)
+{
+ return m_rom[offset + 0x800 + (m_bank_base & 0x03) * 0xc00];
+}
+
+READ8_MEMBER(o2_rom16_device::read_rom04)
+{
+ return m_rom[offset + 0x400 + (m_bank_base & 0x03) * 0x1000];
+}
+READ8_MEMBER(o2_rom16_device::read_rom0c)
+{
+ return m_rom[offset + 0xc00 + (m_bank_base & 0x03) * 0x1000];
+}
+
diff --git a/src/emu/bus/odyssey2/rom.h b/src/emu/bus/odyssey2/rom.h
new file mode 100644
index 00000000000..174e6dece30
--- /dev/null
+++ b/src/emu/bus/odyssey2/rom.h
@@ -0,0 +1,65 @@
+#ifndef __O2_ROM_H
+#define __O2_ROM_H
+
+#include "slot.h"
+
+
+// ======================> o2_rom_device
+
+class o2_rom_device : public device_t,
+ public device_o2_cart_interface
+{
+public:
+ // construction/destruction
+ o2_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+ o2_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom04);
+ virtual DECLARE_READ8_MEMBER(read_rom0c);
+
+ virtual void write_bank(int bank);
+
+protected:
+ int m_bank_base;
+};
+
+// ======================> o2_rom12_device
+
+class o2_rom12_device : public o2_rom_device
+{
+public:
+ // construction/destruction
+ o2_rom12_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom04);
+ virtual DECLARE_READ8_MEMBER(read_rom0c);
+};
+
+// ======================> o2_rom16_device
+
+class o2_rom16_device : public o2_rom_device
+{
+public:
+ // construction/destruction
+ o2_rom16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom04);
+ virtual DECLARE_READ8_MEMBER(read_rom0c);
+};
+
+
+
+// device type definition
+extern const device_type O2_ROM_STD;
+extern const device_type O2_ROM_12K;
+extern const device_type O2_ROM_16K;
+
+
+#endif
diff --git a/src/emu/bus/odyssey2/slot.c b/src/emu/bus/odyssey2/slot.c
new file mode 100644
index 00000000000..a434b32c2f5
--- /dev/null
+++ b/src/emu/bus/odyssey2/slot.c
@@ -0,0 +1,279 @@
+/***********************************************************************************************************
+
+ Magnavox Odyssey 2 cart emulation
+ (through slot devices)
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "slot.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type O2_CART_SLOT = &device_creator<o2_cart_slot_device>;
+
+//**************************************************************************
+// Odyssey 2 Cartridges Interface
+//**************************************************************************
+
+//-------------------------------------------------
+// device_o2_cart_interface - constructor
+//-------------------------------------------------
+
+device_o2_cart_interface::device_o2_cart_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_rom(NULL),
+ m_rom_size(0)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_o2_cart_interface - destructor
+//-------------------------------------------------
+
+device_o2_cart_interface::~device_o2_cart_interface()
+{
+}
+
+//-------------------------------------------------
+// rom_alloc - alloc the space for the cart
+//-------------------------------------------------
+
+void device_o2_cart_interface::rom_alloc(UINT32 size, const char *tag)
+{
+ if (m_rom == NULL)
+ {
+ astring tempstring(tag);
+ tempstring.cat(O2SLOT_ROM_REGION_TAG);
+ m_rom = device().machine().memory().region_alloc(tempstring, size, 1, ENDIANNESS_LITTLE)->base();
+ m_rom_size = size;
+ }
+}
+
+
+//-------------------------------------------------
+// ram_alloc - alloc the space for the ram
+//-------------------------------------------------
+
+void device_o2_cart_interface::ram_alloc(UINT32 size)
+{
+ m_ram.resize(size);
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// o2_cart_slot_device - constructor
+//-------------------------------------------------
+o2_cart_slot_device::o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, O2_CART_SLOT, "Odyssey 2 Cartridge Slot", tag, owner, clock, "o2_cart_slot", __FILE__),
+ device_image_interface(mconfig, *this),
+ device_slot_interface(mconfig, *this),
+ m_type(O2_STD)
+{
+}
+
+
+//-------------------------------------------------
+// o2_cart_slot_device - destructor
+//-------------------------------------------------
+
+o2_cart_slot_device::~o2_cart_slot_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void o2_cart_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_o2_cart_interface *>(get_card_device());
+}
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void o2_cart_slot_device::device_config_complete()
+{
+ // set brief and instance name
+ update_names();
+}
+
+
+//-------------------------------------------------
+// O2 PCB
+//-------------------------------------------------
+
+struct o2_slot
+{
+ int pcb_id;
+ const char *slot_option;
+};
+
+// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
+static const o2_slot slot_list[] =
+{
+ { O2_STD, "o2_rom" },
+ { O2_ROM12, "o2_rom12" },
+ { O2_ROM16, "o2_rom16" },
+ { O2_CHESS, "o2_chess" },
+ { O2_VOICE, "o2_voice" }
+};
+
+static int o2_get_pcb_id(const char *slot)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (!core_stricmp(slot_list[i].slot_option, slot))
+ return slot_list[i].pcb_id;
+ }
+
+ return 0;
+}
+
+static const char *o2_get_slot(int type)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (slot_list[i].pcb_id == type)
+ return slot_list[i].slot_option;
+ }
+
+ return "o2_rom";
+}
+
+
+/*-------------------------------------------------
+ call load
+ -------------------------------------------------*/
+
+bool o2_cart_slot_device::call_load()
+{
+ if (m_cart)
+ {
+ UINT32 size = (software_entry() == NULL) ? length() : get_software_region_length("rom");
+ m_cart->rom_alloc(size, tag());
+
+ if (software_entry() == NULL)
+ fread(m_cart->get_rom_base(), size);
+ else
+ memcpy(m_cart->get_rom_base(), get_software_region("rom"), size);
+
+ if (software_entry() == NULL)
+ {
+ m_type = O2_STD;
+ if (size == 12288)
+ m_type = O2_ROM12;
+ if (size == 16384)
+ m_type = O2_ROM16;
+ }
+ else
+ {
+ const char *pcb_name = get_feature("slot");
+ if (pcb_name)
+ m_type = o2_get_pcb_id(pcb_name);
+ }
+
+ //printf("Type: %s\n", o2_get_slot(m_type));
+
+ return IMAGE_INIT_PASS;
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+/*-------------------------------------------------
+ call softlist load
+ -------------------------------------------------*/
+
+bool o2_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
+{
+ load_software_part_region(*this, swlist, swname, start_entry);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------
+ get default card software
+ -------------------------------------------------*/
+
+void o2_cart_slot_device::get_default_card_software(astring &result)
+{
+ if (open_image_file(mconfig().options()))
+ {
+ const char *slot_string = "o2_rom";
+ UINT32 size = core_fsize(m_file);
+ int type = O2_STD;
+
+ if (size == 12288)
+ type = O2_ROM12;
+ if (size == 16384)
+ type = O2_ROM16;
+
+ slot_string = o2_get_slot(type);
+
+ //printf("type: %s\n", slot_string);
+ clear();
+
+ result.cpy(slot_string);
+ return;
+ }
+
+ software_get_default_slot(result, "o2_rom");
+}
+
+/*-------------------------------------------------
+ read_rom**
+ -------------------------------------------------*/
+
+READ8_MEMBER(o2_cart_slot_device::read_rom04)
+{
+ if (m_cart)
+ return m_cart->read_rom04(space, offset);
+ else
+ return 0xff;
+}
+
+READ8_MEMBER(o2_cart_slot_device::read_rom0c)
+{
+ if (m_cart)
+ return m_cart->read_rom0c(space, offset);
+ else
+ return 0xff;
+}
+
+/*-------------------------------------------------
+ io_write
+ -------------------------------------------------*/
+
+WRITE8_MEMBER(o2_cart_slot_device::io_write)
+{
+ if (m_cart)
+ m_cart->io_write(space, offset, data);
+}
+
+
+#include "bus/odyssey2/rom.h"
+#include "bus/odyssey2/chess.h"
+#include "bus/odyssey2/voice.h"
+
+SLOT_INTERFACE_START(o2_cart)
+ SLOT_INTERFACE_INTERNAL("o2_rom", O2_ROM_STD)
+ SLOT_INTERFACE_INTERNAL("o2_rom12", O2_ROM_12K)
+ SLOT_INTERFACE_INTERNAL("o2_rom16", O2_ROM_16K)
+ SLOT_INTERFACE_INTERNAL("o2_chess", O2_ROM_CHESS)
+ SLOT_INTERFACE_INTERNAL("o2_voice", O2_ROM_VOICE)
+SLOT_INTERFACE_END
+
diff --git a/src/emu/bus/odyssey2/slot.h b/src/emu/bus/odyssey2/slot.h
new file mode 100644
index 00000000000..f1f30c58587
--- /dev/null
+++ b/src/emu/bus/odyssey2/slot.h
@@ -0,0 +1,120 @@
+#ifndef __O2_SLOT_H
+#define __O2_SLOT_H
+
+/***************************************************************************
+ TYPE DEFINITIONS
+ ***************************************************************************/
+
+
+/* PCB */
+enum
+{
+ O2_STD = 0,
+ O2_ROM12,
+ O2_ROM16,
+ O2_CHESS,
+ O2_VOICE
+};
+
+
+// ======================> device_o2_cart_interface
+
+class device_o2_cart_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_o2_cart_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_o2_cart_interface();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom04) { return 0xff; }
+ virtual DECLARE_READ8_MEMBER(read_rom0c) { return 0xff; }
+ virtual void write_bank(int bank) {}
+
+ virtual DECLARE_WRITE8_MEMBER(io_write) {}
+ virtual DECLARE_READ8_MEMBER(t0_read) { return 0; }
+
+ void rom_alloc(UINT32 size, const char *tag);
+ void ram_alloc(UINT32 size);
+ UINT8* get_rom_base() { return m_rom; }
+ UINT8* get_ram_base() { return m_ram; }
+ UINT32 get_rom_size() { return m_rom_size; }
+ UINT32 get_ram_size() { return m_ram.count(); }
+
+protected:
+ // internal state
+ UINT8 *m_rom;
+ UINT32 m_rom_size;
+ dynamic_buffer m_ram;
+};
+
+
+// ======================> o2_cart_slot_device
+
+class o2_cart_slot_device : public device_t,
+ public device_image_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~o2_cart_slot_device();
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_config_complete();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual void call_unload() {}
+ virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
+
+ int get_type() { return m_type; }
+
+ virtual iodevice_t image_type() const { return IO_CARTSLOT; }
+ virtual bool is_readable() const { return 1; }
+ virtual bool is_writeable() const { return 0; }
+ virtual bool is_creatable() const { return 0; }
+ virtual bool must_be_loaded() const { return 0; }
+ virtual bool is_reset_on_load() const { return 1; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+ virtual const char *image_interface() const { return "odyssey_cart"; }
+ virtual const char *file_extensions() const { return "bin,rom"; }
+
+ // slot interface overrides
+ virtual void get_default_card_software(astring &result);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom04);
+ virtual DECLARE_READ8_MEMBER(read_rom0c);
+ virtual DECLARE_WRITE8_MEMBER(io_write);
+ virtual DECLARE_READ8_MEMBER(t0_read) { if (m_cart) return m_cart->t0_read(space, offset); else return 0; }
+
+ virtual void write_bank(int bank) { if (m_cart) m_cart->write_bank(bank); }
+
+protected:
+
+ int m_type;
+ device_o2_cart_interface* m_cart;
+};
+
+
+
+// device type definition
+extern const device_type O2_CART_SLOT;
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+ ***************************************************************************/
+
+#define O2SLOT_ROM_REGION_TAG ":cart:rom"
+
+#define MCFG_O2_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
+ MCFG_DEVICE_ADD(_tag, O2_CART_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+
+
+SLOT_INTERFACE_EXTERN(o2_cart);
+
+#endif
diff --git a/src/emu/bus/odyssey2/voice.c b/src/emu/bus/odyssey2/voice.c
new file mode 100644
index 00000000000..7da5d308695
--- /dev/null
+++ b/src/emu/bus/odyssey2/voice.c
@@ -0,0 +1,101 @@
+/***********************************************************************************************************
+
+
+ Magnavox The Voice emulation
+
+ TODO:
+ - load speech ROM from softlist
+ - move external speech rom for S.I.D. the Spellbinder into the softlist entry
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "voice.h"
+
+
+//-------------------------------------------------
+// o2_voice_device - constructor
+//-------------------------------------------------
+
+const device_type O2_ROM_VOICE = &device_creator<o2_voice_device>;
+
+
+o2_voice_device::o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : o2_rom_device(mconfig, O2_ROM_VOICE, "Odyssey 2 The Voice Passthrough Cart", tag, owner, clock, "o2_voice", __FILE__),
+ m_speech(*this, "sp0256_speech"),
+ m_subslot(*this, "subslot"),
+ m_lrq_state(0)
+{
+}
+
+
+void o2_voice_device::device_start()
+{
+ save_item(NAME(m_lrq_state));
+}
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( sub_slot )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( o2voice )
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+
+ MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
+ MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(o2_voice_device, lrq_callback))
+ // The Voice uses a speaker with its own volume control so the relative volumes to use are subjective, these sound good
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+
+ MCFG_O2_CARTRIDGE_ADD("subslot", o2_cart, NULL)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor o2_voice_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( o2voice );
+}
+
+
+ROM_START( o2voice )
+ ROM_REGION( 0x10000, "sp0256_speech", 0 )
+ // SP0256B-019 Speech chip w/2KiB mask rom
+ ROM_LOAD( "sp0256b-019.bin", 0x1000, 0x0800, CRC(4bb43724) SHA1(49f5326ad45392dc96c89d1d4e089a20bd21e609) )
+
+ /* A note about "The Voice": Two versions of "The Voice" exist:
+ * An earlier version with eight 2KiB speech roms, spr016-??? through spr016-??? on a small daughterboard
+ <note to self: fill in numbers later>
+ * A later version with one 16KiB speech rom, spr128-003, mounted directly on the mainboard
+ The rom contents of these two versions are EXACTLY the same.
+ Both versions have an sp0256b-019 speech chip, which has 2KiB of its own internal speech data
+ Thanks to kevtris for this info. - LN
+ */
+
+ // External 16KiB speech ROM (spr128-003) from "The Voice"
+ ROM_LOAD( "spr128-003.bin", 0x4000, 0x4000, CRC(509367b5) SHA1(0f31f46bc02e9272885779a6dd7102c78b18895b) )
+ // Additional External 16KiB speech ROM (spr128-004) from S.I.D. the Spellbinder
+ ROM_LOAD( "spr128-004.bin", 0x8000, 0x4000, CRC(e79dfb75) SHA1(37f33d79ffd1739d7c2f226b010a1eac28d74ca0) )
+ROM_END
+
+const rom_entry *o2_voice_device::device_rom_region() const
+{
+ return ROM_NAME( o2voice );
+}
+
+WRITE_LINE_MEMBER(o2_voice_device::lrq_callback)
+{
+ m_lrq_state = state;
+}
+
+WRITE8_MEMBER(o2_voice_device::io_write)
+{
+ if (data & 0x20)
+ m_speech->ald_w(space, 0, offset & 0x7f);
+ else
+ m_speech->reset();
+}
diff --git a/src/emu/bus/odyssey2/voice.h b/src/emu/bus/odyssey2/voice.h
new file mode 100644
index 00000000000..14ffb32c407
--- /dev/null
+++ b/src/emu/bus/odyssey2/voice.h
@@ -0,0 +1,48 @@
+#ifndef __O2_VOICE_H
+#define __O2_VOICE_H
+
+#include "slot.h"
+#include "rom.h"
+#include "sound/sp0256.h"
+
+
+// ======================> o2_voice_device
+
+class o2_voice_device : public o2_rom_device
+{
+public:
+ // construction/destruction
+ o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset() {}
+
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual const rom_entry *device_rom_region() const;
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom04) { if (m_subslot->exists()) return m_subslot->read_rom04(space, offset); else return 0xff; }
+ virtual DECLARE_READ8_MEMBER(read_rom0c) { if (m_subslot->exists()) return m_subslot->read_rom0c(space, offset); else return 0xff; }
+
+ virtual void write_bank(int bank) { if (m_subslot->exists()) m_subslot->write_bank(bank); }
+
+ DECLARE_WRITE_LINE_MEMBER(lrq_callback);
+ DECLARE_WRITE8_MEMBER(io_write);
+ DECLARE_READ8_MEMBER(t0_read) { return m_speech->lrq_r() ? 0 : 1; }
+
+private:
+ required_device<sp0256_device> m_speech;
+ required_device<o2_cart_slot_device> m_subslot;
+
+ int m_lrq_state;
+};
+
+
+
+
+// device type definition
+extern const device_type O2_ROM_VOICE;
+
+
+#endif
diff --git a/src/mess/drivers/odyssey2.c b/src/mess/drivers/odyssey2.c
index 117a6f7cf50..3d1e22a28ec 100644
--- a/src/mess/drivers/odyssey2.c
+++ b/src/mess/drivers/odyssey2.c
@@ -14,12 +14,12 @@
#include "emu.h"
#include "cpu/mcs48/mcs48.h"
-#include "imagedev/cartslot.h"
-#include "sound/sp0256.h"
#include "video/i8244.h"
#include "machine/i8243.h"
#include "video/ef9340_1.h"
+#include "bus/odyssey2/slot.h"
+
class odyssey2_state : public driver_device
{
@@ -28,24 +28,18 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_i8244(*this, "i8244"),
- m_sp0256(*this, "sp0256_speech"),
- m_user1(*this, "user1"),
- m_bank1(*this, "bank1"),
- m_bank2(*this, "bank2"),
+ m_cart(*this, "cartslot"),
m_keyboard(*this, "KEY"),
m_joysticks(*this, "JOY") { }
required_device<cpu_device> m_maincpu;
required_device<i8244_device> m_i8244;
- required_device<sp0256_device> m_sp0256;
+ required_device<o2_cart_slot_device> m_cart;
- int m_the_voice_lrq_state;
UINT8 m_ram[256];
UINT8 m_p1;
UINT8 m_p2;
- int m_cart_size;
UINT8 m_lum;
- DECLARE_READ8_MEMBER(t0_read);
DECLARE_READ8_MEMBER(io_read);
DECLARE_WRITE8_MEMBER(io_write);
DECLARE_READ8_MEMBER(bus_read);
@@ -60,7 +54,6 @@ public:
virtual void machine_reset();
DECLARE_PALETTE_INIT(odyssey2);
UINT32 screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- DECLARE_WRITE_LINE_MEMBER(the_voice_lrq_callback);
DECLARE_WRITE_LINE_MEMBER(irq_callback);
DECLARE_WRITE16_MEMBER(scanline_postprocess);
@@ -76,15 +69,8 @@ protected:
static const UINT8 P1_VDC_COPY_MODE_ENABLE = 0x40;
static const UINT8 P2_KEYBOARD_SELECT_MASK = 0x07; /* select row to scan */
- required_memory_region m_user1;
-
- required_memory_bank m_bank1;
- required_memory_bank m_bank2;
-
required_ioport_array<6> m_keyboard;
required_ioport_array<2> m_joysticks;
-
- void switch_banks();
};
class g7400_state : public odyssey2_state
@@ -115,9 +101,9 @@ protected:
static ADDRESS_MAP_START( odyssey2_mem , AS_PROGRAM, 8, odyssey2_state )
- AM_RANGE(0x0000, 0x03FF) AM_ROM
- AM_RANGE(0x0400, 0x0BFF) AM_RAMBANK("bank1")
- AM_RANGE(0x0C00, 0x0FFF) AM_RAMBANK("bank2")
+ AM_RANGE(0x0000, 0x03ff) AM_ROM
+ AM_RANGE(0x0400, 0x0bff) AM_DEVREAD("cartslot", o2_cart_slot_device, read_rom04)
+ AM_RANGE(0x0c00, 0x0fff) AM_DEVREAD("cartslot", o2_cart_slot_device, read_rom0c)
ADDRESS_MAP_END
@@ -126,7 +112,7 @@ static ADDRESS_MAP_START( odyssey2_io , AS_IO, 8, odyssey2_state )
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(p1_read, p1_write)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_read, p2_write)
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_read, bus_write)
- AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_read)
+ AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_DEVREAD("cartslot", o2_cart_slot_device, t0_read)
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_read)
ADDRESS_MAP_END
@@ -136,7 +122,7 @@ static ADDRESS_MAP_START( g7400_io , AS_IO, 8, g7400_state )
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(p1_read, p1_write)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_read, p2_write)
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_read, bus_write)
- AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_read)
+ AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_DEVREAD("cartslot", o2_cart_slot_device, t0_read)
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_read)
AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_DEVWRITE("i8243", i8243_device, i8243_prog_w);
ADDRESS_MAP_END
@@ -298,67 +284,15 @@ WRITE_LINE_MEMBER(odyssey2_state::irq_callback)
}
-void odyssey2_state::switch_banks()
-{
- switch ( m_cart_size )
- {
- case 12288:
- /* 12KB cart support (for instance, KTAA as released) */
- m_bank1->set_base( m_user1->base() + (m_p1 & 0x03) * 0xC00 );
- m_bank2->set_base( m_user1->base() + (m_p1 & 0x03) * 0xC00 + 0x800 );
- break;
-
- case 16384:
- /* 16KB cart support (for instance, full sized version KTAA) */
- m_bank1->set_base( m_user1->base() + (m_p1 & 0x03) * 0x1000 + 0x400 );
- m_bank2->set_base( m_user1->base() + (m_p1 & 0x03) * 0x1000 + 0xC00 );
- break;
-
- default:
- m_bank1->set_base( m_user1->base() + (m_p1 & 0x03) * 0x800 );
- m_bank2->set_base( m_user1->base() + (m_p1 & 0x03) * 0x800 );
- break;
- }
-}
-
-
-WRITE_LINE_MEMBER(odyssey2_state::the_voice_lrq_callback)
-{
- m_the_voice_lrq_state = state;
-}
-
-
-READ8_MEMBER(odyssey2_state::t0_read)
-{
- return m_sp0256->lrq_r() ? 0 : 1;
-}
-
-
DRIVER_INIT_MEMBER(odyssey2_state,odyssey2)
{
- int i;
- int size = 0;
UINT8 *gfx = memregion("gfx1")->base();
- device_image_interface *image = dynamic_cast<device_image_interface *>(machine().device("cart"));
- for (i = 0; i < 256; i++)
+ for (int i = 0; i < 256; i++)
{
gfx[i] = i; /* TODO: Why i and not 0? */
m_ram[i] = 0;
}
-
- if (image->exists())
- {
- if (image->software_entry() == NULL)
- {
- size = image->length();
- }
- else
- {
- size = image->get_software_region_length("rom");
- }
- }
- m_cart_size = size;
}
@@ -367,9 +301,7 @@ void odyssey2_state::machine_start()
save_pointer(NAME(m_ram),256);
save_item(NAME(m_p1));
save_item(NAME(m_p2));
- save_item(NAME(m_cart_size));
save_item(NAME(m_lum));
- save_item(NAME(m_the_voice_lrq_state));
}
@@ -378,9 +310,9 @@ void odyssey2_state::machine_reset()
m_lum = 0;
/* jump to "last" bank, will work for all sizes due to being mirrored */
- m_p1 = 0xFF;
- m_p2 = 0xFF;
- switch_banks();
+ m_p1 = 0xff;
+ m_p2 = 0xff;
+ m_cart->write_bank(m_p1);
}
@@ -426,17 +358,10 @@ WRITE8_MEMBER(odyssey2_state::io_write)
if ((m_p1 & (P1_EXT_RAM_ENABLE | P1_VDC_COPY_MODE_ENABLE)) == 0x00)
{
m_ram[offset] = data;
- if ( offset & 0x80 )
+ if (offset & 0x80)
{
- if ( data & 0x20 )
- {
- logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1 );
- m_sp0256->ald_w(space, 0, offset & 0x7f);
- }
- else
- {
- m_sp0256->reset();
- }
+ logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1);
+ m_cart->io_write(space, offset, data);
}
}
else if (!(m_p1 & P1_VDC_ENABLE))
@@ -470,6 +395,11 @@ WRITE8_MEMBER(g7400_state::io_write)
if ((m_p1 & (P1_EXT_RAM_ENABLE | P1_VDC_COPY_MODE_ENABLE)) == 0x00)
{
m_ram[offset] = data;
+ if (offset & 0x80)
+ {
+ logerror("voice write %02X, data = %02X (p1 = %02X)\n", offset, data, m_p1);
+ m_cart->io_write(space, offset, data);
+ }
}
else if (!(m_p1 & P1_VDC_ENABLE))
{
@@ -567,8 +497,7 @@ WRITE8_MEMBER(odyssey2_state::p1_write)
{
m_p1 = data;
m_lum = ( data & 0x80 ) >> 4;
-
- switch_banks();
+ m_cart->write_bank(m_p1);
}
@@ -735,11 +664,10 @@ static GFXDECODE_START( odyssey2 )
GFXDECODE_END
+
static MACHINE_CONFIG_FRAGMENT( odyssey2_cartslot )
- MCFG_CARTSLOT_ADD("cart")
- MCFG_CARTSLOT_EXTENSION_LIST("bin,rom")
- MCFG_CARTSLOT_NOT_MANDATORY
- MCFG_CARTSLOT_INTERFACE("odyssey_cart")
+ MCFG_O2_CARTRIDGE_ADD("cartslot", o2_cart, NULL)
+
MCFG_SOFTWARE_LIST_ADD("cart_list","odyssey2")
MACHINE_CONFIG_END
@@ -766,11 +694,6 @@ static MACHINE_CONFIG_START( odyssey2, odyssey2_state )
MCFG_I8244_ADD( "i8244", XTAL_7_15909MHz/2 * 2, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
- MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
- MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(odyssey2_state, the_voice_lrq_callback))
- /* The Voice uses a speaker with its own volume control so the relative volumes to use are subjective, these sound good */
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
-
MCFG_FRAGMENT_ADD(odyssey2_cartslot)
MACHINE_CONFIG_END
@@ -797,10 +720,6 @@ static MACHINE_CONFIG_START( videopac, odyssey2_state )
MCFG_I8245_ADD( "i8244", XTAL_17_73447MHz/5 * 2, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
- MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
- MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(odyssey2_state, the_voice_lrq_callback))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
-
MCFG_FRAGMENT_ADD(odyssey2_cartslot)
MACHINE_CONFIG_END
@@ -830,10 +749,6 @@ static MACHINE_CONFIG_START( g7400, g7400_state )
MCFG_I8245_ADD( "i8244", 3540000 * 2, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( g7400_state, scanline_postprocess ) )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
- MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
- MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(odyssey2_state, the_voice_lrq_callback))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
-
MCFG_FRAGMENT_ADD(odyssey2_cartslot)
MCFG_DEVICE_REMOVE("cart_list")
MCFG_SOFTWARE_LIST_ADD("cart_list","g7400")
@@ -866,10 +781,6 @@ static MACHINE_CONFIG_START( odyssey3, g7400_state )
MCFG_I8244_ADD( "i8244", 3540000 * 2, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( g7400_state, scanline_postprocess ) )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
- MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
- MCFG_SP0256_DATA_REQUEST_CB(WRITELINE(odyssey2_state, the_voice_lrq_callback))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
-
MCFG_FRAGMENT_ADD(odyssey2_cartslot)
MCFG_DEVICE_REMOVE("cart_list")
MCFG_SOFTWARE_LIST_ADD("cart_list","g7400")
@@ -881,26 +792,6 @@ ROM_START (odyssey2)
ROM_REGION(0x10000,"maincpu",0) /* safer for the memory handler/bankswitching??? */
ROM_LOAD ("o2bios.rom", 0x0000, 0x0400, CRC(8016a315) SHA1(b2e1955d957a475de2411770452eff4ea19f4cee))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
-
- ROM_REGION(0x4000, "user1", 0)
- ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_MIRROR)
-
- ROM_REGION( 0x10000, "sp0256_speech", 0 )
- /* SP0256B-019 Speech chip w/2KiB mask rom */
- ROM_LOAD( "sp0256b-019.bin", 0x1000, 0x0800, CRC(4bb43724) SHA1(49f5326ad45392dc96c89d1d4e089a20bd21e609) )
-
- /* A note about "The Voice": Two versions of "The Voice" exist:
- * An earlier version with eight 2KiB speech roms, spr016-??? through spr016-??? on a small daughterboard
- <note to self: fill in numbers later>
- * A later version with one 16KiB speech rom, spr128-003, mounted directly on the mainboard
- The rom contents of these two versions are EXACTLY the same.
- Both versions have an sp0256b-019 speech chip, which has 2KiB of its own internal speech data
- Thanks to kevtris for this info. - LN
- */
- /* External 16KiB speech ROM (spr128-003) from "The Voice" */
- ROM_LOAD( "spr128-003.bin", 0x4000, 0x4000, CRC(509367b5) SHA1(0f31f46bc02e9272885779a6dd7102c78b18895b) )
- /* Additional External 16KiB ROM (spr128-004) from S.I.D. the Spellbinder */
- ROM_LOAD( "spr128-004.bin", 0x8000, 0x4000, CRC(e79dfb75) SHA1(37f33d79ffd1739d7c2f226b010a1eac28d74ca0) )
ROM_END
@@ -911,17 +802,6 @@ ROM_START (videopac)
ROM_SYSTEM_BIOS( 1, "c52", "c52" )
ROMX_LOAD ("c52.bin", 0x0000, 0x0400, CRC(a318e8d6) SHA1(a6120aed50831c9c0d95dbdf707820f601d9452e), ROM_BIOS(2))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
-
- ROM_REGION(0x4000, "user1", 0)
- ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_MIRROR)
-
- ROM_REGION( 0x10000, "sp0256_speech", 0 )
- /* SP0256B-019 Speech chip w/2KiB mask rom */
- ROM_LOAD( "sp0256b-019.bin", 0x1000, 0x0800, CRC(4bb43724) SHA1(49f5326ad45392dc96c89d1d4e089a20bd21e609) )
- /* External 16KiB speech ROM (spr128-003) from "The Voice" */
- ROM_LOAD( "spr128-003.bin", 0x4000, 0x4000, CRC(509367b5) SHA1(0f31f46bc02e9272885779a6dd7102c78b18895b) )
- /* Additional External 16KiB speech ROM (spr128-004) from S.I.D. the Spellbinder */
- ROM_LOAD( "spr128-004.bin", 0x8000, 0x4000, CRC(e79dfb75) SHA1(37f33d79ffd1739d7c2f226b010a1eac28d74ca0) )
ROM_END
@@ -929,9 +809,6 @@ ROM_START (g7400)
ROM_REGION(0x10000,"maincpu",0) /* safer for the memory handler/bankswitching??? */
ROM_LOAD ("g7400.bin", 0x0000, 0x0400, CRC(e20a9f41) SHA1(5130243429b40b01a14e1304d0394b8459a6fbae))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
-
- ROM_REGION(0x4000, "user1", 0)
- ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_MIRROR)
ROM_END
@@ -939,9 +816,6 @@ ROM_START (jopac)
ROM_REGION(0x10000,"maincpu",0) /* safer for the memory handler/bankswitching??? */
ROM_LOAD ("jopac.bin", 0x0000, 0x0400, CRC(11647ca5) SHA1(54b8d2c1317628de51a85fc1c424423a986775e4))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
-
- ROM_REGION(0x4000, "user1", 0)
- ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_MIRROR)
ROM_END
@@ -950,9 +824,6 @@ ROM_START (odyssey3)
ROM_LOAD ("odyssey3.bin", 0x0000, 0x0400, CRC(e2b23324) SHA1(0a38c5f2cea929d2fe0a23e5e1a60de9155815dc))
ROM_REGION(0x100, "gfx1", ROMREGION_ERASEFF)
-
- ROM_REGION(0x4000, "user1", 0)
- ROM_CART_LOAD("cart", 0x000, 0x4000, ROM_MIRROR)
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
diff --git a/src/mess/mess.mak b/src/mess/mess.mak
index ca411b1e79d..9495461e505 100644
--- a/src/mess/mess.mak
+++ b/src/mess/mess.mak
@@ -603,6 +603,7 @@ BUSES += MSX_SLOT
BUSES += NEOGEO
BUSES += NES
BUSES += NUBUS
+BUSES += O2
BUSES += ORICEXT
BUSES += PCE
BUSES += PCI