apricot: add an expansion slot interface and add two ram expansion

cards. this will also be usuable by the apricot f series and portable.
This commit is contained in:
Dirk Best 2015-06-08 20:41:08 +02:00
parent af38621a8b
commit 9b4905c6b6
9 changed files with 635 additions and 17 deletions

View File

@ -162,6 +162,23 @@ if (BUSES["APF"]~=null) then
end
---------------------------------------------------
--
--@src/emu/bus/apricot/expansion.h,BUSES += APRICOT_EXPANSION
---------------------------------------------------
if (BUSES["APRICOT_EXPANSION"]~=null) then
files {
MAME_DIR .. "src/emu/bus/apricot/expansion.c",
MAME_DIR .. "src/emu/bus/apricot/expansion.h",
MAME_DIR .. "src/emu/bus/apricot/cards.c",
MAME_DIR .. "src/emu/bus/apricot/cards.h",
MAME_DIR .. "src/emu/bus/apricot/ram.c",
MAME_DIR .. "src/emu/bus/apricot/ram.h",
}
end
---------------------------------------------------
--
--@src/emu/bus/arcadia/slot.h,BUSES += ARCADIA

View File

@ -572,6 +572,7 @@ BUSES["ABCKB"] = true
BUSES["ADAM"] = true
BUSES["ADAMNET"] = true
BUSES["APF"] = true
BUSES["APRICOT_EXPANSION"] = true
BUSES["ARCADIA"] = true
BUSES["ASTROCADE"] = true
BUSES["BML3"] = true

View File

@ -0,0 +1,14 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
ACT Apricot Expansion Slot Devices
***************************************************************************/
#include "cards.h"
SLOT_INTERFACE_START( apricot_expansion_cards )
SLOT_INTERFACE("256k", APRICOT_256K_RAM)
SLOT_INTERFACE("128_512k", APRICOT_128_512K_RAM)
SLOT_INTERFACE_END

View File

@ -0,0 +1,19 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
ACT Apricot Expansion Slot Devices
***************************************************************************/
#pragma once
#ifndef __APRICOT_CARDS_H__
#define __APRICOT_CARDS_H__
#include "emu.h"
#include "ram.h"
SLOT_INTERFACE_EXTERN( apricot_expansion_cards );
#endif // __APRICOT_CARDS_H__

View File

@ -0,0 +1,166 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
ACT Apricot Expansion Slot
***************************************************************************/
#include "expansion.h"
//**************************************************************************
// EXPANSION SLOT DEVICE
//**************************************************************************
const device_type APRICOT_EXPANSION_SLOT = &device_creator<apricot_expansion_slot_device>;
//-------------------------------------------------
// apricot_expansion_slot_device - constructor
//-------------------------------------------------
apricot_expansion_slot_device::apricot_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, APRICOT_EXPANSION_SLOT, "Apricot Expansion Slot", tag, owner, clock, "apricot_exp_slot", __FILE__),
device_slot_interface(mconfig, *this)
{
}
apricot_expansion_slot_device::apricot_expansion_slot_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_slot_interface(mconfig, *this)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void apricot_expansion_slot_device::device_start()
{
device_apricot_expansion_card_interface *dev = dynamic_cast<device_apricot_expansion_card_interface *>(get_card_device());
if (dev)
{
apricot_expansion_bus_device *bus = downcast<apricot_expansion_bus_device *>(m_owner);
bus->add_card(dev);
}
}
//**************************************************************************
// EXPANSION BUS DEVICE
//**************************************************************************
const device_type APRICOT_EXPANSION_BUS = &device_creator<apricot_expansion_bus_device>;
//-------------------------------------------------
// apricot_expansion_bus_device - constructor
//-------------------------------------------------
apricot_expansion_bus_device::apricot_expansion_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, APRICOT_EXPANSION_BUS, "Apricot Expansion Bus", tag, owner, clock, "apricot_exp_bus", __FILE__),
m_program(NULL),
m_io(NULL),
m_dma1_handler(*this),
m_dma2_handler(*this),
m_ext1_handler(*this),
m_ext2_handler(*this),
m_int2_handler(*this),
m_int3_handler(*this)
{
}
//-------------------------------------------------
// apricot_expansion_bus_device - destructor
//-------------------------------------------------
apricot_expansion_bus_device::~apricot_expansion_bus_device()
{
m_dev.detach_all();
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void apricot_expansion_bus_device::device_start()
{
// resolve callbacks
m_dma1_handler.resolve_safe();
m_dma2_handler.resolve_safe();
m_ext1_handler.resolve_safe();
m_ext2_handler.resolve_safe();
m_int2_handler.resolve_safe();
m_int3_handler.resolve_safe();
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void apricot_expansion_bus_device::device_reset()
{
cpu_device *cpu = m_owner->subdevice<cpu_device>(m_cpu_tag);
if (!cpu->started())
printf("cpu not running yet\n");
m_program = &cpu->space(AS_PROGRAM);
m_io = &cpu->space(AS_IO);
}
//-------------------------------------------------
// add_card - add new card to our bus
//-------------------------------------------------
void apricot_expansion_bus_device::add_card(device_apricot_expansion_card_interface *card)
{
card->set_bus_device(this);
m_dev.append(*card);
}
//-------------------------------------------------
// set_cpu_tag - set cpu we are attached to
//-------------------------------------------------
void apricot_expansion_bus_device::set_cpu_tag(device_t &device, device_t *owner, const char *cpu_tag)
{
apricot_expansion_bus_device &bus = dynamic_cast<apricot_expansion_bus_device &>(device);
bus.m_cpu_tag = cpu_tag;
}
// callbacks from slot device to the host
WRITE_LINE_MEMBER( apricot_expansion_bus_device::dma1_w ) { m_dma1_handler(state); }
WRITE_LINE_MEMBER( apricot_expansion_bus_device::dma2_w ) { m_dma2_handler(state); }
WRITE_LINE_MEMBER( apricot_expansion_bus_device::ext1_w ) { m_ext1_handler(state); }
WRITE_LINE_MEMBER( apricot_expansion_bus_device::ext2_w ) { m_ext2_handler(state); }
WRITE_LINE_MEMBER( apricot_expansion_bus_device::int2_w ) { m_int2_handler(state); }
WRITE_LINE_MEMBER( apricot_expansion_bus_device::int3_w ) { m_int3_handler(state); }
//**************************************************************************
// CARTRIDGE INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_apricot_expansion_card_interface - constructor
//-------------------------------------------------
device_apricot_expansion_card_interface::device_apricot_expansion_card_interface(const machine_config &mconfig, device_t &device) :
device_slot_card_interface(mconfig, device),
m_next(NULL),
m_bus(NULL)
{
}
//-------------------------------------------------
// ~device_apricot_expansion_card_interface - destructor
//-------------------------------------------------
device_apricot_expansion_card_interface::~device_apricot_expansion_card_interface()
{
}
void device_apricot_expansion_card_interface::set_bus_device(apricot_expansion_bus_device *bus)
{
m_bus = bus;
}

View File

@ -0,0 +1,198 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
ACT Apricot Expansion Slot
A B
-12V 32 +12V
+5V 31 +5V
DB0 30 DB1
DB2 29 DB3
DB4 28 DB5
DB6 27 DB7
AB10 26 AB9
AB11 25 AB12
/AMWC 24 /MRDC
/DMA2 23 DT/R
/DMA1 22 /IORC
/MWTC 21 /RES
/IOWC 20 /AIOWC
GND 19 GND
/CLK5 18 DEN
/IRDY 17 /MRDY
/EXT1 16 /EXT2
/INT3 15 /ALE
AB6 14 /INT2
AB8 13 AB7
DB9 12 DB8
DB11 11 DB10
DB13 10 DB12
DB15 9 DB14
AB2 8 AB1
AB4 7 AB3
AB0 6 AB5
AB14 5 AB13
AB15 4 AB16
AB17 3 AB18
AB19 2 /BHE
NMI 1 CLK15
***************************************************************************/
#pragma once
#ifndef __APRICOT_EXPANSION_H__
#define __APRICOT_EXPANSION_H__
#include "emu.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_EXPANSION_ADD(_tag, _cpu_tag) \
MCFG_DEVICE_ADD(_tag, APRICOT_EXPANSION_BUS, 0) \
apricot_expansion_bus_device::set_cpu_tag(*device, owner, _cpu_tag);
#define MCFG_EXPANSION_SLOT_ADD(_tag, _slot_intf, _def_slot) \
MCFG_DEVICE_ADD(_tag, APRICOT_EXPANSION_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
#define MCFG_EXPANSION_DMA1_HANDLER(_devcb) \
devcb = &apricot_expansion_bus_device::set_dma1_handler(*device, DEVCB_##_devcb);
#define MCFG_EXPANSION_DMA2_HANDLER(_devcb) \
devcb = &apricot_expansion_bus_device::set_dma2_handler(*device, DEVCB_##_devcb);
#define MCFG_EXPANSION_EXT1_HANDLER(_devcb) \
devcb = &apricot_expansion_bus_device::set_ext1_handler(*device, DEVCB_##_devcb);
#define MCFG_EXPANSION_EXT2_HANDLER(_devcb) \
devcb = &apricot_expansion_bus_device::set_ext2_handler(*device, DEVCB_##_devcb);
#define MCFG_EXPANSION_INT2_HANDLER(_devcb) \
devcb = &apricot_expansion_bus_device::set_int2_handler(*device, DEVCB_##_devcb);
#define MCFG_EXPANSION_INT3_HANDLER(_devcb) \
devcb = &apricot_expansion_bus_device::set_int3_handler(*device, DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// forward declaration
class device_apricot_expansion_card_interface;
// ======================> apricot_expansion_slot_device
class apricot_expansion_slot_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
apricot_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
apricot_expansion_slot_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-level overrides
virtual void device_start();
};
// device type definition
extern const device_type APRICOT_EXPANSION_SLOT;
// ======================> apricot_expansion_bus_device
class apricot_expansion_bus_device : public device_t
{
public:
// construction/destruction
apricot_expansion_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~apricot_expansion_bus_device();
template<class _Object> static devcb_base &set_dma1_handler(device_t &device, _Object object)
{ return downcast<apricot_expansion_bus_device &>(device).m_dma1_handler.set_callback(object); }
template<class _Object> static devcb_base &set_dma2_handler(device_t &device, _Object object)
{ return downcast<apricot_expansion_bus_device &>(device).m_dma2_handler.set_callback(object); }
template<class _Object> static devcb_base &set_ext1_handler(device_t &device, _Object object)
{ return downcast<apricot_expansion_bus_device &>(device).m_ext1_handler.set_callback(object); }
template<class _Object> static devcb_base &set_ext2_handler(device_t &device, _Object object)
{ return downcast<apricot_expansion_bus_device &>(device).m_ext2_handler.set_callback(object); }
template<class _Object> static devcb_base &set_int2_handler(device_t &device, _Object object)
{ return downcast<apricot_expansion_bus_device &>(device).m_int2_handler.set_callback(object); }
template<class _Object> static devcb_base &set_int3_handler(device_t &device, _Object object)
{ return downcast<apricot_expansion_bus_device &>(device).m_int3_handler.set_callback(object); }
// inline configuration
static void set_cpu_tag(device_t &device, device_t *owner, const char *cpu_tag);
void add_card(device_apricot_expansion_card_interface *card);
address_space *m_program;
address_space *m_io;
// from cards
DECLARE_WRITE_LINE_MEMBER( dma1_w );
DECLARE_WRITE_LINE_MEMBER( dma2_w );
DECLARE_WRITE_LINE_MEMBER( ext1_w );
DECLARE_WRITE_LINE_MEMBER( ext2_w );
DECLARE_WRITE_LINE_MEMBER( int2_w );
DECLARE_WRITE_LINE_MEMBER( int3_w );
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
private:
simple_list<device_apricot_expansion_card_interface> m_dev;
devcb_write_line m_dma1_handler;
devcb_write_line m_dma2_handler;
devcb_write_line m_ext1_handler;
devcb_write_line m_ext2_handler;
devcb_write_line m_int2_handler;
devcb_write_line m_int3_handler;
// configuration
const char *m_cpu_tag;
};
// device type definition
extern const device_type APRICOT_EXPANSION_BUS;
// ======================> device_apricot_expansion_card_interface
class device_apricot_expansion_card_interface : public device_slot_card_interface
{
public:
// construction/destruction
device_apricot_expansion_card_interface(const machine_config &mconfig, device_t &device);
virtual ~device_apricot_expansion_card_interface();
void set_bus_device(apricot_expansion_bus_device *bus);
device_apricot_expansion_card_interface *next() const { return m_next; }
device_apricot_expansion_card_interface *m_next;
protected:
apricot_expansion_bus_device *m_bus;
};
// include here so drivers don't need to
#include "cards.h"
#endif // __APRICOT_EXPANSION_H__

141
src/emu/bus/apricot/ram.c Normal file
View File

@ -0,0 +1,141 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
ACT Apricot RAM Expansions
***************************************************************************/
#include "ram.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type APRICOT_256K_RAM = &device_creator<apricot_256k_ram_device>;
const device_type APRICOT_128_512K_RAM = &device_creator<apricot_128_512k_ram_device>;
//**************************************************************************
// APRICOT 256K RAM DEVICE
//**************************************************************************
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( apricot_256k )
PORT_START("sw")
PORT_DIPNAME(0x01, 0x00, "Base Address")
PORT_DIPSETTING(0x00, "40000H")
PORT_DIPSETTING(0x01, "80000H")
INPUT_PORTS_END
ioport_constructor apricot_256k_ram_device::device_input_ports() const
{
return INPUT_PORTS_NAME( apricot_256k );
}
//-------------------------------------------------
// apricot_256k_ram_device - constructor
//-------------------------------------------------
apricot_256k_ram_device::apricot_256k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, APRICOT_256K_RAM, "Apricot 256K RAM Expansion Board", tag, owner, clock, "apricot_256k_ram", __FILE__),
device_apricot_expansion_card_interface(mconfig, *this),
m_sw(*this, "sw")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void apricot_256k_ram_device::device_start()
{
m_ram.resize(0x40000 / 2);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void apricot_256k_ram_device::device_reset()
{
if (m_sw->read() == 0)
m_bus->m_program->install_ram(0x40000, 0x7ffff, &m_ram[0]);
else
m_bus->m_program->install_ram(0x80000, 0xbffff, &m_ram[0]);
}
//**************************************************************************
// APRICOT 128/512K RAM DEVICE
//**************************************************************************
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( apricot_128_512k )
PORT_START("config")
PORT_CONFNAME(0x01, 0x01, "DRAM Size")
PORT_CONFSETTING(0x00, "64K")
PORT_CONFSETTING(0x01, "256K")
PORT_START("strap")
PORT_DIPNAME(0x03, 0x00, "Base Address")
PORT_DIPSETTING(0x00, "512K")
PORT_DIPSETTING(0x01, "256K - 384K")
PORT_DIPSETTING(0x02, "384K - 512K")
INPUT_PORTS_END
ioport_constructor apricot_128_512k_ram_device::device_input_ports() const
{
return INPUT_PORTS_NAME( apricot_128_512k );
}
//-------------------------------------------------
// apricot_128_512k_ram_device - constructor
//-------------------------------------------------
apricot_128_512k_ram_device::apricot_128_512k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, APRICOT_128_512K_RAM, "Apricot 128/512K RAM Expansion Board", tag, owner, clock, "apricot_128_512k_ram", __FILE__),
device_apricot_expansion_card_interface(mconfig, *this),
m_config(*this, "config"),
m_strap(*this, "strap")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void apricot_128_512k_ram_device::device_start()
{
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void apricot_128_512k_ram_device::device_reset()
{
// 128 or 512k?
if (m_config->read() == 1)
{
m_ram.resize(0x80000 / 2);
if (m_strap->read() == 0)
m_bus->m_program->install_ram(0x40000, 0xbffff, &m_ram[0]);
}
else
{
m_ram.resize(0x20000 / 2);
if (m_strap->read() == 1)
m_bus->m_program->install_ram(0x40000, 0x5ffff, &m_ram[0]);
else if (m_strap->read() == 2)
m_bus->m_program->install_ram(0x60000, 0x7ffff, &m_ram[0]);
}
}

69
src/emu/bus/apricot/ram.h Normal file
View File

@ -0,0 +1,69 @@
// license:GPL-2.0+
// copyright-holders:Dirk Best
/***************************************************************************
ACT Apricot RAM Expansions
***************************************************************************/
#pragma once
#ifndef __APRICOT_RAM__
#define __APRICOT_RAM__
#include "emu.h"
#include "expansion.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> apricot_256k_ram_device
class apricot_256k_ram_device : public device_t, public device_apricot_expansion_card_interface
{
public:
// construction/destruction
apricot_256k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
virtual ioport_constructor device_input_ports() const;
virtual void device_start();
virtual void device_reset();
private:
required_ioport m_sw;
std::vector<UINT16> m_ram;
};
// ======================> apricot_128_512k_ram_device
class apricot_128_512k_ram_device : public device_t, public device_apricot_expansion_card_interface
{
public:
// construction/destruction
apricot_128_512k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
virtual ioport_constructor device_input_ports() const;
virtual void device_start();
virtual void device_reset();
private:
required_ioport m_config;
required_ioport m_strap;
std::vector<UINT16> m_ram;
};
// device type definition
extern const device_type APRICOT_256K_RAM;
extern const device_type APRICOT_128_512K_RAM;
#endif // __APRICOT_RAM__

View File

@ -9,11 +9,8 @@
***************************************************************************/
#include "bus/centronics/ctronics.h"
#include "bus/rs232/rs232.h"
#include "cpu/i86/i86.h"
#include "cpu/i8089/i8089.h"
#include "machine/ram.h"
#include "machine/pit8253.h"
#include "machine/i8255.h"
#include "machine/pic8259.h"
@ -23,6 +20,9 @@
#include "sound/sn76496.h"
#include "imagedev/flopdrv.h"
#include "formats/apridisk.h"
#include "bus/centronics/ctronics.h"
#include "bus/rs232/rs232.h"
#include "bus/apricot/expansion.h"
//**************************************************************************
@ -35,7 +35,6 @@ public:
apricot_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_cpu(*this, "ic91"),
m_ram(*this, RAM_TAG),
m_iop(*this, "ic71"),
m_sn(*this, "ic7"),
m_crtc(*this, "ic30"),
@ -89,7 +88,6 @@ protected:
private:
required_device<i8086_cpu_device> m_cpu;
required_device<ram_device> m_ram;
required_device<i8089_device> m_iop;
required_device<sn76489_device> m_sn;
required_device<mc6845_device> m_crtc;
@ -262,14 +260,13 @@ UINT32 apricot_state::screen_update_apricot(screen_device &screen, bitmap_rgb32
MC6845_UPDATE_ROW( apricot_state::crtc_update_row )
{
UINT8 *ram = m_ram->pointer();
const pen_t *pen = m_palette->pens();
for (int i = 0; i < x_count; i++)
{
UINT16 code = m_screen_buffer[(ma + i) & 0x7ff];
UINT16 offset = ((code & 0x7ff) << 5) | (ra << 1);
UINT16 data = ram[offset + 1] << 8 | ram[offset];
UINT16 data = m_cpu->space(AS_PROGRAM).read_word(offset);
if (m_video_mode)
{
@ -302,9 +299,6 @@ MC6845_UPDATE_ROW( apricot_state::crtc_update_row )
void apricot_state::machine_start()
{
// install shared memory to the main cpu and the iop
m_cpu->space(AS_PROGRAM).install_ram(0x00000, m_ram->size() - 1, m_ram->pointer());
m_iop->space(AS_PROGRAM).install_ram(0x00000, m_ram->size() - 1, m_ram->pointer());
}
IRQ_CALLBACK_MEMBER( apricot_state::irq_callback )
@ -322,8 +316,7 @@ IRQ_CALLBACK_MEMBER( apricot_state::irq_callback )
//**************************************************************************
static ADDRESS_MAP_START( apricot_mem, AS_PROGRAM, 16, apricot_state )
// AM_RANGE(0x00000, 0x3ffff) AM_RAMBANK("standard_ram")
// AM_RANGE(0x40000, 0xeffff) AM_RAMBANK("expansion_ram")
AM_RANGE(0x00000, 0x3ffff) AM_RAM
AM_RANGE(0xf0000, 0xf0fff) AM_MIRROR(0x7000) AM_RAM AM_SHARE("screen_buffer")
AM_RANGE(0xfc000, 0xfffff) AM_MIRROR(0x4000) AM_ROM AM_REGION("bootstrap", 0)
ADDRESS_MAP_END
@ -382,11 +375,6 @@ static MACHINE_CONFIG_START( apricot, apricot_state )
MCFG_SOUND_ADD("ic7", SN76489, XTAL_4MHz / 2)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
// internal ram
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("256k")
MCFG_RAM_EXTRA_OPTIONS("384k,512k") // with 1 or 2 128k expansion boards
// devices
MCFG_DEVICE_ADD("ic17", I8255A, 0)
MCFG_I8255_IN_PORTA_CB(DEVREAD8("cent_data_in", input_buffer_device, read))
@ -441,6 +429,11 @@ static MACHINE_CONFIG_START( apricot, apricot_state )
MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("ic71", i8089_device, drq1_w))
MCFG_FLOPPY_DRIVE_ADD("ic68:0", apricot_floppies, "d32w", apricot_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("ic68:1", apricot_floppies, "d32w", apricot_state::floppy_formats)
// expansion bus
MCFG_EXPANSION_ADD("exp", "ic91")
MCFG_EXPANSION_SLOT_ADD("exp:1", apricot_expansion_cards, NULL)
MCFG_EXPANSION_SLOT_ADD("exp:2", apricot_expansion_cards, NULL)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( apricotxi, apricot )