summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/bus/abc1600/abc1600.c577
-rw-r--r--src/emu/bus/abc1600/abc1600.h228
-rw-r--r--src/emu/bus/abc1600/lux4105.c390
-rw-r--r--src/emu/bus/abc1600/lux4105.h90
-rw-r--r--src/emu/bus/adam/adamlink.c87
-rw-r--r--src/emu/bus/adam/adamlink.h50
-rw-r--r--src/emu/bus/adam/exp.c274
-rw-r--r--src/emu/bus/adam/exp.h154
-rw-r--r--src/emu/bus/adam/ide.c209
-rw-r--r--src/emu/bus/adam/ide.h62
-rw-r--r--src/emu/bus/adam/ram.c74
-rw-r--r--src/emu/bus/adam/ram.h50
-rw-r--r--src/emu/bus/bus.mak177
-rw-r--r--src/emu/bus/bw2/exp.c190
-rw-r--r--src/emu/bus/bw2/exp.h137
-rw-r--r--src/emu/bus/bw2/ramcard.c129
-rw-r--r--src/emu/bus/bw2/ramcard.h62
-rw-r--r--src/emu/bus/c64/cbm_crt.c196
-rw-r--r--src/emu/bus/c64/exp.h2
-rw-r--r--src/emu/bus/cbm2/24k.c90
-rw-r--r--src/emu/bus/cbm2/24k.h49
-rw-r--r--src/emu/bus/cbm2/exp.c304
-rw-r--r--src/emu/bus/cbm2/exp.h162
-rw-r--r--src/emu/bus/cbm2/hrg.c209
-rw-r--r--src/emu/bus/cbm2/hrg.h65
-rw-r--r--src/emu/bus/cbm2/std.c68
-rw-r--r--src/emu/bus/cbm2/std.h49
-rw-r--r--src/emu/bus/cbm2/user.c133
-rw-r--r--src/emu/bus/cbm2/user.h146
-rw-r--r--src/emu/bus/ecbbus/ecbbus.c280
-rw-r--r--src/emu/bus/ecbbus/ecbbus.h170
-rw-r--r--src/emu/bus/ecbbus/grip.c947
-rw-r--r--src/emu/bus/ecbbus/grip.h127
-rw-r--r--src/emu/bus/econet/e01.c773
-rw-r--r--src/emu/bus/econet/e01.h135
-rw-r--r--src/emu/bus/econet/econet.c367
-rw-r--r--src/emu/bus/econet/econet.h183
-rw-r--r--src/emu/bus/ep64/exdos.c246
-rw-r--r--src/emu/bus/ep64/exdos.h67
-rw-r--r--src/emu/bus/ep64/exp.c90
-rw-r--r--src/emu/bus/ep64/exp.h152
-rw-r--r--src/emu/bus/pet/64k.c206
-rw-r--r--src/emu/bus/pet/64k.h59
-rw-r--r--src/emu/bus/pet/c2n.c174
-rw-r--r--src/emu/bus/pet/c2n.h89
-rw-r--r--src/emu/bus/pet/cass.c102
-rw-r--r--src/emu/bus/pet/cass.h120
-rw-r--r--src/emu/bus/pet/diag264_lb_tape.c86
-rw-r--r--src/emu/bus/pet/diag264_lb_tape.h56
-rw-r--r--src/emu/bus/pet/exp.c200
-rw-r--r--src/emu/bus/pet/exp.h146
-rw-r--r--src/emu/bus/pet/superpet.c445
-rw-r--r--src/emu/bus/pet/superpet.h86
-rw-r--r--src/emu/bus/pet/user.c124
-rw-r--r--src/emu/bus/pet/user.h141
-rw-r--r--src/emu/bus/plus4/c1551.c598
-rw-r--r--src/emu/bus/plus4/c1551.h106
-rw-r--r--src/emu/bus/plus4/diag264_lb_user.c49
-rw-r--r--src/emu/bus/plus4/diag264_lb_user.h63
-rw-r--r--src/emu/bus/plus4/exp.c329
-rw-r--r--src/emu/bus/plus4/exp.h201
-rw-r--r--src/emu/bus/plus4/sid.c168
-rw-r--r--src/emu/bus/plus4/sid.h62
-rw-r--r--src/emu/bus/plus4/std.c72
-rw-r--r--src/emu/bus/plus4/std.h49
-rw-r--r--src/emu/bus/plus4/user.c105
-rw-r--r--src/emu/bus/plus4/user.h129
-rw-r--r--src/emu/bus/vcs/ctrl.c114
-rw-r--r--src/emu/bus/vcs/ctrl.h135
-rw-r--r--src/emu/bus/vcs/joybooster.c96
-rw-r--r--src/emu/bus/vcs/joybooster.h60
-rw-r--r--src/emu/bus/vcs/joystick.c77
-rw-r--r--src/emu/bus/vcs/joystick.h54
-rw-r--r--src/emu/bus/vcs/keypad.c140
-rw-r--r--src/emu/bus/vcs/keypad.h60
-rw-r--r--src/emu/bus/vcs/lightpen.c88
-rw-r--r--src/emu/bus/vcs/lightpen.h58
-rw-r--r--src/emu/bus/vcs/paddles.c102
-rw-r--r--src/emu/bus/vcs/paddles.h61
-rw-r--r--src/emu/bus/vcs/wheel.c77
-rw-r--r--src/emu/bus/vcs/wheel.h53
-rw-r--r--src/emu/bus/vic10/exp.c287
-rw-r--r--src/emu/bus/vic10/exp.h188
-rw-r--r--src/emu/bus/vic10/std.c81
-rw-r--r--src/emu/bus/vic10/std.h50
-rw-r--r--src/emu/bus/vic20/exp.c334
-rw-r--r--src/emu/bus/vic20/exp.h192
-rw-r--r--src/emu/bus/vic20/megacart.c131
-rw-r--r--src/emu/bus/vic20/megacart.h63
-rw-r--r--src/emu/bus/vic20/std.c72
-rw-r--r--src/emu/bus/vic20/std.h49
-rw-r--r--src/emu/bus/vic20/user.c136
-rw-r--r--src/emu/bus/vic20/user.h158
-rw-r--r--src/emu/bus/vic20/vic1010.c129
-rw-r--r--src/emu/bus/vic20/vic1010.h72
-rw-r--r--src/emu/bus/vic20/vic1011.c166
-rw-r--r--src/emu/bus/vic20/vic1011.h60
-rw-r--r--src/emu/bus/vic20/vic1110.c119
-rw-r--r--src/emu/bus/vic20/vic1110.h56
-rw-r--r--src/emu/bus/vic20/vic1111.c83
-rw-r--r--src/emu/bus/vic20/vic1111.h50
-rw-r--r--src/emu/bus/vic20/vic1112.c256
-rw-r--r--src/emu/bus/vic20/vic1112.h75
-rw-r--r--src/emu/bus/vic20/vic1210.c80
-rw-r--r--src/emu/bus/vic20/vic1210.h51
-rw-r--r--src/emu/bus/vidbrain/exp.c260
-rw-r--r--src/emu/bus/vidbrain/exp.h185
-rw-r--r--src/emu/bus/vidbrain/money_minder.c79
-rw-r--r--src/emu/bus/vidbrain/money_minder.h49
-rw-r--r--src/emu/bus/vidbrain/std.c65
-rw-r--r--src/emu/bus/vidbrain/std.h48
-rw-r--r--src/emu/bus/vidbrain/timeshare.c78
-rw-r--r--src/emu/bus/vidbrain/timeshare.h49
-rw-r--r--src/emu/emu.mak13
-rw-r--r--src/emu/machine/64h156.c778
-rw-r--r--src/emu/machine/64h156.h210
-rw-r--r--src/emu/machine/machine.mak36
-rw-r--r--src/emu/machine/mos6702.c71
-rw-r--r--src/emu/machine/mos6702.h69
-rw-r--r--src/emu/machine/mos8706.c81
-rw-r--r--src/emu/machine/mos8706.h73
-rw-r--r--src/emu/machine/mos8722.c429
-rw-r--r--src/emu/machine/mos8722.h119
123 files changed, 18719 insertions, 1 deletions
diff --git a/src/emu/bus/abc1600/abc1600.c b/src/emu/bus/abc1600/abc1600.c
new file mode 100644
index 00000000000..585402548de
--- /dev/null
+++ b/src/emu/bus/abc1600/abc1600.c
@@ -0,0 +1,577 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Luxor ABC 1600 Expansion Bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "abc1600.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type ABC1600BUS_SLOT = &device_creator<abc1600bus_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE ABC1600BUS CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_abc1600bus_card_interface - constructor
+//-------------------------------------------------
+
+device_abc1600bus_card_interface::device_abc1600bus_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_abc1600bus_card_interface - destructor
+//-------------------------------------------------
+
+device_abc1600bus_card_interface::~device_abc1600bus_card_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// abc1600bus_slot_device - constructor
+//-------------------------------------------------
+
+abc1600bus_slot_device::abc1600bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ABC1600BUS_SLOT, "ABC 1600 bus slot", tag, owner, clock, "abc1600bus_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_int(CLEAR_LINE),
+ m_pren(1),
+ m_trrq(1),
+ m_nmi(CLEAR_LINE),
+ m_xint2(CLEAR_LINE),
+ m_xint3(CLEAR_LINE),
+ m_xint4(CLEAR_LINE),
+ m_xint5(CLEAR_LINE)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void abc1600bus_slot_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const abc1600bus_interface *intf = reinterpret_cast<const abc1600bus_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<abc1600bus_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_int_cb, 0, sizeof(m_out_int_cb));
+ memset(&m_out_pren_cb, 0, sizeof(m_out_pren_cb));
+ memset(&m_out_trrq_cb, 0, sizeof(m_out_trrq_cb));
+ memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb));
+ memset(&m_out_xint2_cb, 0, sizeof(m_out_xint2_cb));
+ memset(&m_out_xint3_cb, 0, sizeof(m_out_xint3_cb));
+ memset(&m_out_xint4_cb, 0, sizeof(m_out_xint4_cb));
+ memset(&m_out_xint5_cb, 0, sizeof(m_out_xint5_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void abc1600bus_slot_device::device_start()
+{
+ m_card = dynamic_cast<device_abc1600bus_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_out_int_func.resolve(m_out_int_cb, *this);
+ m_out_pren_func.resolve(m_out_pren_cb, *this);
+ m_out_trrq_func.resolve(m_out_trrq_cb, *this);
+ m_out_nmi_func.resolve(m_out_nmi_cb, *this);
+ m_out_xint2_func.resolve(m_out_xint2_cb, *this);
+ m_out_xint3_func.resolve(m_out_xint3_cb, *this);
+ m_out_xint4_func.resolve(m_out_xint4_cb, *this);
+ m_out_xint5_func.resolve(m_out_xint5_cb, *this);
+
+ // state saving
+ save_item(NAME(m_int));
+ save_item(NAME(m_pren));
+ save_item(NAME(m_trrq));
+ save_item(NAME(m_nmi));
+ save_item(NAME(m_xint2));
+ save_item(NAME(m_xint3));
+ save_item(NAME(m_xint4));
+ save_item(NAME(m_xint5));
+}
+
+
+//-------------------------------------------------
+// cs_w -
+//-------------------------------------------------
+
+void abc1600bus_slot_device::cs_w(UINT8 data)
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_cs(data);
+ }
+}
+
+
+//-------------------------------------------------
+// csb_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::csb_r )
+{
+ int data = 1;
+
+ if (m_card != NULL)
+ {
+ data = m_card->abc1600bus_csb();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// brst_w - reset
+//-------------------------------------------------
+
+void abc1600bus_slot_device::brst_w()
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_brst();
+ }
+}
+
+
+//-------------------------------------------------
+// inp_r -
+//-------------------------------------------------
+
+UINT8 abc1600bus_slot_device::inp_r()
+{
+ UINT8 data = 0xff;
+
+ if (m_card != NULL)
+ {
+ data &= m_card->abc1600bus_inp();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// out_w -
+//-------------------------------------------------
+
+void abc1600bus_slot_device::out_w(UINT8 data)
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_out(data);
+ }
+}
+
+
+//-------------------------------------------------
+// stat_r -
+//-------------------------------------------------
+
+UINT8 abc1600bus_slot_device::stat_r()
+{
+ UINT8 data = 0xff;
+
+ if (m_card != NULL)
+ {
+ data &= m_card->abc1600bus_stat();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// stat_r -
+//-------------------------------------------------
+
+UINT8 abc1600bus_slot_device::ops_r()
+{
+ UINT8 data = 0xff;
+
+ if (m_card != NULL)
+ {
+ data &= m_card->abc1600bus_ops();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// c1_w -
+//-------------------------------------------------
+
+void abc1600bus_slot_device::c1_w(UINT8 data)
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_c1(data);
+ }
+}
+
+
+//-------------------------------------------------
+// c2_w -
+//-------------------------------------------------
+
+void abc1600bus_slot_device::c2_w(UINT8 data)
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_c2(data);
+ }
+}
+
+
+//-------------------------------------------------
+// c3_w -
+//-------------------------------------------------
+
+void abc1600bus_slot_device::c3_w(UINT8 data)
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_c3(data);
+ }
+}
+
+
+//-------------------------------------------------
+// c4_w -
+//-------------------------------------------------
+
+void abc1600bus_slot_device::c4_w(UINT8 data)
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_c4(data);
+ }
+}
+
+
+//-------------------------------------------------
+// exp_r -
+//-------------------------------------------------
+
+UINT8 abc1600bus_slot_device::exp_r()
+{
+ UINT8 data = 0xff;
+
+ if (m_card != NULL)
+ {
+ data &= m_card->abc1600bus_exp();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// xcsb2_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xcsb2_r )
+{
+ int data = 1;
+
+ if (m_card != NULL)
+ {
+ data = m_card->abc1600bus_xcsb2();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// xcsb3_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xcsb3_r )
+{
+ int data = 1;
+
+ if (m_card != NULL)
+ {
+ data = m_card->abc1600bus_xcsb3();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// xcsb4_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xcsb4_r )
+{
+ int data = 1;
+
+ if (m_card != NULL)
+ {
+ data = m_card->abc1600bus_xcsb4();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// xcsb5_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xcsb5_r )
+{
+ int data = 1;
+
+ if (m_card != NULL)
+ {
+ data = m_card->abc1600bus_xcsb5();
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// tren_w - transfer enable
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::tren_w )
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_tren(state);
+ }
+}
+
+
+//-------------------------------------------------
+// prac_w - peripheral acknowledge
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::prac_w )
+{
+ if (m_card != NULL)
+ {
+ m_card->abc1600bus_prac(state);
+ }
+}
+
+
+//-------------------------------------------------
+// int_w - interrupt request
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::int_w )
+{
+ m_int = state;
+ m_out_int_func(state);
+}
+
+
+//-------------------------------------------------
+// pren_w - peripheral enable
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::pren_w )
+{
+ m_pren = state;
+ m_out_pren_func(state);
+}
+
+
+//-------------------------------------------------
+// trrq_w - transfer request
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::trrq_w )
+{
+ m_trrq = state;
+ m_out_trrq_func(state);
+}
+
+
+//-------------------------------------------------
+// nmi_w - non-maskable interrupt
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::nmi_w )
+{
+ m_nmi = state;
+ m_out_nmi_func(state);
+}
+
+
+//-------------------------------------------------
+// xint2_w - expansion interrupt
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::xint2_w )
+{
+ m_xint2 = state;
+ m_out_xint2_func(state);
+}
+
+
+//-------------------------------------------------
+// xint3_w - expansion interrupt
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::xint3_w )
+{
+ m_xint3 = state;
+ m_out_xint3_func(state);
+}
+
+
+//-------------------------------------------------
+// xint4_w - expansion interrupt
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::xint4_w )
+{
+ m_xint4 = state;
+ m_out_xint4_func(state);
+}
+
+
+//-------------------------------------------------
+// xint5_w - expansion interrupt
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( abc1600bus_slot_device::xint5_w )
+{
+ m_xint5 = state;
+ m_out_xint5_func(state);
+}
+
+
+//-------------------------------------------------
+// int_r - interrupt request
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::int_r )
+{
+ return m_int;
+}
+
+
+//-------------------------------------------------
+// pren_r - peripheral enable
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::pren_r )
+{
+ return m_pren;
+}
+
+
+//-------------------------------------------------
+// trrq_r - transfer request
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::trrq_r )
+{
+ return m_trrq;
+}
+
+
+//-------------------------------------------------
+// nmi_r - non-maskable interrupt
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::nmi_r )
+{
+ return m_nmi;
+}
+
+
+//-------------------------------------------------
+// xint2_r - expansion interrupt
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xint2_r )
+{
+ return m_xint2;
+}
+
+
+//-------------------------------------------------
+// xint3_r - expansion interrupt
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xint3_r )
+{
+ return m_xint3;
+}
+
+
+//-------------------------------------------------
+// xint4_r - expansion interrupt
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xint4_r )
+{
+ return m_xint4;
+}
+
+
+//-------------------------------------------------
+// xint5_r - expansion interrupt
+//-------------------------------------------------
+
+READ_LINE_MEMBER( abc1600bus_slot_device::xint5_r )
+{
+ return m_xint5;
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFAC( abc1600bus_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( abc1600bus_cards )
+ SLOT_INTERFACE("4105", LUXOR_4105) // SASI interface
+// SLOT_INTERFACE("4077", LUXOR_4077) // Winchester controller
+// SLOT_INTERFACE("4004", LUXOR_4004) // ICOM I/O (Z80, Z80PIO, Z80SIO/2, Z80CTC, 2 Z80DMAs, 2 PROMs, 64KB RAM)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/abc1600/abc1600.h b/src/emu/bus/abc1600/abc1600.h
new file mode 100644
index 00000000000..df73977ea4b
--- /dev/null
+++ b/src/emu/bus/abc1600/abc1600.h
@@ -0,0 +1,228 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Luxor ABC 1600 Expansion Bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ A B
+ -12 V --- * 1 * --- -12V
+ 0 V --- * 2 * --- 0 V
+ BPCLK* --- * 3 * --- BPCLK
+ 0 V --- * 4 * --- 0 V
+ INT* --- * 5 * --- 0 V
+ D7 --- * 6 * --- 0 V
+ D6 --- * 7 * ---
+ D5 --- * 8 * ---
+ D4 --- * 9 * ---
+ D3 --- * 10 * --- XINT*5^
+ D2 --- * 11 * --- XINT*4^
+ D1 --- * 12 * --- XINT*3^
+ D0 --- * 13 * --- XINT*2^
+ CSB* --- * 14 * --- XCSB*2^
+ BRST* --- * 15 * --- XCSB*3^
+ STAT* --- * 16 * --- XCSB*4^
+ INP* --- * 17 * --- XCSB*5^
+ C4* --- * 18 * ---
+ C3* --- * 19 * ---
+ C2* --- * 20 * ---
+ C1* --- * 21 * --- EXP*^
+ OUT* --- * 22 * --- BUSEN*^
+ CS* --- * 23 * --- DSTB*
+ NMI*^ --- * 24 * --- 0 V
+ OPS* --- * 25 * --- A4
+ --- * 26 * --- A3
+ TREN* --- * 27 * --- A2
+ TRRQ* --- * 28 * --- A1
+ PRAC* --- * 29 * --- A0
+ PREN* --- * 30 * --- DIRW/R*
+ +5 V --- * 31 * --- +5 V
+ +12 V --- * 32 * --- +12 V
+
+ ^ only connected on BUS0X
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ABC1600BUS__
+#define __ABC1600BUS__
+
+#include "emu.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define ABC1600BUS_TAG "abc1600bus"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define ABC1600BUS_INTERFACE(_name) \
+ const abc1600bus_interface (_name) =
+
+
+#define MCFG_ABC1600BUS_SLOT_ADD(_tag, _config, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, ABC1600BUS_SLOT, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> abc1600bus_interface
+
+struct abc1600bus_interface
+{
+ devcb_write_line m_out_int_cb;
+ devcb_write_line m_out_pren_cb;
+ devcb_write_line m_out_trrq_cb;
+
+ // the following are connected only on BUS0X
+ devcb_write_line m_out_nmi_cb;
+ devcb_write_line m_out_xint2_cb;
+ devcb_write_line m_out_xint3_cb;
+ devcb_write_line m_out_xint4_cb;
+ devcb_write_line m_out_xint5_cb;
+};
+
+
+// ======================> device_abc1600bus_card_interface
+
+class abc1600bus_slot_device;
+
+// class representing interface-specific live abc1600bus card
+class device_abc1600bus_card_interface : public device_slot_card_interface
+{
+ friend class abc1600bus_slot_device;
+
+public:
+ // construction/destruction
+ device_abc1600bus_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_abc1600bus_card_interface();
+
+ // required operation overrides
+ virtual void abc1600bus_cs(UINT8 data) = 0;
+ virtual int abc1600bus_csb() = 0;
+
+ // optional operation overrides
+ virtual void abc1600bus_brst() { };
+ virtual UINT8 abc1600bus_inp() { return 0xff; };
+ virtual void abc1600bus_out(UINT8 data) { };
+ virtual UINT8 abc1600bus_stat() { return 0xff; };
+ virtual UINT8 abc1600bus_ops() { return 0xff; };
+ virtual void abc1600bus_c1(UINT8 data) { };
+ virtual void abc1600bus_c2(UINT8 data) { };
+ virtual void abc1600bus_c3(UINT8 data) { };
+ virtual void abc1600bus_c4(UINT8 data) { };
+ virtual void abc1600bus_tren(int state) { };
+ virtual void abc1600bus_prac(int state) { };
+ virtual UINT8 abc1600bus_exp() { return 0xff; };
+ virtual int abc1600bus_xcsb2() { return 1; };
+ virtual int abc1600bus_xcsb3() { return 1; };
+ virtual int abc1600bus_xcsb4() { return 1; };
+ virtual int abc1600bus_xcsb5() { return 1; };
+
+public:
+ abc1600bus_slot_device *m_bus;
+};
+
+
+// ======================> abc1600bus_slot_device
+
+class abc1600bus_slot_device : public device_t,
+ public device_slot_interface,
+ public abc1600bus_interface
+{
+public:
+ // construction/destruction
+ abc1600bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_config_complete();
+
+ void cs_w(UINT8 data);
+ DECLARE_READ_LINE_MEMBER( csb_r );
+ void brst_w();
+ UINT8 inp_r();
+ void out_w(UINT8 data);
+ UINT8 stat_r();
+ UINT8 ops_r();
+ void c1_w(UINT8 data);
+ void c2_w(UINT8 data);
+ void c3_w(UINT8 data);
+ void c4_w(UINT8 data);
+ UINT8 exp_r();
+ DECLARE_READ_LINE_MEMBER( xcsb2_r );
+ DECLARE_READ_LINE_MEMBER( xcsb3_r );
+ DECLARE_READ_LINE_MEMBER( xcsb4_r );
+ DECLARE_READ_LINE_MEMBER( xcsb5_r );
+ DECLARE_WRITE_LINE_MEMBER( tren_w );
+ DECLARE_WRITE_LINE_MEMBER( prac_w );
+
+ DECLARE_WRITE_LINE_MEMBER( int_w );
+ DECLARE_WRITE_LINE_MEMBER( pren_w );
+ DECLARE_WRITE_LINE_MEMBER( trrq_w );
+ DECLARE_WRITE_LINE_MEMBER( nmi_w );
+ DECLARE_WRITE_LINE_MEMBER( xint2_w );
+ DECLARE_WRITE_LINE_MEMBER( xint3_w );
+ DECLARE_WRITE_LINE_MEMBER( xint4_w );
+ DECLARE_WRITE_LINE_MEMBER( xint5_w );
+
+ DECLARE_READ_LINE_MEMBER( int_r );
+ DECLARE_READ_LINE_MEMBER( pren_r );
+ DECLARE_READ_LINE_MEMBER( trrq_r );
+ DECLARE_READ_LINE_MEMBER( nmi_r );
+ DECLARE_READ_LINE_MEMBER( xint2_r );
+ DECLARE_READ_LINE_MEMBER( xint3_r );
+ DECLARE_READ_LINE_MEMBER( xint4_r );
+ DECLARE_READ_LINE_MEMBER( xint5_r );
+
+private:
+ devcb_resolved_write_line m_out_int_func;
+ devcb_resolved_write_line m_out_pren_func;
+ devcb_resolved_write_line m_out_trrq_func;
+ devcb_resolved_write_line m_out_nmi_func;
+ devcb_resolved_write_line m_out_xint2_func;
+ devcb_resolved_write_line m_out_xint3_func;
+ devcb_resolved_write_line m_out_xint4_func;
+ devcb_resolved_write_line m_out_xint5_func;
+
+ device_abc1600bus_card_interface *m_card;
+
+ int m_int;
+ int m_pren;
+ int m_trrq;
+ int m_nmi;
+ int m_xint2;
+ int m_xint3;
+ int m_xint4;
+ int m_xint5;
+};
+
+
+// device type definition
+extern const device_type ABC1600BUS_SLOT;
+
+
+// slot devices
+#include "lux4105.h"
+
+SLOT_INTERFACE_EXTERN( abc1600bus_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/abc1600/lux4105.c b/src/emu/bus/abc1600/lux4105.c
new file mode 100644
index 00000000000..f145f1de806
--- /dev/null
+++ b/src/emu/bus/abc1600/lux4105.c
@@ -0,0 +1,390 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Luxor 4105 SASI hard disk controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+*********************************************************************/
+
+#include "lux4105.h"
+#include "machine/scsibus.h"
+#include "machine/scsicb.h"
+#include "machine/scsihd.h"
+#include "machine/s1410.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define SASIBUS_TAG "sasi"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type LUXOR_4105 = &device_creator<luxor_4105_device>;
+
+
+WRITE_LINE_MEMBER( luxor_4105_device::sasi_bsy_w )
+{
+ if (state)
+ {
+ m_sasibus->scsi_sel_w(0);
+ }
+}
+
+WRITE_LINE_MEMBER( luxor_4105_device::sasi_io_w )
+{
+ if (!state)
+ {
+ m_sasibus->scsi_data_w(m_data);
+ }
+
+ update_trrq_int();
+}
+
+WRITE_LINE_MEMBER( luxor_4105_device::sasi_req_w )
+{
+ if (state)
+ {
+ m_sasibus->scsi_ack_w(0);
+ }
+
+ update_trrq_int();
+}
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( luxor_4105 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( luxor_4105 )
+ MCFG_SCSIBUS_ADD(SASIBUS_TAG)
+ MCFG_SCSIDEV_ADD(SASIBUS_TAG ":harddisk0", S1410, SCSI_ID_0)
+ MCFG_SCSICB_ADD(SASIBUS_TAG ":host")
+ MCFG_SCSICB_BSY_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, luxor_4105_device, sasi_bsy_w))
+ MCFG_SCSICB_IO_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, luxor_4105_device, sasi_io_w))
+ MCFG_SCSICB_REQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, luxor_4105_device, sasi_req_w))
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor luxor_4105_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( luxor_4105 );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( luxor_4105 )
+//-------------------------------------------------
+
+INPUT_PORTS_START( luxor_4105 )
+ PORT_START("1E")
+ PORT_DIPNAME( 0x03, 0x00, "Stepping" ) PORT_DIPLOCATION("1E:1,2")
+ PORT_DIPSETTING( 0x00, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x01, "Half (Seagate/Texas)" )
+ PORT_DIPSETTING( 0x02, "Half (Tandon)" )
+ PORT_DIPSETTING( 0x03, "Buffered" )
+ PORT_DIPNAME( 0x0c, 0x00, "Heads" ) PORT_DIPLOCATION("1E:3,4")
+ PORT_DIPSETTING( 0x00, "2" )
+ PORT_DIPSETTING( 0x04, "4" )
+ PORT_DIPSETTING( 0x08, "6" )
+ PORT_DIPSETTING( 0x0c, "8" )
+ PORT_DIPNAME( 0xf0, 0x00, "Drive Type" ) PORT_DIPLOCATION("1E:5,6,7,8")
+ PORT_DIPSETTING( 0x00, "Seagate ST506" )
+ PORT_DIPSETTING( 0x10, "Rodime RO100" )
+ PORT_DIPSETTING( 0x20, "Shugart SA600" )
+ PORT_DIPSETTING( 0x30, "Seagate ST412" )
+
+ PORT_START("5E")
+ PORT_DIPNAME( 0x7f, 0x25, "Card Address" ) PORT_DIPLOCATION("5E:1,2,3,4,5,6,7")
+ PORT_DIPSETTING( 0x25, "37" )
+ PORT_DIPSETTING( 0x2d, "45" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor luxor_4105_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( luxor_4105 );
+}
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+inline void luxor_4105_device::update_trrq_int()
+{
+ int cd = !m_sasibus->scsi_cd_r();
+ int req = !m_sasibus->scsi_req_r();
+ int trrq = !(cd & !req);
+
+ if (BIT(m_dma, 5))
+ {
+ m_slot->int_w(trrq ? CLEAR_LINE : ASSERT_LINE);
+ }
+ else
+ {
+ m_slot->int_w(CLEAR_LINE);
+ }
+
+ if (BIT(m_dma, 6))
+ {
+ m_slot->trrq_w(trrq);
+ }
+ else
+ {
+ m_slot->trrq_w(1);
+ }
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// luxor_4105_device - constructor
+//-------------------------------------------------
+
+luxor_4105_device::luxor_4105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, LUXOR_4105, "Luxor 4105", tag, owner, clock, "luxor_4105", __FILE__),
+ device_abc1600bus_card_interface(mconfig, *this),
+ m_sasibus(*this, SASIBUS_TAG ":host"),
+ m_1e(*this, "1E"),
+ m_5e(*this, "5E")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void luxor_4105_device::device_start()
+{
+ m_slot = dynamic_cast<abc1600bus_slot_device *>(owner());
+
+ // state saving
+ save_item(NAME(m_cs));
+ save_item(NAME(m_data));
+ save_item(NAME(m_dma));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void luxor_4105_device::device_reset()
+{
+ m_cs = 0;
+ m_data = 0;
+ m_dma = 0;
+
+ m_sasibus->scsi_rst_w(1);
+ m_sasibus->scsi_rst_w(0);
+
+ m_slot->trrq_w(1);
+}
+
+
+
+//**************************************************************************
+// ABC 1600 BUS INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// abc1600bus_cs -
+//-------------------------------------------------
+
+void luxor_4105_device::abc1600bus_cs(UINT8 data)
+{
+ m_cs = (data == m_5e->read());
+}
+
+
+//-------------------------------------------------
+// abc1600bus_csb -
+//-------------------------------------------------
+
+int luxor_4105_device::abc1600bus_csb()
+{
+ return !m_cs;
+}
+
+
+//-------------------------------------------------
+// abc1600bus_rst -
+//-------------------------------------------------
+
+void luxor_4105_device::abc1600bus_brst()
+{
+ device_reset();
+}
+
+
+//-------------------------------------------------
+// abc1600bus_stat -
+//-------------------------------------------------
+
+UINT8 luxor_4105_device::abc1600bus_stat()
+{
+ UINT8 data = 0xff;
+
+ if (m_cs)
+ {
+ /*
+
+ bit description
+
+ 0 ?
+ 1 ?
+ 2 ?
+ 3 ?
+ 4
+ 5
+ 6 ? (tested at 014D9A, after command 08 sent and 1 byte read from SASI, should be 1)
+ 7
+
+ */
+
+ data = m_sasibus->scsi_bsy_r();
+ data |= m_sasibus->scsi_req_r() << 2;
+ data |= m_sasibus->scsi_cd_r() << 3;
+ data |= m_sasibus->scsi_io_r() << 6;
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// abc1600bus_inp -
+//-------------------------------------------------
+
+UINT8 luxor_4105_device::abc1600bus_inp()
+{
+ UINT8 data = 0xff;
+
+ if (m_cs)
+ {
+ if (!m_sasibus->scsi_bsy_r())
+ {
+ data = m_1e->read();
+ }
+ else
+ {
+ if (m_sasibus->scsi_io_r())
+ {
+ data = m_sasibus->scsi_data_r();
+
+ if (m_sasibus->scsi_req_r())
+ {
+ m_sasibus->scsi_ack_w(1);
+ }
+ }
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// abc1600bus_utp -
+//-------------------------------------------------
+
+void luxor_4105_device::abc1600bus_out(UINT8 data)
+{
+ if (m_cs)
+ {
+ m_data = data;
+
+ if (!m_sasibus->scsi_io_r())
+ {
+ m_sasibus->scsi_data_w(m_data);
+
+ if (m_sasibus->scsi_req_r())
+ {
+ m_sasibus->scsi_ack_w(1);
+ }
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// abc1600bus_c1 -
+//-------------------------------------------------
+
+void luxor_4105_device::abc1600bus_c1(UINT8 data)
+{
+ if (m_cs)
+ {
+ m_sasibus->scsi_sel_w(1);
+ }
+}
+
+
+//-------------------------------------------------
+// abc1600bus_c3 -
+//-------------------------------------------------
+
+void luxor_4105_device::abc1600bus_c3(UINT8 data)
+{
+ if (m_cs)
+ {
+ m_data = 0;
+ m_dma = 0;
+
+ m_sasibus->scsi_rst_w(1);
+ m_sasibus->scsi_rst_w(0);
+ }
+}
+
+
+//-------------------------------------------------
+// abc1600bus_c4 -
+//-------------------------------------------------
+
+void luxor_4105_device::abc1600bus_c4(UINT8 data)
+{
+ if (m_cs)
+ {
+ /*
+
+ bit description
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5 byte interrupt enable?
+ 6 DMA/CPU mode (1=DMA, 0=CPU)?
+ 7 error interrupt enable?
+
+ */
+
+ m_dma = data;
+
+ update_trrq_int();
+ }
+}
diff --git a/src/emu/bus/abc1600/lux4105.h b/src/emu/bus/abc1600/lux4105.h
new file mode 100644
index 00000000000..61a945525f1
--- /dev/null
+++ b/src/emu/bus/abc1600/lux4105.h
@@ -0,0 +1,90 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Luxor 4105 SASI hard disk controller emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+*********************************************************************/
+
+#pragma once
+
+#ifndef __LUXOR_4105__
+#define __LUXOR_4105__
+
+
+#include "emu.h"
+#include "abc1600.h"
+#include "machine/scsicb.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LUXOR_4105_TAG "luxor_4105"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> luxor_4105_device
+
+class luxor_4105_device : public device_t,
+ public device_abc1600bus_card_interface
+{
+public:
+ // construction/destruction
+ luxor_4105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+
+ // not really public
+ DECLARE_WRITE_LINE_MEMBER( sasi_bsy_w );
+ DECLARE_WRITE_LINE_MEMBER( sasi_io_w );
+ DECLARE_WRITE_LINE_MEMBER( sasi_req_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_abc1600bus_interface overrides
+ virtual void abc1600bus_cs(UINT8 data);
+ virtual int abc1600bus_csb();
+ virtual void abc1600bus_brst();
+ virtual UINT8 abc1600bus_inp();
+ virtual void abc1600bus_out(UINT8 data);
+ virtual UINT8 abc1600bus_stat();
+ virtual void abc1600bus_c1(UINT8 data);
+ virtual void abc1600bus_c3(UINT8 data);
+ virtual void abc1600bus_c4(UINT8 data);
+
+private:
+ inline void update_trrq_int();
+
+ abc1600bus_slot_device *m_slot;
+
+ required_device<scsicb_device> m_sasibus;
+ required_ioport m_1e;
+ required_ioport m_5e;
+
+ int m_cs;
+ UINT8 m_data;
+ UINT8 m_dma;
+};
+
+
+// device type definition
+extern const device_type LUXOR_4105;
+
+
+
+#endif
diff --git a/src/emu/bus/adam/adamlink.c b/src/emu/bus/adam/adamlink.c
new file mode 100644
index 00000000000..a3fd6e1407b
--- /dev/null
+++ b/src/emu/bus/adam/adamlink.c
@@ -0,0 +1,87 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Coleco AdamLink 300 Baud Modem emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "adamlink.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type ADAMLINK = &device_creator<adamlink_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// adamlink_device - constructor
+//-------------------------------------------------
+
+adamlink_device::adamlink_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, ADAMLINK, "AdamLink modem", tag, owner, clock, "adamlink", __FILE__),
+ device_adam_expansion_slot_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void adamlink_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// adam_bd_r - buffered data read
+//-------------------------------------------------
+
+UINT8 adamlink_device::adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (!biorq)
+ {
+ switch (offset)
+ {
+ case 0x5e:
+ break;
+
+ case 0x5f:
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// adam_bd_w - buffered data write
+//-------------------------------------------------
+
+void adamlink_device::adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (!biorq)
+ {
+ switch (offset)
+ {
+ case 0x5e:
+ break;
+
+ case 0x5f:
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/adam/adamlink.h b/src/emu/bus/adam/adamlink.h
new file mode 100644
index 00000000000..c06fcb82e57
--- /dev/null
+++ b/src/emu/bus/adam/adamlink.h
@@ -0,0 +1,50 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Coleco AdamLink 300 Baud Modem emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ADAMLINK__
+#define __ADAMLINK__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> adamlink_device
+
+class adamlink_device : public device_t,
+ public device_adam_expansion_slot_card_interface
+{
+public:
+ // construction/destruction
+ adamlink_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_adam_expansion_slot_card_interface overrides
+ virtual UINT8 adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+ virtual void adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+};
+
+
+// device type definition
+extern const device_type ADAMLINK;
+
+
+
+#endif
diff --git a/src/emu/bus/adam/exp.c b/src/emu/bus/adam/exp.c
new file mode 100644
index 00000000000..a092c30edc4
--- /dev/null
+++ b/src/emu/bus/adam/exp.c
@@ -0,0 +1,274 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Coleco Adam Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type ADAM_EXPANSION_SLOT = &device_creator<adam_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE C64_EXPANSION CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_adam_expansion_slot_card_interface - constructor
+//-------------------------------------------------
+
+device_adam_expansion_slot_card_interface::device_adam_expansion_slot_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_rom(NULL),
+ m_ram(NULL),
+ m_rom_mask(0),
+ m_ram_mask(0)
+{
+ m_slot = dynamic_cast<adam_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_adam_expansion_slot_card_interface - destructor
+//-------------------------------------------------
+
+device_adam_expansion_slot_card_interface::~device_adam_expansion_slot_card_interface()
+{
+}
+
+
+//-------------------------------------------------
+// adam_rom_pointer - get expansion ROM pointer
+//-------------------------------------------------
+
+UINT8* device_adam_expansion_slot_card_interface::adam_rom_pointer(running_machine &machine, size_t size)
+{
+ if (m_rom == NULL)
+ {
+ m_rom = auto_alloc_array(machine, UINT8, size);
+
+ m_rom_mask = size - 1;
+ }
+
+ return m_rom;
+}
+
+
+//-------------------------------------------------
+// adam_ram_pointer - get expansion ROM pointer
+//-------------------------------------------------
+
+UINT8* device_adam_expansion_slot_card_interface::adam_ram_pointer(running_machine &machine, size_t size)
+{
+ if (m_ram == NULL)
+ {
+ m_ram = auto_alloc_array(machine, UINT8, size);
+
+ m_ram_mask = size - 1;
+ }
+
+ return m_ram;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// adam_expansion_slot_device - constructor
+//-------------------------------------------------
+
+adam_expansion_slot_device::adam_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ADAM_EXPANSION_SLOT, "ADAM expansion slot", tag, owner, clock, "adam_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ device_image_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// adam_expansion_slot_device - destructor
+//-------------------------------------------------
+
+adam_expansion_slot_device::~adam_expansion_slot_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void adam_expansion_slot_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const adam_expansion_slot_interface *intf = reinterpret_cast<const adam_expansion_slot_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<adam_expansion_slot_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_int_cb, 0, sizeof(m_out_int_cb));
+ }
+
+ // set brief and instance name
+ update_names();
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void adam_expansion_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_adam_expansion_slot_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_out_int_func.resolve(m_out_int_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void adam_expansion_slot_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// call_load -
+//-------------------------------------------------
+
+bool adam_expansion_slot_device::call_load()
+{
+ if (m_cart)
+ {
+ size_t size = 0;
+
+ if (software_entry() == NULL)
+ {
+ size = length();
+
+ fread(m_cart->adam_rom_pointer(machine(), size), size);
+ }
+ else
+ {
+ size = get_software_region_length("rom");
+ if (size) memcpy(m_cart->adam_rom_pointer(machine(), size), get_software_region("rom"), size);
+
+ size = get_software_region_length("ram");
+ if (size) memcpy(m_cart->adam_ram_pointer(machine(), size), get_software_region("ram"), size);
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+//-------------------------------------------------
+// call_softlist_load -
+//-------------------------------------------------
+
+bool adam_expansion_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
+{
+ load_software_part_region(this, swlist, swname, start_entry);
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// get_default_card_software -
+//-------------------------------------------------
+
+const char * adam_expansion_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
+{
+ return software_get_default_slot(config, options, this, "standard");
+}
+
+
+//-------------------------------------------------
+// bd_r - buffered data read
+//-------------------------------------------------
+
+UINT8 adam_expansion_slot_device::bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (m_cart != NULL)
+ {
+ data = m_cart->adam_bd_r(space, offset, data, bmreq, biorq, aux_rom_cs, cas1, cas2);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cd_w - cartridge data write
+//-------------------------------------------------
+
+void adam_expansion_slot_device::bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (m_cart != NULL)
+ {
+ m_cart->adam_bd_w(space, offset, data, bmreq, biorq, aux_rom_cs, cas1, cas2);
+ }
+}
+
+WRITE_LINE_MEMBER( adam_expansion_slot_device::int_w ) { m_out_int_func(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( adam_slot1_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( adam_slot1_devices )
+ SLOT_INTERFACE("adamlink", ADAMLINK)
+SLOT_INTERFACE_END
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( adam_slot2_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( adam_slot2_devices )
+ SLOT_INTERFACE("ide", ADAM_IDE)
+SLOT_INTERFACE_END
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( adam_slot3_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( adam_slot3_devices )
+ SLOT_INTERFACE("ram", ADAM_RAM)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/adam/exp.h b/src/emu/bus/adam/exp.h
new file mode 100644
index 00000000000..42bb1f230a5
--- /dev/null
+++ b/src/emu/bus/adam/exp.h
@@ -0,0 +1,154 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Coleco Adam Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ADAM_EXPANSION_SLOT__
+#define __ADAM_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define ADAM_LEFT_EXPANSION_SLOT_TAG "slot1"
+#define ADAM_CENTER_EXPANSION_SLOT_TAG "slot2"
+#define ADAM_RIGHT_EXPANSION_SLOT_TAG "slot3"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define ADAM_EXPANSION_SLOT_INTERFACE(_name) \
+ const adam_expansion_slot_interface (_name) =
+
+
+#define MCFG_ADAM_EXPANSION_SLOT_ADD(_tag, _clock, _config, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, ADAM_EXPANSION_SLOT, _clock) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> adam_expansion_slot_interface
+
+struct adam_expansion_slot_interface
+{
+ devcb_write_line m_out_int_cb;
+};
+
+
+// ======================> adam_expansion_slot_device
+
+class device_adam_expansion_slot_card_interface;
+
+class adam_expansion_slot_device : public device_t,
+ public adam_expansion_slot_interface,
+ public device_slot_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ adam_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~adam_expansion_slot_device();
+
+ // computer interface
+ UINT8 bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+ void bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( int_w );
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
+
+ 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 char *image_interface() const { return "adam_rom"; }
+ virtual const char *file_extensions() const { return "bin,rom"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // slot interface overrides
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
+
+ devcb_resolved_write_line m_out_int_func;
+
+ device_adam_expansion_slot_card_interface *m_cart;
+};
+
+
+// ======================> device_adam_expansion_slot_card_interface
+
+class device_adam_expansion_slot_card_interface : public device_slot_card_interface
+{
+ friend class adam_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_adam_expansion_slot_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_adam_expansion_slot_card_interface();
+
+protected:
+ // initialization
+ virtual UINT8* adam_rom_pointer(running_machine &machine, size_t size);
+ virtual UINT8* adam_ram_pointer(running_machine &machine, size_t size);
+
+ // runtime
+ virtual UINT8 adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2) { return data; }
+ virtual void adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2) { }
+
+ adam_expansion_slot_device *m_slot;
+
+ UINT8 *m_rom;
+ UINT8 *m_ram;
+
+ size_t m_rom_mask;
+ size_t m_ram_mask;
+};
+
+
+// device type definition
+extern const device_type ADAM_EXPANSION_SLOT;
+
+
+// slot devices
+#include "adamlink.h"
+#include "ide.h"
+#include "ram.h"
+
+SLOT_INTERFACE_EXTERN( adam_slot1_devices );
+SLOT_INTERFACE_EXTERN( adam_slot2_devices );
+SLOT_INTERFACE_EXTERN( adam_slot3_devices );
+
+
+
+#endif
diff --git a/src/emu/bus/adam/ide.c b/src/emu/bus/adam/ide.c
new file mode 100644
index 00000000000..bc15a7bbc3c
--- /dev/null
+++ b/src/emu/bus/adam/ide.c
@@ -0,0 +1,209 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Micro Innovations Powermate IDE Hard Disk emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - parallel status port
+ - memory bank switching port
+ - boot ROM
+
+*/
+
+#include "ide.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define ATA_TAG "ata"
+#define CENTRONICS_TAG "centronics"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type ADAM_IDE = &device_creator<powermate_ide_device>;
+
+
+//-------------------------------------------------
+// ROM( adam_ata )
+//-------------------------------------------------
+
+ROM_START( adam_ata )
+ ROM_REGION( 0x1000, "rom", 0 )
+ ROM_LOAD( "exp.rom", 0x0000, 0x1000, NO_DUMP )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *powermate_ide_device::device_rom_region() const
+{
+ return ROM_NAME( adam_ata );
+}
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( adam_ata )
+//-------------------------------------------------
+static MACHINE_CONFIG_FRAGMENT( adam_ata )
+ MCFG_ATA_INTERFACE_ADD(ATA_TAG, ata_devices, "hdd", NULL, false)
+ MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor powermate_ide_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( adam_ata );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// powermate_ide_device - constructor
+//-------------------------------------------------
+
+powermate_ide_device::powermate_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, ADAM_IDE, "Powermate HP IDE", tag, owner, clock, "adam_ide", __FILE__),
+ device_adam_expansion_slot_card_interface(mconfig, *this),
+ m_ata(*this, ATA_TAG),
+ m_centronics(*this, CENTRONICS_TAG)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void powermate_ide_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// adam_bd_r - buffered data read
+//-------------------------------------------------
+
+UINT8 powermate_ide_device::adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (!biorq)
+ {
+ switch (offset & 0xff)
+ {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ data = m_ata->read_cs0(space, offset & 0x07, 0xff);
+ break;
+
+ case 0x40: // Printer status
+ /*
+
+ bit description
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+
+ */
+ break;
+
+ case 0x58:
+ m_ata_data = m_ata->read_cs0(space, 0, 0xffff);
+
+ data = m_ata_data & 0xff;
+ break;
+
+ case 0x59:
+ data = m_ata_data >> 8;
+ break;
+
+ case 0x5a:
+ data = m_ata->read_cs1(space, 6, 0xff);
+ break;
+
+ case 0x5b: // Digital Input Register
+ data = 0xff;
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// adam_bd_w - buffered data write
+//-------------------------------------------------
+
+void powermate_ide_device::adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (!biorq)
+ {
+ switch (offset & 0xff)
+ {
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ m_ata->write_cs0(space, offset & 0x07, data, 0xff);
+ break;
+
+ case 0x40:
+ m_centronics->write(space, 0, data);
+ break;
+
+ case 0x42: // Bank Number
+ break;
+
+ case 0x58:
+ m_ata_data |= data;
+ m_ata->write_cs0(space, 0, m_ata_data, 0xffff);
+ break;
+
+ case 0x59:
+ m_ata_data = data << 8;
+ break;
+
+ case 0x5a: // Fixed Disk Control Register
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/adam/ide.h b/src/emu/bus/adam/ide.h
new file mode 100644
index 00000000000..11950249301
--- /dev/null
+++ b/src/emu/bus/adam/ide.h
@@ -0,0 +1,62 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Micro Innovations Powermate IDE Hard Disk emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ADAM_IDE__
+#define __ADAM_IDE__
+
+#include "emu.h"
+#include "exp.h"
+#include "machine/ctronics.h"
+#include "machine/ataintf.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> powermate_ide_device
+
+class powermate_ide_device : public device_t,
+ public device_adam_expansion_slot_card_interface
+{
+public:
+ // construction/destruction
+ powermate_ide_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_adam_expansion_slot_card_interface overrides
+ virtual UINT8 adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+ virtual void adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+
+private:
+ required_device<ata_interface_device> m_ata;
+ required_device<centronics_device> m_centronics;
+
+ UINT16 m_ata_data;
+};
+
+
+// device type definition
+extern const device_type ADAM_IDE;
+
+
+
+#endif
diff --git a/src/emu/bus/adam/ram.c b/src/emu/bus/adam/ram.c
new file mode 100644
index 00000000000..8c51fb2f7ac
--- /dev/null
+++ b/src/emu/bus/adam/ram.c
@@ -0,0 +1,74 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Coleco Adam Internal 64KB RAM Expansion emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "ram.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type ADAM_RAM = &device_creator<adam_ram_expansion_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// adam_ram_expansion_device - constructor
+//-------------------------------------------------
+
+adam_ram_expansion_device::adam_ram_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, ADAM_RAM, "Adam 64KB RAM expansion", tag, owner, clock, "adam_ram", __FILE__),
+ device_adam_expansion_slot_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void adam_ram_expansion_device::device_start()
+{
+ adam_ram_pointer(machine(), 64 * 1024);
+}
+
+
+//-------------------------------------------------
+// adam_bd_r - buffered data read
+//-------------------------------------------------
+
+UINT8 adam_ram_expansion_device::adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (!cas2)
+ {
+ data = m_ram[offset];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// adam_bd_w - buffered data write
+//-------------------------------------------------
+
+void adam_ram_expansion_device::adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2)
+{
+ if (!cas2)
+ {
+ m_ram[offset] = data;
+ }
+}
diff --git a/src/emu/bus/adam/ram.h b/src/emu/bus/adam/ram.h
new file mode 100644
index 00000000000..96c8d53d941
--- /dev/null
+++ b/src/emu/bus/adam/ram.h
@@ -0,0 +1,50 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Coleco Adam Internal 64KB RAM Expansion emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ADAM_RAM__
+#define __ADAM_RAM__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> adam_ram_expansion_device
+
+class adam_ram_expansion_device : public device_t,
+ public device_adam_expansion_slot_card_interface
+{
+public:
+ // construction/destruction
+ adam_ram_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_adam_expansion_slot_card_interface overrides
+ virtual UINT8 adam_bd_r(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+ virtual void adam_bd_w(address_space &space, offs_t offset, UINT8 data, int bmreq, int biorq, int aux_rom_cs, int cas1, int cas2);
+};
+
+
+// device type definition
+extern const device_type ADAM_RAM;
+
+
+
+#endif
diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak
index 192a0685def..eb28955810a 100644
--- a/src/emu/bus/bus.mak
+++ b/src/emu/bus/bus.mak
@@ -16,6 +16,17 @@ BUSOBJ = $(EMUOBJ)/bus
#-------------------------------------------------
#
+#@src/emu/bus/abc1600/abc1600.h,BUSES += ABC1600
+#-------------------------------------------------
+
+ifneq ($(filter ABC1600,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/abc1600/abc1600.o
+BUSOBJS += $(BUSOBJ)/abc1600/lux4105.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/abcbus/abcbus.h,BUSES += ABCBUS
#-------------------------------------------------
@@ -37,6 +48,19 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/adam/exp.h,BUSES += ADAM
+#-------------------------------------------------
+
+ifneq ($(filter ADAM,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/adam/exp.o
+BUSOBJS += $(BUSOBJ)/adam/adamlink.o
+BUSOBJS += $(BUSOBJ)/adam/ide.o
+BUSOBJS += $(BUSOBJ)/adam/ram.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/adamnet/adamnet.h,BUSES += ADAMNET
#-------------------------------------------------
@@ -52,6 +76,17 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/bw2/exp.h,BUSES += BW2
+#-------------------------------------------------
+
+ifneq ($(filter BW2,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/bw2/exp.o
+BUSOBJS += $(BUSOBJ)/bw2/ramcard.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/c64/exp.h,BUSES += C64
#@src/emu/bus/c64/user.h,BUSES += C64
#-------------------------------------------------
@@ -135,6 +170,21 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/cbm2/exp.h,BUSES += CBM2
+#@src/emu/bus/cbm2/user.h,BUSES += CBM2
+#-------------------------------------------------
+
+ifneq ($(filter CBM2,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/cbm2/exp.o
+BUSOBJS += $(BUSOBJ)/cbm2/24k.o
+BUSOBJS += $(BUSOBJ)/cbm2/hrg.o
+BUSOBJS += $(BUSOBJ)/cbm2/std.o
+BUSOBJS += $(BUSOBJ)/cbm2/user.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/cbmiec/cbmiec.h,BUSES += CBMIEC
#-------------------------------------------------
@@ -172,6 +222,39 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/ecbbus/ecbbus.h,BUSES += ECBBUS
+#-------------------------------------------------
+
+ifneq ($(filter ECBBUS,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/ecbbus/ecbbus.o
+BUSOBJS += $(BUSOBJ)/ecbbus/grip.o
+endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/econet/econet.h,BUSES += ECONET
+#-------------------------------------------------
+
+ifneq ($(filter ECONET,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/econet/econet.o
+BUSOBJS += $(BUSOBJ)/econet/e01.o
+endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/ep64/exp.h,BUSES += EP64
+#-------------------------------------------------
+
+ifneq ($(filter EP64,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/ep64/exp.o
+BUSOBJS += $(BUSOBJ)/ep64/exdos.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/ieee488/ieee488.h,BUSES += IEEE488
#-------------------------------------------------
@@ -201,6 +284,40 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/pet/cass.h,BUSES += PET
+#@src/emu/bus/pet/exp.h,BUSES += PET
+#@src/emu/bus/pet/user.h,BUSES += PET
+#-------------------------------------------------
+
+ifneq ($(filter PET,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/pet/cass.o
+BUSOBJS += $(BUSOBJ)/pet/c2n.o
+BUSOBJS += $(BUSOBJ)/pet/diag264_lb_tape.o
+BUSOBJS += $(BUSOBJ)/pet/exp.o
+BUSOBJS += $(BUSOBJ)/pet/64k.o
+BUSOBJS += $(BUSOBJ)/pet/superpet.o
+BUSOBJS += $(BUSOBJ)/pet/user.o
+endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/plus4/exp.h,BUSES += PLUS4
+#@src/emu/bus/plus4/user.h,BUSES += PLUS4
+#-------------------------------------------------
+
+ifneq ($(filter PLUS4,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/plus4/exp.o
+BUSOBJS += $(BUSOBJ)/plus4/c1551.o
+BUSOBJS += $(BUSOBJ)/plus4/sid.o
+BUSOBJS += $(BUSOBJ)/plus4/std.o
+BUSOBJS += $(BUSOBJ)/plus4/user.o
+BUSOBJS += $(BUSOBJ)/plus4/diag264_lb_user.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/s100/s100.h,BUSES += S100
#-------------------------------------------------
@@ -217,6 +334,66 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/vcs/ctrl.h,BUSES += VCS
+#-------------------------------------------------
+
+ifneq ($(filter VCS,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/vcs/ctrl.o
+BUSOBJS += $(BUSOBJ)/vcs/joystick.o
+BUSOBJS += $(BUSOBJ)/vcs/joybooster.o
+BUSOBJS += $(BUSOBJ)/vcs/keypad.o
+BUSOBJS += $(BUSOBJ)/vcs/lightpen.o
+BUSOBJS += $(BUSOBJ)/vcs/paddles.o
+BUSOBJS += $(BUSOBJ)/vcs/wheel.o
+endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/vic10/exp.h,BUSES += VIC10
+#-------------------------------------------------
+
+ifneq ($(filter VIC10,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/vic10/exp.o
+BUSOBJS += $(BUSOBJ)/vic10/std.o
+endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/vic20/exp.h,BUSES += VIC20
+#@src/emu/bus/vic20/user.h,BUSES += VIC20
+#-------------------------------------------------
+
+ifneq ($(filter VIC20,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/vic20/exp.o
+BUSOBJS += $(BUSOBJ)/vic20/megacart.o
+BUSOBJS += $(BUSOBJ)/vic20/std.o
+BUSOBJS += $(BUSOBJ)/vic20/vic1010.o
+BUSOBJS += $(BUSOBJ)/vic20/vic1110.o
+BUSOBJS += $(BUSOBJ)/vic20/vic1111.o
+BUSOBJS += $(BUSOBJ)/vic20/vic1112.o
+BUSOBJS += $(BUSOBJ)/vic20/vic1210.o
+BUSOBJS += $(BUSOBJ)/vic20/user.o
+BUSOBJS += $(BUSOBJ)/vic20/vic1011.o
+endif
+
+
+#-------------------------------------------------
+#
+#@src/emu/bus/vidbrain/exp.h,BUSES += VIDBRAIN
+#-------------------------------------------------
+
+ifneq ($(filter VIDBRAIN,$(BUSES)),)
+BUSOBJS += $(BUSOBJ)/vidbrain/exp.o
+BUSOBJS += $(BUSOBJ)/vidbrain/std.o
+BUSOBJS += $(BUSOBJ)/vidbrain/money_minder.o
+BUSOBJS += $(BUSOBJ)/vidbrain/timeshare.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/vip/byteio.h,BUSES += VIP
#@src/emu/bus/vip/exp.h,BUSES += VIP
#-------------------------------------------------
diff --git a/src/emu/bus/bw2/exp.c b/src/emu/bus/bw2/exp.c
new file mode 100644
index 00000000000..505322cfcb9
--- /dev/null
+++ b/src/emu/bus/bw2/exp.c
@@ -0,0 +1,190 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Bondwell 2 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type BW2_EXPANSION_SLOT = &device_creator<bw2_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_bw2_expansion_slot_interface - constructor
+//-------------------------------------------------
+
+device_bw2_expansion_slot_interface::device_bw2_expansion_slot_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_slot = dynamic_cast<bw2_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_bw2_expansion_slot_interface - destructor
+//-------------------------------------------------
+
+device_bw2_expansion_slot_interface::~device_bw2_expansion_slot_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// bw2_expansion_slot_device - constructor
+//-------------------------------------------------
+
+bw2_expansion_slot_device::bw2_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, BW2_EXPANSION_SLOT, "Bondwell 2 expansion port", tag, owner, clock, "bw2_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// bw2_expansion_slot_device - destructor
+//-------------------------------------------------
+
+bw2_expansion_slot_device::~bw2_expansion_slot_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void bw2_expansion_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_bw2_expansion_slot_interface *>(get_card_device());
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void bw2_expansion_slot_device::device_reset()
+{
+ if (m_cart != NULL)
+ {
+ m_cart->device().reset();
+ }
+}
+
+
+//-------------------------------------------------
+// cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 bw2_expansion_slot_device::cd_r(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6)
+{
+ if (m_cart != NULL)
+ {
+ data = m_cart->bw2_cd_r(space, offset, data, ram2, ram3, ram4, ram5, ram6);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cd_w - cartridge data write
+//-------------------------------------------------
+
+void bw2_expansion_slot_device::cd_w(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6)
+{
+ if (m_cart != NULL)
+ {
+ m_cart->bw2_cd_w(space, offset, data, ram2, ram3, ram4, ram5, ram6);
+ }
+}
+
+
+//-------------------------------------------------
+// slot_r - slot read
+//-------------------------------------------------
+
+READ8_MEMBER( bw2_expansion_slot_device::slot_r )
+{
+ UINT8 data = 0xff;
+
+ if (m_cart != NULL)
+ {
+ data = m_cart->bw2_slot_r(space, offset);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// slot_w - slot write
+//-------------------------------------------------
+
+WRITE8_MEMBER( bw2_expansion_slot_device::slot_w )
+{
+ if (m_cart != NULL)
+ {
+ m_cart->bw2_slot_w(space, offset, data);
+ }
+}
+
+
+//-------------------------------------------------
+// modsel_r - modsel read
+//-------------------------------------------------
+
+READ8_MEMBER( bw2_expansion_slot_device::modsel_r )
+{
+ UINT8 data = 0xff;
+
+ if (m_cart != NULL)
+ {
+ data = m_cart->bw2_modsel_r(space, offset);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// modsel_w - modsel write
+//-------------------------------------------------
+
+WRITE8_MEMBER( bw2_expansion_slot_device::modsel_w )
+{
+ if (m_cart != NULL)
+ {
+ m_cart->bw2_modsel_w(space, offset, data);
+ }
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( bw2_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( bw2_expansion_cards )
+ SLOT_INTERFACE("ramcard", BW2_RAMCARD)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/bw2/exp.h b/src/emu/bus/bw2/exp.h
new file mode 100644
index 00000000000..af1f58be548
--- /dev/null
+++ b/src/emu/bus/bw2/exp.h
@@ -0,0 +1,137 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Bondwell 2 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ 5V 1 26 12V
+ D3 2 27 12V
+ A1 3 28 A3
+ A2 4 29 A4
+ _CTSB 5 30 A5
+ _RST 6 31 A6
+ _MODSEL 7 32 A7
+ 16MHZ 8 33 A8
+ _IORQ 9 34 A9
+ _RD 10 35 A10
+ D0 11 36 A11
+ D1 12 37 A12
+ D2 13 38 A13
+ A0 14 39 A14
+ D4 15 40 _RAM6
+ D5 16 41 _RAM5
+ D6 17 42 _RFSH
+ D7 18 43 _WR
+ DCDB 19 44 SELECT
+ _DTRB 20 45 _RAM2
+ _RTSB 21 46 _RAM3
+ _DSRB 22 47 _RAM4
+ TXDB 23 48 _SLOT
+ RXDB 24 49 GND
+ GND 25 50 5V
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __BW2_EXPANSION_SLOT__
+#define __BW2_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define BW2_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_BW2_EXPANSION_SLOT_ADD(_tag, _clock, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, BW2_EXPANSION_SLOT, _clock) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> bw2_expansion_slot_device
+
+class device_bw2_expansion_slot_interface;
+
+class bw2_expansion_slot_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ bw2_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~bw2_expansion_slot_device();
+
+ // computer interface
+ UINT8 cd_r(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6);
+ void cd_w(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6);
+
+ DECLARE_READ8_MEMBER( slot_r );
+ DECLARE_WRITE8_MEMBER( slot_w );
+
+ DECLARE_READ8_MEMBER( modsel_r );
+ DECLARE_WRITE8_MEMBER( modsel_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ device_bw2_expansion_slot_interface *m_cart;
+};
+
+
+// ======================> device_bw2_expansion_slot_interface
+
+// class representing interface-specific live bw2_expansion card
+class device_bw2_expansion_slot_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_bw2_expansion_slot_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_bw2_expansion_slot_interface();
+
+ virtual UINT8 bw2_cd_r(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6) { return data; };
+ virtual void bw2_cd_w(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6) { };
+
+ virtual UINT8 bw2_slot_r(address_space &space, offs_t offset) { return 0xff; }
+ virtual void bw2_slot_w(address_space &space, offs_t offset, UINT8 data) { }
+
+ virtual UINT8 bw2_modsel_r(address_space &space, offs_t offset) { return 0xff; }
+ virtual void bw2_modsel_w(address_space &space, offs_t offset, UINT8 data) { }
+
+protected:
+ bw2_expansion_slot_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type BW2_EXPANSION_SLOT;
+
+
+// slot devices
+#include "ramcard.h"
+
+SLOT_INTERFACE_EXTERN( bw2_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/bw2/ramcard.c b/src/emu/bus/bw2/ramcard.c
new file mode 100644
index 00000000000..94d53dc0dae
--- /dev/null
+++ b/src/emu/bus/bw2/ramcard.c
@@ -0,0 +1,129 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Bondwell 2 RAMCARD emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "ramcard.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type BW2_RAMCARD = &device_creator<bw2_ramcard_device>;
+
+
+//-------------------------------------------------
+// ROM( bw2_ramcard )
+//-------------------------------------------------
+
+ROM_START( bw2_ramcard )
+ ROM_REGION( 0x4000, "ramcard", 0 )
+ ROM_LOAD( "ramcard-10.ic10", 0x0000, 0x4000, CRC(68cde1ba) SHA1(a776a27d64f7b857565594beb63aa2cd692dcf04) )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *bw2_ramcard_device::device_rom_region() const
+{
+ return ROM_NAME( bw2_ramcard );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// bw2_ramcard_device - constructor
+//-------------------------------------------------
+
+bw2_ramcard_device::bw2_ramcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, BW2_RAMCARD, "RAMCARD", tag, owner, clock, "bw2_ramcard", __FILE__),
+ device_bw2_expansion_slot_interface(mconfig, *this),
+ m_rom(*this, "ramcard"),
+ m_ram(*this, "ram"),
+ m_en(0),
+ m_bank(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void bw2_ramcard_device::device_start()
+{
+ // allocate memory
+ m_ram.allocate(512 * 1024);
+
+ // state saving
+ save_item(NAME(m_en));
+ save_item(NAME(m_bank));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void bw2_ramcard_device::device_reset()
+{
+ m_en = 0;
+ m_bank = 0;
+}
+
+
+//-------------------------------------------------
+// bw2_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 bw2_ramcard_device::bw2_cd_r(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6)
+{
+ if (!ram2)
+ {
+ data = m_rom->base()[offset & 0x3fff];
+ }
+ else if (m_en && !ram5)
+ {
+ data = m_ram[(m_bank << 15) | offset];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// bw2_cd_r - cartridge data write
+//-------------------------------------------------
+
+void bw2_ramcard_device::bw2_cd_w(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6)
+{
+ if (m_en && !ram5)
+ {
+ m_ram[(m_bank << 15) | offset] = data;
+ }
+}
+
+
+//-------------------------------------------------
+// bw2_slot_w - slot write
+//-------------------------------------------------
+
+void bw2_ramcard_device::bw2_slot_w(address_space &space, offs_t offset, UINT8 data)
+{
+ m_en = 1;
+ m_bank = data & 0x0f;
+}
diff --git a/src/emu/bus/bw2/ramcard.h b/src/emu/bus/bw2/ramcard.h
new file mode 100644
index 00000000000..47c93403628
--- /dev/null
+++ b/src/emu/bus/bw2/ramcard.h
@@ -0,0 +1,62 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Bondwell 2 RAMCARD emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __BW2_RAMCARD__
+#define __BW2_RAMCARD__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> bw2_ramcard_device
+
+class bw2_ramcard_device : public device_t,
+ public device_bw2_expansion_slot_interface
+{
+public:
+ // construction/destruction
+ bw2_ramcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_bw2_expansion_slot_interface overrides
+ virtual UINT8 bw2_cd_r(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6);
+ virtual void bw2_cd_w(address_space &space, offs_t offset, UINT8 data, int ram2, int ram3, int ram4, int ram5, int ram6);
+ virtual void bw2_slot_w(address_space &space, offs_t offset, UINT8 data);
+
+private:
+ required_memory_region m_rom;
+ optional_shared_ptr<UINT8> m_ram;
+
+ int m_en;
+ UINT8 m_bank;
+};
+
+
+// device type definition
+extern const device_type BW2_RAMCARD;
+
+
+
+#endif
diff --git a/src/emu/bus/c64/cbm_crt.c b/src/emu/bus/c64/cbm_crt.c
new file mode 100644
index 00000000000..54b127c5af5
--- /dev/null
+++ b/src/emu/bus/c64/cbm_crt.c
@@ -0,0 +1,196 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/*********************************************************************
+
+ cbm_crt.c
+
+ Commodore C64 cartridge images
+
+*********************************************************************/
+
+#include "cbm_crt.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+// slot names for the C64 cartridge types
+static const char * CRT_C64_SLOT_NAMES[_CRT_C64_COUNT] =
+{
+ "standard",
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ "simons_basic",
+ "ocean",
+ UNSUPPORTED,
+ "fun_play",
+ "super_games",
+ UNSUPPORTED,
+ "epyxfastload",
+ "westermann",
+ "rex",
+ UNSUPPORTED,
+ "magic_formel",
+ "system3",
+ "warp_speed",
+ "dinamic",
+ "zaxxon",
+ "magic_desk",
+ UNSUPPORTED,
+ "comal80",
+ "struct_basic",
+ "ross",
+ "ep64",
+ "ep7x8",
+ "dela_ep256",
+ "rex_ep256",
+ "mikroasm",
+ UNSUPPORTED,
+ UNSUPPORTED,
+ "stardos",
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ "ieee488",
+ UNSUPPORTED,
+ UNSUPPORTED,
+ "exos",
+ UNSUPPORTED,
+ UNSUPPORTED,
+ UNSUPPORTED,
+ "super_explode",
+ UNSUPPORTED,
+ UNSUPPORTED,
+ "mach5",
+ UNSUPPORTED,
+ "pagefox",
+ UNSUPPORTED,
+ "silverrock"
+};
+
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+//-------------------------------------------------
+// cbm_crt_get_card - get slot interface card
+//-------------------------------------------------
+
+const char * cbm_crt_get_card(core_file *file)
+{
+ // read the header
+ cbm_crt_header header;
+ core_fread(file, &header, CRT_HEADER_LENGTH);
+
+ if (memcmp(header.signature, CRT_SIGNATURE, 16) == 0)
+ {
+ UINT16 hardware = pick_integer_be(header.hardware, 0, 2);
+
+ return CRT_C64_SLOT_NAMES[hardware];
+ }
+
+ return NULL;
+}
+
+
+//-------------------------------------------------
+// cbm_crt_read_header - read cartridge header
+//-------------------------------------------------
+
+bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game)
+{
+ // read the header
+ cbm_crt_header header;
+ core_fread(file, &header, CRT_HEADER_LENGTH);
+
+ if (memcmp(header.signature, CRT_SIGNATURE, 16) != 0)
+ return false;
+
+ UINT16 hardware = pick_integer_be(header.hardware, 0, 2);
+ *exrom = header.exrom;
+ *game = header.game;
+
+ if (LOG)
+ {
+ logerror("Name: %s\n", header.name);
+ logerror("Hardware: %04x\n", hardware);
+ logerror("Slot device: %s\n", CRT_C64_SLOT_NAMES[hardware]);
+ logerror("EXROM: %u\n", header.exrom);
+ logerror("GAME: %u\n", header.game);
+ }
+
+ // determine ROM region lengths
+ while (!core_feof(file))
+ {
+ cbm_crt_chip chip;
+ core_fread(file, &chip, CRT_CHIP_LENGTH);
+
+ UINT16 address = pick_integer_be(chip.start_address, 0, 2);
+ UINT16 size = pick_integer_be(chip.image_size, 0, 2);
+ UINT16 type = pick_integer_be(chip.chip_type, 0, 2);
+
+ if (LOG)
+ {
+ logerror("CHIP Address: %04x\n", address);
+ logerror("CHIP Size: %04x\n", size);
+ logerror("CHIP Type: %04x\n", type);
+ }
+
+ switch (address)
+ {
+ case 0x8000: *roml_size += size; break;
+ case 0xa000: *romh_size += size; break;
+ case 0xe000: *romh_size += size; break;
+ default: logerror("Invalid CHIP loading address!\n"); break;
+ }
+
+ core_fseek(file, size, SEEK_CUR);
+ }
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// cbm_crt_read_data - read cartridge data
+//-------------------------------------------------
+
+bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh)
+{
+ offs_t roml_offset = 0;
+ offs_t romh_offset = 0;
+
+ core_fseek(file, CRT_HEADER_LENGTH, SEEK_SET);
+
+ while (!core_feof(file))
+ {
+ cbm_crt_chip chip;
+ core_fread(file, &chip, CRT_CHIP_LENGTH);
+
+ UINT16 address = pick_integer_be(chip.start_address, 0, 2);
+ UINT16 size = pick_integer_be(chip.image_size, 0, 2);
+
+ switch (address)
+ {
+ case 0x8000: core_fread(file, roml + roml_offset, size); roml_offset += size; break;
+ case 0xa000: core_fread(file, romh + romh_offset, size); romh_offset += size; break;
+ case 0xe000: core_fread(file, romh + romh_offset, size); romh_offset += size; break;
+ }
+ }
+
+ return true;
+}
diff --git a/src/emu/bus/c64/exp.h b/src/emu/bus/c64/exp.h
index 551dab97fb7..265a7b725a5 100644
--- a/src/emu/bus/c64/exp.h
+++ b/src/emu/bus/c64/exp.h
@@ -40,7 +40,7 @@
#define __C64_EXPANSION_SLOT__
#include "emu.h"
-#include "machine/cbm_crt.h"
+#include "formats/cbm_crt.h"
diff --git a/src/emu/bus/cbm2/24k.c b/src/emu/bus/cbm2/24k.c
new file mode 100644
index 00000000000..7cb34a96c31
--- /dev/null
+++ b/src/emu/bus/cbm2/24k.c
@@ -0,0 +1,90 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ GLA 24K RAM cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "24k.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type CBM2_24K = &device_creator<cbm2_24k_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// cbm2_24k_cartridge_device - constructor
+//-------------------------------------------------
+
+cbm2_24k_cartridge_device::cbm2_24k_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, CBM2_24K, "24K RAM/ROM cartridge", tag, owner, clock, "cbm2_24k", __FILE__),
+ device_cbm2_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cbm2_24k_cartridge_device::device_start()
+{
+ cbm2_ram_pointer(machine(), 0x6000);
+}
+
+
+//-------------------------------------------------
+// cbm2_bd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 cbm2_24k_cartridge_device::cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (!csbank1)
+ {
+ data = m_ram[offset];
+ }
+ else if (!csbank2)
+ {
+ data = m_ram[0x2000 | offset];
+ }
+ else if (!csbank3)
+ {
+ data = m_ram[0x4000 | offset];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cbm2_bd_w - cartridge data write
+//-------------------------------------------------
+
+void cbm2_24k_cartridge_device::cbm2_bd_w(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (!csbank1)
+ {
+ m_ram[offset] = data;
+ }
+ else if (!csbank2)
+ {
+ m_ram[0x2000 | offset] = data;
+ }
+ else if (!csbank3)
+ {
+ m_ram[0x4000 | offset] = data;
+ }
+}
diff --git a/src/emu/bus/cbm2/24k.h b/src/emu/bus/cbm2/24k.h
new file mode 100644
index 00000000000..bff7e2b7398
--- /dev/null
+++ b/src/emu/bus/cbm2/24k.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ GLA 24K RAM cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __CBM2_24K_CARTRIDGE__
+#define __CBM2_24K_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> cbm2_24k_cartridge_device
+
+class cbm2_24k_cartridge_device : public device_t,
+ public device_cbm2_expansion_card_interface
+{
+public:
+ // construction/destruction
+ cbm2_24k_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_cbm2_expansion_card_interface overrides
+ virtual UINT8 cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+ virtual void cbm2_bd_w(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+};
+
+
+// device type definition
+extern const device_type CBM2_24K;
+
+
+#endif
diff --git a/src/emu/bus/cbm2/exp.c b/src/emu/bus/cbm2/exp.c
new file mode 100644
index 00000000000..315fa7cbe78
--- /dev/null
+++ b/src/emu/bus/cbm2/exp.c
@@ -0,0 +1,304 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore CBM-II Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type CBM2_EXPANSION_SLOT = &device_creator<cbm2_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE CBM2_EXPANSION CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_cbm2_expansion_card_interface - constructor
+//-------------------------------------------------
+
+device_cbm2_expansion_card_interface::device_cbm2_expansion_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_bank1(NULL),
+ m_bank2(NULL),
+ m_bank3(NULL),
+ m_ram(NULL),
+ m_nvram(NULL),
+ m_nvram_size(0),
+ m_bank1_mask(0),
+ m_bank2_mask(0),
+ m_bank3_mask(0),
+ m_ram_mask(0)
+{
+ m_slot = dynamic_cast<cbm2_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_cbm2_expansion_card_interface - destructor
+//-------------------------------------------------
+
+device_cbm2_expansion_card_interface::~device_cbm2_expansion_card_interface()
+{
+}
+
+
+//-------------------------------------------------
+// cbm2_bank1_pointer - get bank 1 pointer
+//-------------------------------------------------
+
+UINT8* device_cbm2_expansion_card_interface::cbm2_bank1_pointer(running_machine &machine, size_t size)
+{
+ if (m_bank1 == NULL)
+ {
+ m_bank1 = auto_alloc_array(machine, UINT8, size);
+
+ m_bank1_mask = size - 1;
+ }
+
+ return m_bank1;
+}
+
+
+//-------------------------------------------------
+// cbm2_bank2_pointer - get bank 2 pointer
+//-------------------------------------------------
+
+UINT8* device_cbm2_expansion_card_interface::cbm2_bank2_pointer(running_machine &machine, size_t size)
+{
+ if (m_bank2 == NULL)
+ {
+ m_bank2 = auto_alloc_array(machine, UINT8, size);
+
+ m_bank2_mask = size - 1;
+ }
+
+ return m_bank2;
+}
+
+
+//-------------------------------------------------
+// cbm2_bank3_pointer - get bank 3 pointer
+//-------------------------------------------------
+
+UINT8* device_cbm2_expansion_card_interface::cbm2_bank3_pointer(running_machine &machine, size_t size)
+{
+ if (m_bank3 == NULL)
+ {
+ m_bank3 = auto_alloc_array(machine, UINT8, size);
+
+ m_bank3_mask = size - 1;
+ }
+
+ return m_bank3;
+}
+
+
+//-------------------------------------------------
+// cbm2_ram_pointer - get RAM pointer
+//-------------------------------------------------
+
+UINT8* device_cbm2_expansion_card_interface::cbm2_ram_pointer(running_machine &machine, size_t size)
+{
+ if (m_ram == NULL)
+ {
+ m_ram = auto_alloc_array(machine, UINT8, size);
+
+ m_ram_mask = size - 1;
+ }
+
+ return m_ram;
+}
+
+
+//-------------------------------------------------
+// cbm2_ram_pointer - get NVRAM pointer
+//-------------------------------------------------
+
+UINT8* device_cbm2_expansion_card_interface::cbm2_nvram_pointer(running_machine &machine, size_t size)
+{
+ if (m_nvram == NULL)
+ {
+ m_nvram = auto_alloc_array(machine, UINT8, size);
+
+ m_nvram_mask = size - 1;
+ m_nvram_size = size;
+ }
+
+ return m_nvram;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// cbm2_expansion_slot_device - constructor
+//-------------------------------------------------
+
+cbm2_expansion_slot_device::cbm2_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, CBM2_EXPANSION_SLOT, "CBM-II expansion port", tag, owner, clock, "cbm2_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ device_image_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cbm2_expansion_slot_device::device_start()
+{
+ m_card = dynamic_cast<device_cbm2_expansion_card_interface *>(get_card_device());
+
+ // inherit bus clock
+ if (clock() == 0)
+ {
+ cbm2_expansion_slot_device *root = machine().device<cbm2_expansion_slot_device>(CBM2_EXPANSION_SLOT_TAG);
+ assert(root);
+ set_unscaled_clock(root->clock());
+ }
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void cbm2_expansion_slot_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// call_load -
+//-------------------------------------------------
+
+bool cbm2_expansion_slot_device::call_load()
+{
+ size_t size = 0;
+
+ if (m_card)
+ {
+ if (software_entry() == NULL)
+ {
+ size = length();
+
+ if (!mame_stricmp(filetype(), "20"))
+ {
+ fread(m_card->cbm2_bank1_pointer(machine(), size), size);
+ }
+ else if (!mame_stricmp(filetype(), "40"))
+ {
+ fread(m_card->cbm2_bank2_pointer(machine(), size), size);
+ }
+ else if (!mame_stricmp(filetype(), "60"))
+ {
+ fread(m_card->cbm2_bank3_pointer(machine(), size), size);
+ }
+ }
+ else
+ {
+ size = get_software_region_length("bank1");
+ if (size) memcpy(m_card->cbm2_bank1_pointer(machine(), size), get_software_region("bank1"), size);
+
+ size = get_software_region_length("bank2");
+ if (size) memcpy(m_card->cbm2_bank2_pointer(machine(), size), get_software_region("bank2"), size);
+
+ size = get_software_region_length("bank3");
+ if (size) memcpy(m_card->cbm2_bank3_pointer(machine(), size), get_software_region("bank3"), size);
+
+ size = get_software_region_length("ram");
+ if (size) memset(m_card->cbm2_ram_pointer(machine(), size), 0, size);
+
+ size = get_software_region_length("nvram");
+ if (size) memset(m_card->cbm2_nvram_pointer(machine(), size), 0, size);
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+//-------------------------------------------------
+// call_softlist_load -
+//-------------------------------------------------
+
+bool cbm2_expansion_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
+{
+ load_software_part_region(this, swlist, swname, start_entry);
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// get_default_card_software -
+//-------------------------------------------------
+
+const char * cbm2_expansion_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
+{
+ return software_get_default_slot(config, options, this, "standard");
+}
+
+
+//-------------------------------------------------
+// read - cartridge data read
+//-------------------------------------------------
+
+UINT8 cbm2_expansion_slot_device::read(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (m_card != NULL)
+ {
+ data = m_card->cbm2_bd_r(space, offset, data, csbank1, csbank2, csbank3);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write - cartridge data write
+//-------------------------------------------------
+
+void cbm2_expansion_slot_device::write(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (m_card != NULL)
+ {
+ m_card->cbm2_bd_w(space, offset, data, csbank1, csbank2, csbank3);
+ }
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( cbm2_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( cbm2_expansion_cards )
+ SLOT_INTERFACE("24k", CBM2_24K)
+ SLOT_INTERFACE_INTERNAL("standard", CBM2_STD)
+ SLOT_INTERFACE_INTERNAL("graphic", CBM2_GRAPHIC)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/cbm2/exp.h b/src/emu/bus/cbm2/exp.h
new file mode 100644
index 00000000000..be541a0df4b
--- /dev/null
+++ b/src/emu/bus/cbm2/exp.h
@@ -0,0 +1,162 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore CBM-II Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ A0 1 A BD0
+ A1 2 B BD1
+ A2 3 C BD2
+ A3 4 D BD3
+ A4 5 E BD4
+ A5 6 F BD5
+ A6 7 H BD6
+ A7 8 J BD7
+ A8 9 K GND
+ A9 10 L GND
+ A10 11 M SR/_W
+ A11 12 N Sphi2
+ A12 13 P _CSBANK1
+ +5V 14 R _CSBANK2
+ +5V 15 S _CSBANK2
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __CBM2_EXPANSION_SLOT__
+#define __CBM2_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define CBM2_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_CBM2_EXPANSION_SLOT_ADD(_tag, _clock, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, CBM2_EXPANSION_SLOT, _clock) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> cbm2_expansion_slot_device
+
+class device_cbm2_expansion_card_interface;
+
+class cbm2_expansion_slot_device : public device_t,
+ public device_slot_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ cbm2_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // computer interface
+ UINT8 read(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+ void write(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+
+ // cartridge interface
+ int phi2() { return clock(); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete() { update_names(); }
+ virtual void device_start();
+ virtual void device_reset();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
+
+ 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 char *image_interface() const { return "cbm2_cart"; }
+ virtual const char *file_extensions() const { return "20,40,60"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // slot interface overrides
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
+
+ device_cbm2_expansion_card_interface *m_card;
+};
+
+
+// ======================> device_cbm2_expansion_card_interface
+
+class device_cbm2_expansion_card_interface : public device_slot_card_interface
+{
+ friend class cbm2_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_cbm2_expansion_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_cbm2_expansion_card_interface();
+
+protected:
+ // initialization
+ virtual UINT8* cbm2_bank1_pointer(running_machine &machine, size_t size);
+ virtual UINT8* cbm2_bank2_pointer(running_machine &machine, size_t size);
+ virtual UINT8* cbm2_bank3_pointer(running_machine &machine, size_t size);
+ virtual UINT8* cbm2_ram_pointer(running_machine &machine, size_t size);
+ virtual UINT8* cbm2_nvram_pointer(running_machine &machine, size_t size);
+
+ // runtime
+ virtual UINT8 cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3) { return data; };
+ virtual void cbm2_bd_w(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3) { };
+
+ cbm2_expansion_slot_device *m_slot;
+
+ UINT8 *m_bank1;
+ UINT8 *m_bank2;
+ UINT8 *m_bank3;
+ UINT8 *m_ram;
+ UINT8 *m_nvram;
+
+ size_t m_nvram_size;
+
+ size_t m_bank1_mask;
+ size_t m_bank2_mask;
+ size_t m_bank3_mask;
+ size_t m_ram_mask;
+ size_t m_nvram_mask;
+};
+
+
+// device type definition
+extern const device_type CBM2_EXPANSION_SLOT;
+
+
+// slot devices
+#include "24k.h"
+#include "hrg.h"
+#include "std.h"
+
+SLOT_INTERFACE_EXTERN( cbm2_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/cbm2/hrg.c b/src/emu/bus/cbm2/hrg.c
new file mode 100644
index 00000000000..d320262462d
--- /dev/null
+++ b/src/emu/bus/cbm2/hrg.c
@@ -0,0 +1,209 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ CBM 500/600/700 High Resolution Graphics cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - version A (EF9365, 512x512 interlaced, 1 page)
+ - version B (EF9366, 512x256 non-interlaced, 2 pages)
+
+*/
+
+#include "hrg.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define EF9365_TAG "ef9365"
+#define EF9366_TAG "ef9366"
+#define SCREEN_TAG "screen"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type CBM2_GRAPHIC = &device_creator<cbm2_graphic_cartridge_device>;
+
+
+//-------------------------------------------------
+// ef9365_interface gdp_intf
+//-------------------------------------------------
+/*
+static const ef9365_interface gdp_intf =
+{
+ SCREEN_TAG
+};
+*/
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( cbm2_graphic_a )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( cbm2_graphic_a )
+/* MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
+ MCFG_SCREEN_UPDATE_DEVICE(EF9365_TAG, ef9365_device, screen_update)
+ MCFG_SCREEN_SIZE(512, 512)
+ MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 512-1)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
+ MCFG_SCREEN_REFRESH_RATE(50)
+
+ MCFG_EF9365_ADD(EF9365_TAG, gdp_intf)*/
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( cbm2_graphic_b )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( cbm2_graphic_b )
+/* MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
+ MCFG_SCREEN_UPDATE_DEVICE(EF9366_TAG, ef9366_device, screen_update)
+ MCFG_SCREEN_SIZE(512, 256)
+ MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
+ MCFG_SCREEN_REFRESH_RATE(50)
+
+ MCFG_EF9366_ADD(EF9366_TAG, gdp_intf)*/
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor cbm2_graphic_cartridge_device::device_mconfig_additions() const
+{
+ switch (m_variant)
+ {
+ default: return MACHINE_CONFIG_NAME( cbm2_graphic_a );
+ case TYPE_B: return MACHINE_CONFIG_NAME( cbm2_graphic_b );
+ }
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// cbm2_graphic_cartridge_device - constructor
+//-------------------------------------------------
+
+cbm2_graphic_cartridge_device::cbm2_graphic_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, CBM2_GRAPHIC, "CBM 500/600/700 High Resolution Graphics", tag, owner, clock, "cbm2_graphic", __FILE__),
+ device_cbm2_expansion_card_interface(mconfig, *this),
+ //m_gdc(*this, EF9365_TAG),
+ m_variant(TYPE_A)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cbm2_graphic_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void cbm2_graphic_cartridge_device::device_reset()
+{
+ //m_gdc->reset();
+}
+
+
+//-------------------------------------------------
+// cbm2_bd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 cbm2_graphic_cartridge_device::cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (!csbank3)
+ {
+ if (offset < 0x7f80)
+ {
+ data = m_bank3[offset];
+ }
+ else if (offset == 0x7f90)
+ {
+ /*
+
+ bit description
+
+ 0 light pen
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+
+ */
+ }
+ else if (offset == 0x7fb0)
+ {
+ // hard copy
+ }
+ else if (offset >= 0x7ff0)
+ {
+ //data = m_gdc->data_r(space, offset & 0x07);
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cbm2_bd_w - cartridge data write
+//-------------------------------------------------
+
+void cbm2_graphic_cartridge_device::cbm2_bd_w(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (!csbank3)
+ {
+ if (offset == 0x7f80)
+ {
+ /*
+
+ bit description
+
+ 0 hard copy (0=active)
+ 1 operating page select (version B)
+ 2
+ 3 read-modify-write (1=active)
+ 4 display switch (1=graphic)
+ 5 display page select (version B)
+ 6
+ 7
+
+ */
+ }
+ else if (offset >= 0x7ff0)
+ {
+ //m_gdc->data_w(space, offset & 0x07, data);
+ }
+ }
+}
diff --git a/src/emu/bus/cbm2/hrg.h b/src/emu/bus/cbm2/hrg.h
new file mode 100644
index 00000000000..f77528e95a6
--- /dev/null
+++ b/src/emu/bus/cbm2/hrg.h
@@ -0,0 +1,65 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ CBM 500/600/700 High Resolution Graphics cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __CBM2_GRAPHIC__
+#define __CBM2_GRAPHIC__
+
+#include "emu.h"
+#include "exp.h"
+#include "video/ef9345.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> cbm2_graphic_cartridge_device
+
+class cbm2_graphic_cartridge_device : public device_t,
+ public device_cbm2_expansion_card_interface
+{
+public:
+ // construction/destruction
+ cbm2_graphic_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ enum
+ {
+ TYPE_A,
+ TYPE_B
+ };
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_cbm2_expansion_card_interface overrides
+ virtual UINT8 cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+ virtual void cbm2_bd_w(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+
+private:
+ //required_device<ef9345_device> m_gdc;
+
+ int m_variant;
+};
+
+
+// device type definition
+extern const device_type CBM2_GRAPHIC;
+
+
+#endif
diff --git a/src/emu/bus/cbm2/std.c b/src/emu/bus/cbm2/std.c
new file mode 100644
index 00000000000..a872201b968
--- /dev/null
+++ b/src/emu/bus/cbm2/std.c
@@ -0,0 +1,68 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore CBM-II Standard cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "std.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type CBM2_STD = &device_creator<cbm2_standard_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// cbm2_standard_cartridge_device - constructor
+//-------------------------------------------------
+
+cbm2_standard_cartridge_device::cbm2_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, CBM2_STD, "CBM-II standard cartridge", tag, owner, clock, "cbm2_standard", __FILE__),
+ device_cbm2_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cbm2_standard_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// cbm2_bd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 cbm2_standard_cartridge_device::cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3)
+{
+ if (!csbank1 && m_bank1_mask)
+ {
+ data = m_bank1[offset & m_bank1_mask];
+ }
+ else if (!csbank2 && m_bank2_mask)
+ {
+ data = m_bank2[offset & m_bank2_mask];
+ }
+ else if (!csbank3 && m_bank3_mask)
+ {
+ data = m_bank3[offset & m_bank3_mask];
+ }
+
+ return data;
+}
diff --git a/src/emu/bus/cbm2/std.h b/src/emu/bus/cbm2/std.h
new file mode 100644
index 00000000000..45534b54530
--- /dev/null
+++ b/src/emu/bus/cbm2/std.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore CBM-II Standard cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __CBM2_STANDARD_CARTRIDGE__
+#define __CBM2_STANDARD_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+#include "imagedev/cartslot.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> cbm2_standard_cartridge_device
+
+class cbm2_standard_cartridge_device : public device_t,
+ public device_cbm2_expansion_card_interface
+{
+public:
+ // construction/destruction
+ cbm2_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_cbm2_expansion_card_interface overrides
+ virtual UINT8 cbm2_bd_r(address_space &space, offs_t offset, UINT8 data, int csbank1, int csbank2, int csbank3);
+};
+
+
+// device type definition
+extern const device_type CBM2_STD;
+
+
+#endif
diff --git a/src/emu/bus/cbm2/user.c b/src/emu/bus/cbm2/user.c
new file mode 100644
index 00000000000..cf428f39edf
--- /dev/null
+++ b/src/emu/bus/cbm2/user.c
@@ -0,0 +1,133 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore CBM-II User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "user.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type CBM2_USER_PORT = &device_creator<cbm2_user_port_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_cbm2_user_port_interface - constructor
+//-------------------------------------------------
+
+device_cbm2_user_port_interface::device_cbm2_user_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_slot = dynamic_cast<cbm2_user_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_cbm2_user_port_interface - destructor
+//-------------------------------------------------
+
+device_cbm2_user_port_interface::~device_cbm2_user_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// cbm2_user_port_device - constructor
+//-------------------------------------------------
+
+cbm2_user_port_device::cbm2_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, CBM2_USER_PORT, "CBM2 user port", tag, owner, clock, "cbm2_user_port", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// cbm2_user_port_device - destructor
+//-------------------------------------------------
+
+cbm2_user_port_device::~cbm2_user_port_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void cbm2_user_port_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const cbm2_user_port_interface *intf = reinterpret_cast<const cbm2_user_port_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<cbm2_user_port_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb));
+ memset(&m_out_sp_cb, 0, sizeof(m_out_sp_cb));
+ memset(&m_out_cnt_cb, 0, sizeof(m_out_cnt_cb));
+ memset(&m_out_flag_cb, 0, sizeof(m_out_flag_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void cbm2_user_port_device::device_start()
+{
+ m_card = dynamic_cast<device_cbm2_user_port_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_out_irq_func.resolve(m_out_irq_cb, *this);
+ m_out_sp_func.resolve(m_out_sp_cb, *this);
+ m_out_cnt_func.resolve(m_out_cnt_cb, *this);
+ m_out_flag_func.resolve(m_out_flag_cb, *this);
+}
+
+
+READ8_MEMBER( cbm2_user_port_device::d1_r ) { UINT8 data = 0xff; if (m_card != NULL) data = m_card->cbm2_d1_r(space, offset); return data; }
+WRITE8_MEMBER( cbm2_user_port_device::d1_w ) { if (m_card != NULL) m_card->cbm2_d1_w(space, offset, data); }
+READ8_MEMBER( cbm2_user_port_device::d2_r ) { UINT8 data = 0xff; if (m_card != NULL) data = m_card->cbm2_d2_r(space, offset); return data; }
+WRITE8_MEMBER( cbm2_user_port_device::d2_w ) { if (m_card != NULL) m_card->cbm2_d2_w(space, offset, data); }
+READ_LINE_MEMBER( cbm2_user_port_device::pb2_r ) { return m_card ? m_card->cbm2_pb2_r() : 1; }
+WRITE_LINE_MEMBER( cbm2_user_port_device::pb2_w ) { if (m_card != NULL) m_card->cbm2_pb2_w(state); }
+READ_LINE_MEMBER( cbm2_user_port_device::pb3_r ) { return m_card ? m_card->cbm2_pb3_r() : 1; }
+WRITE_LINE_MEMBER( cbm2_user_port_device::pb3_w ) { if (m_card != NULL) m_card->cbm2_pb3_w(state); }
+WRITE_LINE_MEMBER( cbm2_user_port_device::pc_w ) { if (m_card != NULL) m_card->cbm2_pc_w(state); }
+WRITE_LINE_MEMBER( cbm2_user_port_device::cnt_w ) { if (m_card != NULL) m_card->cbm2_cnt_w(state); }
+WRITE_LINE_MEMBER( cbm2_user_port_device::sp_w ) { if (m_card != NULL) m_card->cbm2_sp_w(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( cbm2_user_port_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( cbm2_user_port_cards )
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/cbm2/user.h b/src/emu/bus/cbm2/user.h
new file mode 100644
index 00000000000..eda44e21a88
--- /dev/null
+++ b/src/emu/bus/cbm2/user.h
@@ -0,0 +1,146 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore CBM-II User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __CBM2_USER_PORT__
+#define __CBM2_USER_PORT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define CBM2_USER_PORT_TAG "user"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define CBM2_USER_PORT_INTERFACE(_name) \
+ const cbm2_user_port_interface (_name) =
+
+
+#define MCFG_CBM2_USER_PORT_ADD(_tag, _config, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, CBM2_USER_PORT, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> cbm2_user_port_interface
+
+struct cbm2_user_port_interface
+{
+ devcb_write_line m_out_irq_cb;
+ devcb_write_line m_out_sp_cb;
+ devcb_write_line m_out_cnt_cb;
+ devcb_write_line m_out_flag_cb;
+};
+
+
+// ======================> cbm2_user_port_device
+
+class device_cbm2_user_port_interface;
+
+class cbm2_user_port_device : public device_t,
+ public cbm2_user_port_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ cbm2_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~cbm2_user_port_device();
+
+ // computer interface
+ DECLARE_READ8_MEMBER( d1_r );
+ DECLARE_WRITE8_MEMBER( d1_w );
+ DECLARE_READ8_MEMBER( d2_r );
+ DECLARE_WRITE8_MEMBER( d2_w );
+ DECLARE_READ_LINE_MEMBER( pb2_r );
+ DECLARE_WRITE_LINE_MEMBER( pb2_w );
+ DECLARE_READ_LINE_MEMBER( pb3_r );
+ DECLARE_WRITE_LINE_MEMBER( pb3_w );
+ DECLARE_WRITE_LINE_MEMBER( pc_w );
+ DECLARE_WRITE_LINE_MEMBER( cnt_w );
+ DECLARE_WRITE_LINE_MEMBER( sp_w );
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_out_irq_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( cia_sp_w ) { m_out_sp_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( cia_cnt_w ) { m_out_cnt_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( flag_w ) { m_out_flag_func(state); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+
+ devcb_resolved_write_line m_out_irq_func;
+ devcb_resolved_write_line m_out_sp_func;
+ devcb_resolved_write_line m_out_cnt_func;
+ devcb_resolved_write_line m_out_flag_func;
+
+ device_cbm2_user_port_interface *m_card;
+};
+
+
+// ======================> device_cbm2_user_port_interface
+
+// class representing interface-specific live cbm2_expansion card
+class device_cbm2_user_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_cbm2_user_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_cbm2_user_port_interface();
+
+ virtual UINT8 cbm2_d1_r(address_space &space, offs_t offset) { return 0xff; };
+ virtual void cbm2_d1_w(address_space &space, offs_t offset, UINT8 data) { };
+
+ virtual UINT8 cbm2_d2_r(address_space &space, offs_t offset) { return 0xff; };
+ virtual void cbm2_d2_w(address_space &space, offs_t offset, UINT8 data) { };
+
+ virtual int cbm2_pb2_r() { return 1; }
+ virtual void cbm2_pb2_w(int state) { };
+ virtual int cbm2_pb3_r() { return 1; }
+ virtual void cbm2_pb3_w(int state) { };
+
+ virtual void cbm2_pc_w(int state) { };
+ virtual void cbm2_cnt_w(int state) { };
+ virtual void cbm2_sp_w(int state) { };
+
+protected:
+ cbm2_user_port_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type CBM2_USER_PORT;
+
+
+// slot devices
+SLOT_INTERFACE_EXTERN( cbm2_user_port_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/ecbbus/ecbbus.c b/src/emu/bus/ecbbus/ecbbus.c
new file mode 100644
index 00000000000..efe3beb3153
--- /dev/null
+++ b/src/emu/bus/ecbbus/ecbbus.c
@@ -0,0 +1,280 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Conitec Datensysteme ECB Bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "ecbbus.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type ECBBUS_SLOT = &device_creator<ecbbus_slot_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// ecbbus_slot_device - constructor
+//-------------------------------------------------
+
+ecbbus_slot_device::ecbbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECBBUS_SLOT, "ECB bus slot", tag, owner, clock, "ecbbus_slot", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// static_set_ecbbus_slot -
+//-------------------------------------------------
+
+void ecbbus_slot_device::static_set_ecbbus_slot(device_t &device, const char *tag, int num)
+{
+ ecbbus_slot_device &ecbbus_card = dynamic_cast<ecbbus_slot_device &>(device);
+ ecbbus_card.m_bus_tag = tag;
+ ecbbus_card.m_bus_num = num;
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void ecbbus_slot_device::device_start()
+{
+ m_bus = machine().device<ecbbus_device>(m_bus_tag);
+ device_ecbbus_card_interface *dev = dynamic_cast<device_ecbbus_card_interface *>(get_card_device());
+ if (dev) m_bus->add_ecbbus_card(dev, m_bus_num);
+}
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type ECBBUS = &device_creator<ecbbus_device>;
+
+
+void ecbbus_device::static_set_cputag(device_t &device, const char *tag)
+{
+ ecbbus_device &ecbbus = downcast<ecbbus_device &>(device);
+ ecbbus.m_cputag = tag;
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void ecbbus_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const ecbbus_interface *intf = reinterpret_cast<const ecbbus_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<ecbbus_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_int_cb, 0, sizeof(m_out_int_cb));
+ memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb));
+ }
+}
+
+
+
+//**************************************************************************
+// DEVICE ECBBUS CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_ecbbus_card_interface - constructor
+//-------------------------------------------------
+
+device_ecbbus_card_interface::device_ecbbus_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+ m_slot = dynamic_cast<ecbbus_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_ecbbus_card_interface - destructor
+//-------------------------------------------------
+
+device_ecbbus_card_interface::~device_ecbbus_card_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// ecbbus_device - constructor
+//-------------------------------------------------
+
+ecbbus_device::ecbbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECBBUS, "ECB bus", tag, owner, clock, "ecbbus", __FILE__)
+{
+ for (int i = 0; i < MAX_ECBBUS_SLOTS; i++)
+ m_ecbbus_device[i] = NULL;
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void ecbbus_device::device_start()
+{
+ m_maincpu = machine().device<cpu_device>(m_cputag);
+
+ // resolve callbacks
+ m_out_int_func.resolve(m_out_int_cb, *this);
+ m_out_nmi_func.resolve(m_out_nmi_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void ecbbus_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// add_ecbbus_card - add ECB bus card
+//-------------------------------------------------
+
+void ecbbus_device::add_ecbbus_card(device_ecbbus_card_interface *card, int pos)
+{
+ m_ecbbus_device[pos] = card;
+}
+
+
+//-------------------------------------------------
+// mem_r -
+//-------------------------------------------------
+
+READ8_MEMBER( ecbbus_device::mem_r )
+{
+ UINT8 data = 0;
+
+ for (int i = 0; i < MAX_ECBBUS_SLOTS; i++)
+ {
+ if (m_ecbbus_device[i] != NULL)
+ {
+ data |= m_ecbbus_device[i]->ecbbus_mem_r(offset);
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// mem_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( ecbbus_device::mem_w )
+{
+ for (int i = 0; i < MAX_ECBBUS_SLOTS; i++)
+ {
+ if (m_ecbbus_device[i] != NULL)
+ {
+ m_ecbbus_device[i]->ecbbus_mem_w(offset, data);
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// io_r -
+//-------------------------------------------------
+
+READ8_MEMBER( ecbbus_device::io_r )
+{
+ UINT8 data = 0;
+
+ for (int i = 0; i < MAX_ECBBUS_SLOTS; i++)
+ {
+ if (m_ecbbus_device[i] != NULL)
+ {
+ data |= m_ecbbus_device[i]->ecbbus_io_r(offset);
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// io_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( ecbbus_device::io_w )
+{
+ for (int i = 0; i < MAX_ECBBUS_SLOTS; i++)
+ {
+ if (m_ecbbus_device[i] != NULL)
+ {
+ m_ecbbus_device[i]->ecbbus_io_w(offset, data);
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// int_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( ecbbus_device::int_w )
+{
+ m_out_int_func(state);
+}
+
+
+//-------------------------------------------------
+// nmi_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( ecbbus_device::nmi_w )
+{
+ m_out_nmi_func(state);
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( ecbbus_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( ecbbus_cards )
+ SLOT_INTERFACE("grip21", ECB_GRIP21)
+/* SLOT_INTERFACE("grip25", ECB_GRIP25)
+ SLOT_INTERFACE("grip26", ECB_GRIP26)
+ SLOT_INTERFACE("grip31", ECB_GRIP31)
+ SLOT_INTERFACE("grip562", ECB_GRIP562)
+ SLOT_INTERFACE("grips115", ECB_GRIPS115)*/
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/ecbbus/ecbbus.h b/src/emu/bus/ecbbus/ecbbus.h
new file mode 100644
index 00000000000..7be19a40b91
--- /dev/null
+++ b/src/emu/bus/ecbbus/ecbbus.h
@@ -0,0 +1,170 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Conitec Datensysteme ECB Bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ECBBUS__
+#define __ECBBUS__
+
+#include "emu.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define ECBBUS_TAG "ecbbus"
+
+
+#define MAX_ECBBUS_SLOTS 16
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_ECBBUS_ADD(_cpu_tag, _config) \
+ MCFG_DEVICE_ADD(ECBBUS_TAG, ECBBUS, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ ecbbus_device::static_set_cputag(*device, _cpu_tag);
+
+
+#define ECBBUS_INTERFACE(_name) \
+ const ecbbus_interface (_name) =
+
+
+#define MCFG_ECBBUS_SLOT_ADD(_num, _tag, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, ECBBUS_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+ ecbbus_slot_device::static_set_ecbbus_slot(*device, ECBBUS_TAG, _num);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> ecbbus_slot_device
+
+class ecbbus_device;
+
+class ecbbus_slot_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ ecbbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+
+ // inline configuration
+ static void static_set_ecbbus_slot(device_t &device, const char *tag, int num);
+
+private:
+ // configuration
+ const char *m_bus_tag;
+ int m_bus_num;
+ ecbbus_device *m_bus;
+};
+
+
+// device type definition
+extern const device_type ECBBUS_SLOT;
+
+
+// ======================> ecbbus_interface
+
+struct ecbbus_interface
+{
+ devcb_write_line m_out_int_cb;
+ devcb_write_line m_out_nmi_cb;
+};
+
+class device_ecbbus_card_interface;
+
+
+// ======================> ecbbus_device
+
+class ecbbus_device : public device_t,
+ public ecbbus_interface
+{
+public:
+ // construction/destruction
+ ecbbus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ // inline configuration
+ static void static_set_cputag(device_t &device, const char *tag);
+
+ void add_ecbbus_card(device_ecbbus_card_interface *card, int pos);
+
+ DECLARE_READ8_MEMBER( mem_r );
+ DECLARE_WRITE8_MEMBER( mem_w );
+
+ DECLARE_READ8_MEMBER( io_r );
+ DECLARE_WRITE8_MEMBER( io_w );
+
+ DECLARE_WRITE_LINE_MEMBER( int_w );
+ DECLARE_WRITE_LINE_MEMBER( nmi_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_config_complete();
+
+private:
+ // internal state
+ cpu_device *m_maincpu;
+
+ devcb_resolved_write_line m_out_int_func;
+ devcb_resolved_write_line m_out_nmi_func;
+
+ device_ecbbus_card_interface *m_ecbbus_device[MAX_ECBBUS_SLOTS];
+ const char *m_cputag;
+};
+
+
+// device type definition
+extern const device_type ECBBUS;
+
+
+// ======================> device_ecbbus_card_interface
+
+// class representing interface-specific live ecbbus card
+class device_ecbbus_card_interface : public device_slot_card_interface
+{
+ friend class ecbbus_device;
+
+public:
+ // construction/destruction
+ device_ecbbus_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_ecbbus_card_interface();
+
+ // optional operation overrides
+ virtual UINT8 ecbbus_mem_r(offs_t offset) { return 0; };
+ virtual void ecbbus_mem_w(offs_t offset, UINT8 data) { };
+ virtual UINT8 ecbbus_io_r(offs_t offset) { return 0; };
+ virtual void ecbbus_io_w(offs_t offset, UINT8 data) { };
+
+public:
+ ecbbus_slot_device *m_slot;
+};
+
+
+// slot devices
+#include "grip.h"
+
+SLOT_INTERFACE_EXTERN( ecbbus_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/ecbbus/grip.c b/src/emu/bus/ecbbus/grip.c
new file mode 100644
index 00000000000..1eddb6dede0
--- /dev/null
+++ b/src/emu/bus/ecbbus/grip.c
@@ -0,0 +1,947 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Conitec Datensysteme GRIP graphics card emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "grip.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define SCREEN_TAG "screen"
+#define Z80_TAG "grip_z1"
+#define MC6845_TAG "z30"
+#define HD6345_TAG "z30"
+#define I8255A_TAG "z6"
+#define Z80STI_TAG "z9"
+#define CENTRONICS_TAG "centronics"
+
+
+#define VIDEORAM_SIZE 0x10000
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type ECB_GRIP21 = &device_creator<grip_device>;
+
+
+
+//**************************************************************************
+// ROMS
+//**************************************************************************
+
+//-------------------------------------------------
+// ROM( grip21 )
+//-------------------------------------------------
+
+ROM_START( grip21 )
+ ROM_REGION( 0x4000, Z80_TAG, 0 )
+ ROM_LOAD( "grip21.z2", 0x0000, 0x4000, CRC(7f6a37dd) SHA1(2e89f0b0c378257ff7e41c50d57d90865c6e214b) )
+ROM_END
+
+
+//-------------------------------------------------
+// ROM( grip25 )
+//-------------------------------------------------
+
+ROM_START( grip25 )
+ ROM_REGION( 0x4000, Z80_TAG, 0 )
+ ROM_LOAD( "grip25.z2", 0x0000, 0x4000, CRC(49ebb284) SHA1(0a7eaaf89da6db2750f820146c8f480b7157c6c7) )
+ROM_END
+
+
+//-------------------------------------------------
+// ROM( grip26 )
+//-------------------------------------------------
+
+ROM_START( grip26 )
+ ROM_REGION( 0x4000, Z80_TAG, 0 )
+ ROM_LOAD( "grip26.z2", 0x0000, 0x4000, CRC(a1c424f0) SHA1(83942bc75b9475f044f936b8d9d7540551d87db9) )
+ROM_END
+
+
+//-------------------------------------------------
+// ROM( grip31 )
+//-------------------------------------------------
+
+ROM_START( grip31 )
+ ROM_REGION( 0x4000, Z80_TAG, 0 )
+ ROM_LOAD( "grip31.z2", 0x0000, 0x4000, CRC(e0e4e8ab) SHA1(73d3d14c9b06fed0c187fb0fffe5ec035d8dd256) )
+ROM_END
+
+
+//-------------------------------------------------
+// ROM( grip562 )
+//-------------------------------------------------
+
+ROM_START( grip562 )
+ ROM_REGION( 0x8000, Z80_TAG, 0 )
+ ROM_LOAD( "grip562.z2", 0x0000, 0x8000, CRC(74be0455) SHA1(1c423ecca6363345a8690ddc45dbafdf277490d3) )
+ROM_END
+
+
+//-------------------------------------------------
+// ROM( grips115 )
+//-------------------------------------------------
+
+ROM_START( grips115 )
+ ROM_REGION( 0x4000, Z80_TAG, 0 )
+ ROM_LOAD( "grips115.z2", 0x0000, 0x4000, CRC(505706ef) SHA1(05fb032fb1a504c534c30c352ba4bd47623503d0) )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *grip_device::device_rom_region() const
+{
+ return ROM_NAME( grip21 );
+}
+
+
+
+//**************************************************************************
+// ADDRESS MAPS
+//**************************************************************************
+
+//-------------------------------------------------
+// ADDRESS_MAP( grip_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( grip_mem, AS_PROGRAM, 8, grip_device )
+ AM_RANGE(0x0000, 0x3fff) AM_ROM
+ AM_RANGE(0x4000, 0x47ff) AM_RAM
+ AM_RANGE(0x8000, 0xffff) AM_RAMBANK("videoram")
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( grip_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( grip_io, AS_IO, 8, grip_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x00) AM_READWRITE(cxstb_r, cxstb_w)
+// AM_RANGE(0x10, 0x10) AM_WRITE(ccon_w)
+ AM_RANGE(0x11, 0x11) AM_WRITE(vol0_w)
+// AM_RANGE(0x12, 0x12) AM_WRITE(rts_w)
+ AM_RANGE(0x13, 0x13) AM_WRITE(page_w)
+// AM_RANGE(0x14, 0x14) AM_WRITE(cc1_w)
+// AM_RANGE(0x15, 0x15) AM_WRITE(cc2_w)
+ AM_RANGE(0x16, 0x16) AM_WRITE(flash_w)
+ AM_RANGE(0x17, 0x17) AM_WRITE(vol1_w)
+ AM_RANGE(0x20, 0x2f) AM_DEVREADWRITE(Z80STI_TAG, z80sti_device, read, write)
+ AM_RANGE(0x30, 0x30) AM_READWRITE(lrs_r, lrs_w)
+ AM_RANGE(0x40, 0x40) AM_READ(stat_r)
+ AM_RANGE(0x50, 0x50) AM_DEVWRITE(MC6845_TAG, mc6845_device, address_w)
+ AM_RANGE(0x52, 0x52) AM_DEVWRITE(MC6845_TAG, mc6845_device, register_w)
+ AM_RANGE(0x53, 0x53) AM_DEVREAD(MC6845_TAG, mc6845_device, register_r)
+ AM_RANGE(0x60, 0x60) AM_DEVWRITE(CENTRONICS_TAG, centronics_device, write)
+ AM_RANGE(0x70, 0x73) AM_DEVREADWRITE(I8255A_TAG, i8255_device, read, write)
+// AM_RANGE(0x80, 0x80) AM_WRITE(bl2out_w)
+// AM_RANGE(0x90, 0x90) AM_WRITE(gr2out_w)
+// AM_RANGE(0xa0, 0xa0) AM_WRITE(rd2out_w)
+// AM_RANGE(0xb0, 0xb0) AM_WRITE(clrg2_w)
+// AM_RANGE(0xc0, 0xc0) AM_WRITE(bluout_w)
+// AM_RANGE(0xd0, 0xd0) AM_WRITE(grnout_w)
+// AM_RANGE(0xe0, 0xe0) AM_WRITE(redout_w)
+// AM_RANGE(0xf0, 0xf0) AM_WRITE(clrg1_w)
+ADDRESS_MAP_END
+
+/*
+//-------------------------------------------------
+// ADDRESS_MAP( grip5_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( grip5_mem, AS_PROGRAM, 8, grip5_state )
+ AM_RANGE(0x0000, 0x3fff) AM_ROMBANK("eprom")
+ AM_RANGE(0x4000, 0x5fff) AM_RAM
+ AM_RANGE(0x8000, 0xffff) AM_RAMBANK("videoram")
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( grip5_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( grip5_io, AS_IO, 8, grip5_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x00) AM_READWRITE(cxstb_r, cxstb_w)
+ AM_RANGE(0x10, 0x10) AM_WRITE(eprom_w)
+ AM_RANGE(0x11, 0x11) AM_WRITE(vol0_w)
+// AM_RANGE(0x12, 0x12) AM_WRITE(rts_w)
+ AM_RANGE(0x13, 0x13) AM_WRITE(page_w)
+// AM_RANGE(0x14, 0x14) AM_WRITE(str_w)
+// AM_RANGE(0x15, 0x15) AM_WRITE(intl_w)
+ AM_RANGE(0x16, 0x16) AM_WRITE(dpage_w)
+ AM_RANGE(0x17, 0x17) AM_WRITE(vol1_w)
+ AM_RANGE(0x20, 0x2f) AM_DEVREADWRITE_LEGACY(Z80STI_TAG, z80sti_r, z80sti_w)
+ AM_RANGE(0x30, 0x30) AM_READWRITE(lrs_r, lrs_w)
+ AM_RANGE(0x40, 0x40) AM_READ(stat_r)
+ AM_RANGE(0x50, 0x50) AM_DEVWRITE(HD6345_TAG, hd6345_device, address_w)
+ AM_RANGE(0x52, 0x52) AM_DEVWRITE(HD6345_TAG, hd6345_device, register_w)
+ AM_RANGE(0x53, 0x53) AM_DEVREAD(HD6345_TAG, hd6345_device, register_r)
+ AM_RANGE(0x60, 0x60) AM_DEVWRITE_LEGACY(CENTRONICS_TAG, centronics_data_w)
+ AM_RANGE(0x70, 0x73) AM_DEVREADWRITE(I8255A_TAG, i8255_device, read, write)
+
+// AM_RANGE(0x80, 0x80) AM_WRITE(xrflgs_w)
+// AM_RANGE(0xc0, 0xc0) AM_WRITE(xrclrg_w)
+// AM_RANGE(0xe0, 0xe0) AM_WRITE(xrclu0_w)
+// AM_RANGE(0xe1, 0xe1) AM_WRITE(xrclu1_w)
+// AM_RANGE(0xe2, 0xe2) AM_WRITE(xrclu2_w)
+
+// AM_RANGE(0x80, 0x80) AM_WRITE(bl2out_w)
+// AM_RANGE(0x90, 0x90) AM_WRITE(gr2out_w)
+// AM_RANGE(0xa0, 0xa0) AM_WRITE(rd2out_w)
+// AM_RANGE(0xb0, 0xb0) AM_WRITE(clrg2_w)
+// AM_RANGE(0xc0, 0xc0) AM_WRITE(bluout_w)
+// AM_RANGE(0xd0, 0xd0) AM_WRITE(grnout_w)
+// AM_RANGE(0xe0, 0xe0) AM_WRITE(redout_w)
+// AM_RANGE(0xf0, 0xf0) AM_WRITE(clrg1_w)
+ADDRESS_MAP_END
+*/
+
+
+
+//**************************************************************************
+// DEVICE CONFIGURATION
+//**************************************************************************
+
+//-------------------------------------------------
+// mc6845_interface crtc_intf
+//-------------------------------------------------
+
+void grip_device::crtc_update_row(mc6845_device *device, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param)
+{
+ int column, bit;
+
+ for (column = 0; column < x_count; column++)
+ {
+ UINT16 address = (m_page << 12) | (((ma + column) & 0xfff) << 3) | (ra & 0x07);
+ UINT8 data = m_video_ram[address];
+
+ for (bit = 0; bit < 8; bit++)
+ {
+ int x = (column * 8) + bit;
+ int color = m_flash ? 0 : BIT(data, bit);
+
+ bitmap.pix32(y, x) = RGB_MONOCHROME_WHITE[color];
+ }
+ }
+}
+
+static MC6845_UPDATE_ROW( grip_update_row )
+{
+ grip_device *grip = downcast<grip_device *>(device->owner());
+
+ grip->crtc_update_row(device,bitmap,cliprect,ma,ra,y,x_count,cursor_x,param);
+}
+/*
+static MC6845_UPDATE_ROW( grip5_update_row )
+{
+ grip5_state *state = device->machine().driver_data<grip5_state>();
+ const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
+ int column, bit;
+
+ for (column = 0; column < x_count; column++)
+ {
+ UINT16 address = (state->m_dpage << 12) | (((ma + column) & 0xfff) << 3) | (ra & 0x07);
+ UINT8 data = state->m_video_ram[address];
+
+ for (bit = 0; bit < 8; bit++)
+ {
+ int x = (column * 8) + bit;
+ int color = state->m_flash ? 0 : BIT(data, bit);
+
+ bitmap.pix32(y, x) = palette[color];
+ }
+ }
+}
+
+static MC6845_ON_UPDATE_ADDR_CHANGED( grip5_update_addr_changed )
+{
+}
+*/
+
+static const INT16 speaker_levels[] = { -32768, 0, 32767, 0 };
+
+static const speaker_interface speaker_intf =
+{
+ 4,
+ speaker_levels
+};
+
+static MC6845_INTERFACE( crtc_intf )
+{
+ false,
+ 8,
+ NULL,
+ grip_update_row,
+ NULL,
+ DEVCB_DEVICE_LINE_MEMBER(Z80STI_TAG, z80sti_device, i1_w),
+ DEVCB_DEVICE_LINE_MEMBER(Z80STI_TAG, z80sti_device, i2_w),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ NULL
+};
+/*
+
+static MC6845_INTERFACE( grip5_crtc_intf )
+{
+ false,
+ 8,
+ NULL,
+ grip5_update_row,
+ NULL,
+ DEVCB_DEVICE_LINE(Z80STI_TAG, z80sti_i1_w),
+ DEVCB_DEVICE_LINE(Z80STI_TAG, z80sti_i2_w),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ grip5_update_addr_changed
+};
+*/
+
+
+//-------------------------------------------------
+// I8255A_INTERFACE( ppi_intf )
+//-------------------------------------------------
+
+READ8_MEMBER( grip_device::ppi_pa_r )
+{
+ /*
+
+ bit description
+
+ PA0 ECB bus D0
+ PA1 ECB bus D1
+ PA2 ECB bus D2
+ PA3 ECB bus D3
+ PA4 ECB bus D4
+ PA5 ECB bus D5
+ PA6 ECB bus D6
+ PA7 ECB bus D7
+
+ */
+
+ return m_ppi_pa;
+}
+
+WRITE8_MEMBER( grip_device::ppi_pa_w )
+{
+ /*
+
+ bit description
+
+ PA0 ECB bus D0
+ PA1 ECB bus D1
+ PA2 ECB bus D2
+ PA3 ECB bus D3
+ PA4 ECB bus D4
+ PA5 ECB bus D5
+ PA6 ECB bus D6
+ PA7 ECB bus D7
+
+ */
+
+ m_ppi_pa = data;
+}
+
+READ8_MEMBER( grip_device::ppi_pb_r )
+{
+ /*
+
+ bit description
+
+ PB0 Keyboard input
+ PB1 Keyboard input
+ PB2 Keyboard input
+ PB3 Keyboard input
+ PB4 Keyboard input
+ PB5 Keyboard input
+ PB6 Keyboard input
+ PB7 Keyboard input
+
+ */
+
+ return m_keydata;
+}
+
+WRITE8_MEMBER( grip_device::ppi_pc_w )
+{
+ /*
+
+ bit signal description
+
+ PC0 INTRB interrupt B output (keyboard)
+ PC1 KBF input buffer B full output (keyboard)
+ PC2 _KBSTB strobe B input (keyboard)
+ PC3 INTRA interrupt A output (PROF-80)
+ PC4 _STBA strobe A input (PROF-80)
+ PC5 IBFA input buffer A full output (PROF-80)
+ PC6 _ACKA acknowledge A input (PROF-80)
+ PC7 _OBFA output buffer full output (PROF-80)
+
+ */
+
+ // keyboard interrupt
+ m_ib = BIT(data, 0);
+ m_sti->i4_w(m_ib);
+
+ // keyboard buffer full
+ m_kbf = BIT(data, 1);
+
+ // PROF-80 interrupt
+ m_ia = BIT(data, 3);
+ m_sti->i7_w(m_ia);
+
+ // PROF-80 handshaking
+ m_ppi_pc = (!BIT(data, 7) << 7) | (!BIT(data, 5) << 6) | (m_ppi->pa_r() & 0x3f);
+}
+
+static I8255A_INTERFACE( ppi_intf )
+{
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, grip_device, ppi_pa_r), // Port A read
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, grip_device, ppi_pa_w), // Port A write
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, grip_device, ppi_pb_r), // Port B read
+ DEVCB_NULL, // Port B write
+ DEVCB_NULL, // Port C read
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, grip_device, ppi_pc_w) // Port C write
+};
+
+
+//-------------------------------------------------
+// Z80STI_INTERFACE( sti_intf )
+//-------------------------------------------------
+
+READ8_MEMBER( grip_device::sti_gpio_r )
+{
+ /*
+
+ bit signal description
+
+ I0 _CTS RS-232 clear to send input
+ I1 DE MC6845 display enable input
+ I2 CURSOR MC6845 cursor input
+ I3 BUSY Centronics busy input
+ I4 IB PPI8255 PC0 input
+ I5 _SKBD Serial keyboard input
+ I6 EXIN External interrupt input
+ I7 IA PPI8255 PC3 input
+
+ */
+
+ UINT8 data = 0x20;
+
+ // display enable
+ data |= m_crtc->de_r() << 1;
+
+ // cursor
+ data |= m_crtc->cursor_r() << 2;
+
+ // centronics busy
+ data |= m_centronics->busy_r() << 3;
+
+ // keyboard interrupt
+ data |= m_ib << 4;
+
+ // PROF-80 interrupt
+ data |= m_ia << 7;
+
+ return data;
+}
+
+WRITE_LINE_MEMBER( grip_device::speaker_w )
+{
+ int level = state && ((m_vol1 << 1) | m_vol0);
+
+ m_speaker->level_w(level);
+}
+
+static Z80STI_INTERFACE( sti_intf )
+{
+ 0, // serial receive clock
+ 0, // serial transmit clock
+ DEVCB_CPU_INPUT_LINE(Z80_TAG, INPUT_LINE_IRQ0), // interrupt
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, grip_device, sti_gpio_r), // GPIO read
+ DEVCB_NULL, // GPIO write
+ DEVCB_NULL, // serial input
+ DEVCB_NULL, // serial output
+ DEVCB_NULL, // timer A output
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, grip_device, speaker_w), // timer B output
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF, z80sti_device, tc_w), // timer C output
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF, z80sti_device, rc_w) // timer D output
+};
+
+
+//-------------------------------------------------
+// z80_daisy_config grip_daisy_chain
+//-------------------------------------------------
+
+static const z80_daisy_config grip_daisy_chain[] =
+{
+ { Z80STI_TAG },
+ { NULL }
+};
+
+
+//-------------------------------------------------
+// ASCII_KEYBOARD_INTERFACE( kb_intf )
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::kb_w )
+{
+ if (!m_kbf)
+ {
+ m_keydata = data;
+
+ // trigger GRIP 8255 port C bit 2 (_STBB)
+ m_ppi->pc2_w(0);
+ m_ppi->pc2_w(1);
+ }
+}
+
+static ASCII_KEYBOARD_INTERFACE( kb_intf )
+{
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, grip_device, kb_w)
+};
+
+
+
+//**************************************************************************
+// MACHINE CONFIGURATION
+//**************************************************************************
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( grip )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( grip )
+ // basic machine hardware
+ MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_16MHz/4)
+ MCFG_CPU_CONFIG(grip_daisy_chain)
+ MCFG_CPU_PROGRAM_MAP(grip_mem)
+ MCFG_CPU_IO_MAP(grip_io)
+
+ // video hardware
+ MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
+ MCFG_SCREEN_REFRESH_RATE(50)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not accurate
+ MCFG_SCREEN_UPDATE_DEVICE(MC6845_TAG, mc6845_device, screen_update)
+ MCFG_SCREEN_SIZE(640, 480)
+ MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
+
+ // sound hardware
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
+ MCFG_SOUND_CONFIG(speaker_intf)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
+
+ // devices
+ MCFG_MC6845_ADD(MC6845_TAG, MC6845, SCREEN_TAG, XTAL_16MHz/4, crtc_intf)
+// MCFG_MC6845_ADD(HD6345_TAG, HD6345, SCREEN_TAG, XTAL_16MHz/4, grip5_crtc_intf)
+ MCFG_I8255A_ADD(I8255A_TAG, ppi_intf)
+ MCFG_Z80STI_ADD(Z80STI_TAG, XTAL_16MHz/4, sti_intf)
+ MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics)
+ MCFG_ASCII_KEYBOARD_ADD("keyboard", kb_intf)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor grip_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( grip );
+}
+
+
+
+//**************************************************************************
+// INPUT PORTS
+//**************************************************************************
+
+//-------------------------------------------------
+// INPUT_PORTS( grip )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( grip )
+ PORT_START("J1")
+ PORT_CONFNAME( 0x01, 0x00, "J1 EPROM Type")
+ PORT_CONFSETTING( 0x00, "2732" )
+ PORT_CONFSETTING( 0x01, "2764/27128" )
+
+ PORT_START("J2")
+ PORT_CONFNAME( 0x03, 0x00, "J2 Centronics Mode")
+ PORT_CONFSETTING( 0x00, "Mode 1" )
+ PORT_CONFSETTING( 0x01, "Mode 2" )
+ PORT_CONFSETTING( 0x02, "Mode 3" )
+
+ PORT_START("J3A")
+ PORT_CONFNAME( 0x07, 0x00, "J3 Host")
+ PORT_CONFSETTING( 0x00, "ECB Bus" )
+ PORT_CONFSETTING( 0x01, "V24 9600 Baud" )
+ PORT_CONFSETTING( 0x02, "V24 4800 Baud" )
+ PORT_CONFSETTING( 0x03, "V24 1200 Baud" )
+ PORT_CONFSETTING( 0x04, "Keyboard" )
+
+ PORT_START("J3B")
+ PORT_CONFNAME( 0x07, 0x00, "J3 Keyboard")
+ PORT_CONFSETTING( 0x00, "Parallel" )
+ PORT_CONFSETTING( 0x01, "Serial (1200 Baud, 8 Bits)" )
+ PORT_CONFSETTING( 0x02, "Serial (1200 Baud, 7 Bits)" )
+ PORT_CONFSETTING( 0x03, "Serial (600 Baud, 8 Bits)" )
+ PORT_CONFSETTING( 0x04, "Serial (600 Baud, 7 Bits)" )
+
+ PORT_START("J4")
+ PORT_CONFNAME( 0x01, 0x00, "J4 COLOR")
+ PORT_CONFSETTING( 0x00, DEF_STR( No ) )
+ PORT_CONFSETTING( 0x01, DEF_STR( Yes ) )
+
+ PORT_START("J5")
+ PORT_CONFNAME( 0x01, 0x01, "J5 Power On Reset")
+ PORT_CONFSETTING( 0x00, "External" )
+ PORT_CONFSETTING( 0x01, "Internal" )
+
+ PORT_START("J6")
+ PORT_CONFNAME( 0x03, 0x00, "J6 Serial Clock")
+ PORT_CONFSETTING( 0x00, "TC/16, TD/16, TD" )
+ PORT_CONFSETTING( 0x01, "TD/16, TD/16, TD" )
+ PORT_CONFSETTING( 0x02, "TC/16, BAUD/16, input" )
+ PORT_CONFSETTING( 0x03, "BAUD/16, BAUD/16, input" )
+
+ PORT_START("J7")
+ PORT_CONFNAME( 0xff, 0xc0, "J7 ECB Bus Address")
+ PORT_CONFSETTING( 0xc0, "C0/C1" )
+ PORT_CONFSETTING( 0xa0, "A0/A1" )
+
+ PORT_START("J8")
+ PORT_CONFNAME( 0x01, 0x00, "J8 Video RAM")
+ PORT_CONFSETTING( 0x00, "32 KB" )
+ PORT_CONFSETTING( 0x01, "64 KB" )
+
+ PORT_START("J9")
+ PORT_CONFNAME( 0x01, 0x01, "J9 CPU Clock")
+ PORT_CONFSETTING( 0x00, "2 MHz" )
+ PORT_CONFSETTING( 0x01, "4 MHz" )
+
+ PORT_START("J10")
+ PORT_CONFNAME( 0x01, 0x01, "J10 Pixel Clock")
+ PORT_CONFSETTING( 0x00, "External" )
+ PORT_CONFSETTING( 0x01, "Internal" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor grip_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( grip );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// grip_device - constructor
+//-------------------------------------------------
+
+grip_device::grip_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECB_GRIP21, "GRIP-2.1", tag, owner, clock, "grip", __FILE__),
+ device_ecbbus_card_interface(mconfig, *this),
+ m_ppi(*this, I8255A_TAG),
+ m_sti(*this, Z80STI_TAG),
+ m_crtc(*this, MC6845_TAG),
+ m_centronics(*this, CENTRONICS_TAG),
+ m_speaker(*this, "speaker"),
+ m_video_ram(*this, "video_ram"),
+ m_j3a(*this, "J3A"),
+ m_j3b(*this, "J3B"),
+ m_j7(*this, "J7")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void grip_device::device_start()
+{
+ // allocate video RAM
+ m_video_ram.allocate(VIDEORAM_SIZE);
+
+ // setup GRIP memory banking
+ membank("videoram")->configure_entries(0, 2, m_video_ram, 0x8000);
+ membank("videoram")->set_entry(0);
+
+ // allocate keyboard scan timer
+ m_kb_timer = timer_alloc();
+ m_kb_timer->adjust(attotime::zero, 0, attotime::from_hz(2500));
+
+ // register for state saving
+ save_item(NAME(m_vol0));
+ save_item(NAME(m_vol1));
+ save_item(NAME(m_keydata));
+ save_item(NAME(m_kbf));
+ save_item(NAME(m_lps));
+ save_item(NAME(m_page));
+ save_item(NAME(m_flash));
+}
+
+/*
+void grip5_state::machine_start()
+{
+ grip_device::machine_start();
+
+ // setup ROM banking
+ membank("eprom")->configure_entries(0, 2, memregion(Z80_TAG)->base(), 0x4000);
+ *this.root_device().membank("eprom")->set_entry(0);
+
+ // register for state saving
+ save_item(NAME(m_dpage));
+}
+*/
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void grip_device::device_reset()
+{
+ m_base = m_j7->read();
+ m_page = 0;
+}
+
+
+//-------------------------------------------------
+// vol0_w - volume 0
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::vol0_w )
+{
+ m_vol0 = BIT(data, 7);
+}
+
+
+//-------------------------------------------------
+// vol1_w - volume 1
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::vol1_w )
+{
+ m_vol1 = BIT(data, 7);
+}
+
+
+//-------------------------------------------------
+// flash_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::flash_w )
+{
+ m_flash = BIT(data, 7);
+}
+
+
+//-------------------------------------------------
+// page_w - video page select
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::page_w )
+{
+ m_page = BIT(data, 7);
+
+ membank("videoram")->set_entry(m_page);
+}
+
+
+//-------------------------------------------------
+// stat_r -
+//-------------------------------------------------
+
+READ8_MEMBER( grip_device::stat_r )
+{
+ /*
+
+ bit signal description
+
+ 0 LPA0
+ 1 LPA1
+ 2 LPA2
+ 3 SENSE
+ 4 JS0
+ 5 JS1
+ 6 _ERROR
+ 7 LPSTB light pen strobe
+
+ */
+
+ UINT8 data = 0;
+ int js0 = 0, js1 = 0;
+
+ // JS0
+ switch (m_j3a->read())
+ {
+ case 0: js0 = 0; break;
+ case 1: js0 = 1; break;
+ case 2: js0 = m_vol0; break;
+ case 3: js0 = m_vol1; break;
+ case 4: js0 = m_page; break;
+ }
+
+ data |= js0 << 4;
+
+ // JS1
+ switch (m_j3b->read())
+ {
+ case 0: js1 = 0; break;
+ case 1: js1 = 1; break;
+ case 2: js1 = m_vol0; break;
+ case 3: js1 = m_vol1; break;
+ case 4: js1 = m_page; break;
+ }
+
+ data |= js1 << 5;
+
+ // centronics fault
+ data |= m_centronics->fault_r() << 6;
+
+ // light pen strobe
+ data |= m_lps << 7;
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// lrs_r -
+//-------------------------------------------------
+
+READ8_MEMBER( grip_device::lrs_r )
+{
+ m_lps = 0;
+
+ return 0;
+}
+
+
+//-------------------------------------------------
+// lrs_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::lrs_w )
+{
+ m_lps = 0;
+}
+
+
+//-------------------------------------------------
+// cxstb_r - centronics strobe
+//-------------------------------------------------
+
+READ8_MEMBER( grip_device::cxstb_r )
+{
+ m_centronics->strobe_w(0);
+ m_centronics->strobe_w(1);
+
+ return 0;
+}
+
+
+//-------------------------------------------------
+// cxstb_w - centronics strobe
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip_device::cxstb_w )
+{
+ m_centronics->strobe_w(0);
+ m_centronics->strobe_w(1);
+}
+
+/*
+//-------------------------------------------------
+// eprom_w - EPROM bank select
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip5_state::eprom_w )
+{
+ membank("eprom")->set_entry(BIT(data, 0));
+}
+
+
+//-------------------------------------------------
+// dpage_w - display page select
+//-------------------------------------------------
+
+WRITE8_MEMBER( grip5_state::dpage_w )
+{
+ m_dpage = BIT(data, 7);
+}
+*/
+
+
+//-------------------------------------------------
+// ecbbus_io_r - I/O read
+//-------------------------------------------------
+
+UINT8 grip_device::ecbbus_io_r(offs_t offset)
+{
+ UINT8 data = 0;
+
+ if ((offset & 0xfe) == m_base)
+ {
+ if (BIT(offset, 0))
+ {
+ data = m_ppi_pa;
+
+ // acknowledge PPI port A
+ m_ppi->pc6_w(0);
+ m_ppi->pc6_w(1);
+ }
+ else
+ {
+ data = m_ppi_pc;
+ }
+ }
+
+ return data;
+};
+
+
+//-------------------------------------------------
+// ecbbus_io_w - I/O write
+//-------------------------------------------------
+
+void grip_device::ecbbus_io_w(offs_t offset, UINT8 data)
+{
+ if ((offset & 0xfe) == m_base)
+ {
+ if (BIT(offset, 0))
+ {
+ m_ppi_pa = data;
+
+ // strobe PPI port A
+ m_ppi->pc4_w(0);
+ m_ppi->pc4_w(1);
+ }
+ }
+}
diff --git a/src/emu/bus/ecbbus/grip.h b/src/emu/bus/ecbbus/grip.h
new file mode 100644
index 00000000000..269cade9752
--- /dev/null
+++ b/src/emu/bus/ecbbus/grip.h
@@ -0,0 +1,127 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Conitec Datensysteme GRIP graphics card emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __GRIP__
+#define __GRIP__
+
+#include "emu.h"
+#include "ecbbus.h"
+#include "cpu/z80/z80.h"
+#include "cpu/z80/z80daisy.h"
+#include "machine/ctronics.h"
+#include "machine/i8255.h"
+#include "machine/keyboard.h"
+#include "machine/z80sti.h"
+#include "sound/speaker.h"
+#include "video/mc6845.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> grip_device
+
+class grip_device : public device_t,
+ public device_ecbbus_card_interface
+{
+public:
+ // construction/destruction
+ grip_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+
+ // not really public
+ DECLARE_WRITE8_MEMBER( vol0_w );
+ DECLARE_WRITE8_MEMBER( vol1_w );
+ DECLARE_WRITE8_MEMBER( flash_w );
+ DECLARE_WRITE8_MEMBER( page_w );
+ DECLARE_READ8_MEMBER( stat_r );
+ DECLARE_READ8_MEMBER( lrs_r );
+ DECLARE_WRITE8_MEMBER( lrs_w );
+ DECLARE_READ8_MEMBER( cxstb_r );
+ DECLARE_WRITE8_MEMBER( cxstb_w );
+ DECLARE_READ8_MEMBER( ppi_pa_r );
+ DECLARE_WRITE8_MEMBER( ppi_pa_w );
+ DECLARE_READ8_MEMBER( ppi_pb_r );
+ DECLARE_WRITE8_MEMBER( ppi_pc_w );
+ DECLARE_READ8_MEMBER( sti_gpio_r );
+ DECLARE_WRITE_LINE_MEMBER( speaker_w );
+ DECLARE_WRITE8_MEMBER( kb_w );
+
+ void crtc_update_row(mc6845_device *device, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_ecbbus_card_interface overrides
+ virtual UINT8 ecbbus_io_r(offs_t offset);
+ virtual void ecbbus_io_w(offs_t offset, UINT8 data);
+
+private:
+ required_device<i8255_device> m_ppi;
+ required_device<z80sti_device> m_sti;
+ required_device<mc6845_device> m_crtc;
+ required_device<centronics_device> m_centronics;
+ required_device<speaker_sound_device> m_speaker;
+ optional_shared_ptr<UINT8> m_video_ram;
+ required_ioport m_j3a;
+ required_ioport m_j3b;
+ required_ioport m_j7;
+
+ // sound state
+ int m_vol0;
+ int m_vol1;
+
+ // keyboard state
+ int m_ia; // PPI port A interrupt
+ int m_ib; // PPI port B interrupt
+ UINT8 m_keydata; // keyboard data
+ int m_kbf; // keyboard buffer full
+
+ // video state
+ int m_lps; // light pen sense
+ int m_page; // video page
+ int m_flash; // flash
+
+ // ECB bus state
+ UINT8 m_base; // ECB base address
+ UINT8 m_ppi_pa; // PPI port A data
+ UINT8 m_ppi_pc; // PPI port C data
+
+ // timers
+ emu_timer *m_kb_timer;
+};
+
+
+ /*
+ required_device<hd6345_device> m_crtc;
+ DECLARE_WRITE8_MEMBER( eprom_w );
+ DECLARE_WRITE8_MEMBER( dpage_w );
+
+ // video state
+ int m_dpage; // displayed video page
+ */
+
+
+
+// device type definition
+extern const device_type ECB_GRIP21;
+
+#endif
diff --git a/src/emu/bus/econet/e01.c b/src/emu/bus/econet/e01.c
new file mode 100644
index 00000000000..86ea9b532cc
--- /dev/null
+++ b/src/emu/bus/econet/e01.c
@@ -0,0 +1,773 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Acorn FileStore E01/E01S network hard disk emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+ http://acorn.chriswhy.co.uk/Network/Econet.html
+ http://acorn.chriswhy.co.uk/Network/Pics/Acorn_FileStoreE01.html
+ http://acorn.chriswhy.co.uk/8bit_Upgrades/Acorn_FileStoreE01S.html
+ http://www.heyrick.co.uk/econet/fs/emulator.html
+ http://www.pdfio.com/k-1019481.html#
+
+**********************************************************************/
+
+/*
+
+ The FileStore E01 is an Econet station in its own right which acts as a fileserver when connected to a network. It is a single unit
+ which does not require a monitor or keyboard. Communication with the FileStore is done via another Econet station when the FileStore
+ is in one of two "maintenance modes"
+
+ The E01 can be seen as a slimmed-down BBC computer tailored for its function as a fileserver. It has a 6502 processor at its heart
+ along with a 6522 VIA just like the BBC. It requires a Master series Econet module to be plugged in and connects to the network via
+ an Econet port in the same way as any other station.
+
+ The FileStore E01S was Acorns second generation Filestore replacing the FileStore E01. The FileStore is a dedicated Econet fileserver,
+ it does not support a keyboard and monitor, instead you use an Econet attached station to logon and perform administrative tasks.
+
+ Hitachi HD146818P Real Time Clock
+ Rockwell R65C102P3 CPU
+ 2 x TMM27256D-20 white labelled EPROMs, TMSE01 MOS on left and E01 FS on the right
+ IC20 WD2793-APL-02 floppy disc controller
+ 2 x NEC D41464C-12 64k x 4bit NMOS RAM ICs giving 64K memory
+ IC21 Rockwell RC6522AP VIA behind to the right
+
+*/
+
+/*
+
+ TODO:
+
+ - centronics strobe
+ - econet clock speed select
+ - ADLC interrupts
+ - ECONET device
+ - artwork
+ - hard disk
+
+ E20: Rodime RO652 (-chs 306,4,17,512)
+ E40S: Rodime RO3057S (-chs 680,5,26,512)
+ E60S:
+
+*/
+
+#include "e01.h"
+#include "machine/scsibus.h"
+#include "machine/scsicb.h"
+#include "machine/scsihd.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define R65C102_TAG "r65c102"
+#define R6522_TAG "ic21"
+#define WD2793_TAG "ic20"
+#define MC6854_TAG "mc6854"
+#define HD146818_TAG "hd146818"
+#define CENTRONICS_TAG "centronics"
+#define SCSIBUS_TAG "scsi"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type E01 = &device_creator<e01_device>;
+const device_type E01S = &device_creator<e01s_device>;
+
+e01s_device::e01s_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ :e01_device(mconfig, E01S, "Acorn FileStore E01S", tag, owner, clock, "e01s", __FILE__) { m_variant = TYPE_E01S; }
+
+
+//-------------------------------------------------
+// ROM( e01 )
+//-------------------------------------------------
+
+ROM_START( e01 )
+ ROM_REGION( 0x10000, R65C102_TAG, 0 )
+ //ROM_DEFAULT_BIOS("v131")
+ //ROM_SYSTEM_BIOS( 0, "v131", "V 1.31" )
+ ROM_LOAD( "0254,205-04 e01 fs", 0x0000, 0x8000, CRC(ae666c76) SHA1(0954119eb5cd09cdbadf76d60d812aa845838d5a) )
+ ROM_LOAD( "0254,205-03 e01 mos", 0x8000, 0x8000, CRC(a13e8014) SHA1(6f44a1a48108c60a64a1774cb30c1a59c4a6a199) )
+ROM_END
+
+
+//-------------------------------------------------
+// ROM( e01s )
+//-------------------------------------------------
+
+ROM_START( e01s )
+ ROM_REGION( 0x10000, R65C102_TAG, 0 )
+ //ROM_DEFAULT_BIOS("v140")
+ //ROM_SYSTEM_BIOS( 0, "v133", "V 1.33" ) // 0282,008-02 e01s rom
+ ROM_LOAD( "e01sv133.rom", 0x0000, 0x10000, CRC(2a4a0032) SHA1(54ad68ceae44992293ccdd64ec88ad8520deec22) ) // which label?
+ //ROM_SYSTEM_BIOS( 1, "v140", "V 1.40" )
+ ROM_LOAD( "e01sv140.rom", 0x0000, 0x10000, CRC(5068fe86) SHA1(9b8740face15b5541e2375b3054988af00757931) ) // which label?
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *e01_device::device_rom_region() const
+{
+ switch (m_variant)
+ {
+ default:
+ case TYPE_E01:
+ return ROM_NAME( e01 );
+
+ case TYPE_E01S:
+ return ROM_NAME( e01s );
+ }
+}
+
+
+//-------------------------------------------------
+// MC146818_INTERFACE( rtc_intf )
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( e01_device::rtc_irq_w )
+{
+ m_rtc_irq = state;
+
+ update_interrupts();
+}
+
+
+//-------------------------------------------------
+// mc6854_interface adlc_intf
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( e01_device::adlc_irq_w )
+{
+ m_adlc_irq = state;
+
+ update_interrupts();
+}
+
+READ_LINE_MEMBER( e01_device::econet_data_r )
+{
+ return m_econet->data_r();
+}
+
+WRITE_LINE_MEMBER( e01_device::econet_data_w )
+{
+ m_econet->data_w(this, state);
+}
+
+static const mc6854_interface adlc_intf =
+{
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, e01_device, adlc_irq_w),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, e01_device, econet_data_r),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, e01_device, econet_data_w),
+ NULL,
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// via6522_interface via_intf
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( e01_device::via_irq_w )
+{
+ m_via_irq = state;
+
+ update_interrupts();
+}
+
+WRITE_LINE_MEMBER( e01_device::clk_en_w )
+{
+ m_clk_en = state;
+}
+
+static const via6522_interface via_intf =
+{
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_DEVICE_MEMBER(CENTRONICS_TAG, centronics_device, write),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, e01_device, via_irq_w)
+};
+
+
+//-------------------------------------------------
+// wd17xx_interface fdc_intf
+//-------------------------------------------------
+
+static SLOT_INTERFACE_START( e01_floppies )
+ SLOT_INTERFACE( "35dd", FLOPPY_35_DD ) // NEC FD1036 A
+SLOT_INTERFACE_END
+
+void e01_device::fdc_irq_w(bool state)
+{
+ m_fdc_irq = state;
+
+ update_interrupts();
+}
+
+void e01_device::fdc_drq_w(bool state)
+{
+ m_fdc_drq = state;
+
+ update_interrupts();
+}
+
+WRITE_LINE_MEMBER( e01_device::scsi_bsy_w )
+{
+ if (state)
+ {
+ m_scsibus->scsi_sel_w(0);
+ }
+}
+
+WRITE_LINE_MEMBER( e01_device::scsi_req_w )
+{
+ if (!state)
+ {
+ m_scsibus->scsi_ack_w(0);
+ }
+
+ m_hdc_irq = !state;
+ update_interrupts();
+}
+
+
+//-------------------------------------------------
+// centronics_interface e01_centronics_intf
+//-------------------------------------------------
+
+static centronics_interface e01_centronics_intf =
+{
+ DEVCB_DEVICE_LINE_MEMBER(R6522_TAG, via6522_device, write_ca1),
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( e01_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( e01_mem, AS_PROGRAM, 8, e01_device )
+ AM_RANGE(0x0000, 0xffff) AM_READWRITE(read, write)
+ AM_RANGE(0xfc00, 0xfc00) AM_MIRROR(0x00c3) AM_READWRITE(rtc_address_r, rtc_address_w)
+ AM_RANGE(0xfc04, 0xfc04) AM_MIRROR(0x00c3) AM_READWRITE(rtc_data_r, rtc_data_w)
+ AM_RANGE(0xfc08, 0xfc08) AM_MIRROR(0x00c0) AM_READ(ram_select_r) AM_WRITE(floppy_w)
+ AM_RANGE(0xfc0c, 0xfc0f) AM_MIRROR(0x00c0) AM_DEVREADWRITE(WD2793_TAG, wd2793_t, read, write)
+ AM_RANGE(0xfc10, 0xfc1f) AM_MIRROR(0x00c0) AM_DEVREADWRITE(R6522_TAG, via6522_device, read, write)
+ AM_RANGE(0xfc20, 0xfc23) AM_MIRROR(0x00c0) AM_DEVREADWRITE_LEGACY(MC6854_TAG, mc6854_r, mc6854_w)
+ AM_RANGE(0xfc24, 0xfc24) AM_MIRROR(0x00c3) AM_READWRITE(network_irq_disable_r, network_irq_disable_w)
+ AM_RANGE(0xfc28, 0xfc28) AM_MIRROR(0x00c3) AM_READWRITE(network_irq_enable_r, network_irq_enable_w)
+ AM_RANGE(0xfc2c, 0xfc2c) AM_MIRROR(0x00c3) AM_READ_PORT("FLAP")
+ AM_RANGE(0xfc30, 0xfc30) AM_MIRROR(0x00c0) AM_READWRITE(hdc_data_r, hdc_data_w)
+ AM_RANGE(0xfc31, 0xfc31) AM_MIRROR(0x00c0) AM_READ(hdc_status_r)
+ AM_RANGE(0xfc32, 0xfc32) AM_MIRROR(0x00c0) AM_WRITE(hdc_select_w)
+ AM_RANGE(0xfc33, 0xfc33) AM_MIRROR(0x00c0) AM_WRITE(hdc_irq_enable_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( e01 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( e01 )
+ // basic machine hardware
+ MCFG_CPU_ADD(R65C102_TAG, M65C02, XTAL_8MHz/4) // Rockwell R65C102P3
+ MCFG_CPU_PROGRAM_MAP(e01_mem)
+
+ MCFG_MC146818_IRQ_ADD(HD146818_TAG, MC146818_STANDARD, WRITELINE(e01_device, rtc_irq_w))
+
+ // devices
+ MCFG_VIA6522_ADD(R6522_TAG, XTAL_8MHz/4, via_intf)
+ MCFG_MC6854_ADD(MC6854_TAG, adlc_intf)
+ MCFG_WD2793x_ADD(WD2793_TAG, XTAL_8MHz/4)
+ MCFG_FLOPPY_DRIVE_ADD(WD2793_TAG":0", e01_floppies, "35dd", floppy_image_device::default_floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(WD2793_TAG":1", e01_floppies, "35dd", floppy_image_device::default_floppy_formats)
+ MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, e01_centronics_intf)
+
+ MCFG_SCSIBUS_ADD(SCSIBUS_TAG)
+ MCFG_SCSIDEV_ADD(SCSIBUS_TAG ":harddisk0", SCSIHD, SCSI_ID_0)
+ MCFG_SCSICB_ADD(SCSIBUS_TAG ":host")
+ MCFG_SCSICB_BSY_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, e01_device, scsi_bsy_w))
+ MCFG_SCSICB_REQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, e01_device, scsi_req_w))
+
+ // internal ram
+ MCFG_RAM_ADD(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("64K")
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor e01_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( e01 );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( e01 )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( e01 )
+ PORT_START("FLAP")
+ PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_CONFNAME( 0x40, 0x00, "Front Flap")
+ PORT_CONFSETTING( 0x00, "Closed" )
+ PORT_CONFSETTING( 0x40, "Open" )
+ PORT_DIPNAME( 0x80, 0x00, "SW3")
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor e01_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( e01 );
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// update_interrupts - update interrupt state
+//-------------------------------------------------
+
+inline void e01_device::update_interrupts()
+{
+ int irq = (m_via_irq || (m_hdc_ie & m_hdc_irq) || m_rtc_irq) ? ASSERT_LINE : CLEAR_LINE;
+ int nmi = (m_fdc_irq || m_fdc_drq || (m_adlc_ie & m_adlc_irq)) ? ASSERT_LINE : CLEAR_LINE;
+
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, irq);
+ m_maincpu->set_input_line(INPUT_LINE_NMI, nmi);
+}
+
+
+//-------------------------------------------------
+// network_irq_enable - network interrupt enable
+//-------------------------------------------------
+
+inline void e01_device::network_irq_enable(int enabled)
+{
+ m_adlc_ie = enabled;
+
+ update_interrupts();
+}
+
+
+//-------------------------------------------------
+// hdc_irq_enable - hard disk interrupt enable
+//-------------------------------------------------
+
+inline void e01_device::hdc_irq_enable(int enabled)
+{
+ m_hdc_ie = enabled;
+
+ update_interrupts();
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// e01_device - constructor
+//-------------------------------------------------
+
+e01_device::e01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, E01, "Acorn FileStore E01", tag, owner, clock, "e01" , __FILE__),
+ device_econet_interface(mconfig, *this),
+ m_maincpu(*this, R65C102_TAG),
+ m_fdc(*this, WD2793_TAG),
+ m_adlc(*this, MC6854_TAG),
+ m_rtc(*this, HD146818_TAG),
+ m_ram(*this, RAM_TAG),
+ m_scsibus(*this, SCSIBUS_TAG ":host"),
+ m_floppy0(*this, WD2793_TAG":0"),
+ m_floppy1(*this, WD2793_TAG":1"),
+ m_rom(*this, R65C102_TAG),
+ m_adlc_ie(0),
+ m_hdc_ie(0),
+ m_rtc_irq(CLEAR_LINE),
+ m_via_irq(CLEAR_LINE),
+ m_hdc_irq(CLEAR_LINE),
+ m_fdc_irq(CLEAR_LINE),
+ m_fdc_drq(CLEAR_LINE),
+ m_adlc_irq(CLEAR_LINE),
+ m_clk_en(0)
+{
+}
+
+
+e01_device::e01_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_econet_interface(mconfig, *this),
+ m_maincpu(*this, R65C102_TAG),
+ m_fdc(*this, WD2793_TAG),
+ m_adlc(*this, MC6854_TAG),
+ m_rtc(*this, HD146818_TAG),
+ m_ram(*this, RAM_TAG),
+ m_scsibus(*this, SCSIBUS_TAG ":host"),
+ m_floppy0(*this, WD2793_TAG":0"),
+ m_floppy1(*this, WD2793_TAG":1"),
+ m_rom(*this, R65C102_TAG),
+ m_adlc_ie(0),
+ m_hdc_ie(0),
+ m_rtc_irq(CLEAR_LINE),
+ m_via_irq(CLEAR_LINE),
+ m_hdc_irq(CLEAR_LINE),
+ m_fdc_irq(CLEAR_LINE),
+ m_fdc_drq(CLEAR_LINE),
+ m_adlc_irq(CLEAR_LINE),
+ m_clk_en(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void e01_device::device_start()
+{
+ // floppy callbacks
+ m_fdc->setup_intrq_cb(wd2793_t::line_cb(FUNC(e01_device::fdc_irq_w), this));
+ m_fdc->setup_drq_cb(wd2793_t::line_cb(FUNC(e01_device::fdc_drq_w), this));
+
+ // allocate timers
+ m_clk_timer = timer_alloc();
+
+ // register for state saving
+ save_item(NAME(m_adlc_ie));
+ save_item(NAME(m_hdc_ie));
+ save_item(NAME(m_rtc_irq));
+ save_item(NAME(m_via_irq));
+ save_item(NAME(m_hdc_irq));
+ save_item(NAME(m_fdc_drq));
+ save_item(NAME(m_adlc_irq));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void e01_device::device_reset()
+{
+ m_clk_timer->adjust(attotime::zero, 0, attotime::from_hz(200000));
+ m_ram_en = false;
+}
+
+
+//-------------------------------------------------
+// device_timer - handler timer events
+//-------------------------------------------------
+
+void e01_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if (m_clk_en)
+ {
+ m_econet->clk_w(this, 1);
+ m_econet->clk_w(this, 0);
+ }
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::read )
+{
+ UINT8 data = 0;
+
+ if (m_ram_en)
+ {
+ data = m_ram->pointer()[offset];
+ }
+ else
+ {
+ data = m_rom->base()[offset];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::write )
+{
+ m_ram->pointer()[offset] = data;
+}
+
+
+//-------------------------------------------------
+// eprom_r - ROM/RAM select read
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::ram_select_r )
+{
+ m_ram_en = true;
+
+ return 0;
+}
+
+
+//-------------------------------------------------
+// floppy_w - floppy control write
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::floppy_w )
+{
+ /*
+
+ bit description
+
+ 0 floppy 1 select
+ 1 floppy 2 select
+ 2 floppy side select
+ 3 NVRAM select
+ 4 floppy density
+ 5 floppy master reset
+ 6 floppy test
+ 7 mode LED
+
+ */
+
+ // floppy select
+ floppy_image_device *floppy = NULL;
+
+ if (!BIT(data, 0)) floppy = m_floppy0->get_device();
+ if (!BIT(data, 1)) floppy = m_floppy1->get_device();
+
+ m_fdc->set_floppy(floppy);
+
+ // floppy side select
+ if (floppy) floppy->ss_w(BIT(data, 2));
+
+ // TODO NVRAM select
+ //mc146818_stby_w(m_rtc, BIT(data, 3));
+
+ // floppy density
+ m_fdc->dden_w(BIT(data, 4));
+
+ // floppy master reset
+ if (!BIT(data, 5)) m_fdc->reset();
+
+ // TODO floppy test
+
+ // mode LED
+ output_set_value("led_0", BIT(data, 7));
+}
+
+
+//-------------------------------------------------
+// network_irq_disable_r -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::network_irq_disable_r )
+{
+ network_irq_enable(0);
+
+ return 0;
+}
+
+
+//-------------------------------------------------
+// network_irq_disable_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::network_irq_disable_w )
+{
+ network_irq_enable(0);
+}
+
+
+//-------------------------------------------------
+// network_irq_enable_r -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::network_irq_enable_r )
+{
+ network_irq_enable(1);
+
+ return 0;
+}
+
+
+//-------------------------------------------------
+// network_irq_enable_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::network_irq_enable_w )
+{
+ network_irq_enable(1);
+}
+
+
+//-------------------------------------------------
+// hdc_data_r -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::hdc_data_r )
+{
+ UINT8 data = m_scsibus->scsi_data_r(space, 0);
+
+ m_scsibus->scsi_ack_w(1);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// hdc_data_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::hdc_data_w )
+{
+ m_scsibus->scsi_data_w(space, 0, data);
+
+ m_scsibus->scsi_ack_w(1);
+}
+
+
+//-------------------------------------------------
+// hdc_status_r -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::hdc_status_r )
+{
+ /*
+
+ bit description
+
+ 0 MSG
+ 1 BSY
+ 2 0
+ 3 0
+ 4 NIRQ
+ 5 REQ
+ 6 I/O
+ 7 C/D
+
+ */
+
+ UINT8 data = 0;
+
+ // SCSI bus
+ data |= m_scsibus->scsi_msg_r();
+ data |= m_scsibus->scsi_bsy_r() << 1;
+ data |= m_scsibus->scsi_req_r() << 5;
+ data |= m_scsibus->scsi_io_r() << 6;
+ data |= m_scsibus->scsi_cd_r() << 7;
+
+ // TODO NIRQ
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// hdc_select_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::hdc_select_w )
+{
+ m_scsibus->scsi_sel_w(1);
+}
+
+
+//-------------------------------------------------
+// hdc_irq_enable_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::hdc_irq_enable_w )
+{
+ hdc_irq_enable(BIT(data, 0));
+}
+
+
+//-------------------------------------------------
+// rtc_address_r -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::rtc_address_r )
+{
+ return m_rtc->read(space, 0);
+}
+
+
+//-------------------------------------------------
+// rtc_address_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::rtc_address_w )
+{
+ m_rtc->write(space, 0, data);
+}
+
+
+//-------------------------------------------------
+// rtc_data_r -
+//-------------------------------------------------
+
+READ8_MEMBER( e01_device::rtc_data_r )
+{
+ return m_rtc->read(space, 1);
+}
+
+
+//-------------------------------------------------
+// rtc_data_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( e01_device::rtc_data_w )
+{
+ m_rtc->write(space, 1, data);
+}
+
+
+//-------------------------------------------------
+// econet_clk_w -
+//-------------------------------------------------
+
+void e01_device::econet_clk(int state)
+{
+ mc6854_rxc_w(m_adlc, state);
+ mc6854_txc_w(m_adlc, state);
+}
diff --git a/src/emu/bus/econet/e01.h b/src/emu/bus/econet/e01.h
new file mode 100644
index 00000000000..bea01f4768c
--- /dev/null
+++ b/src/emu/bus/econet/e01.h
@@ -0,0 +1,135 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Acorn FileStore E01/E01S network hard disk emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __E01__
+#define __E01__
+
+#include "emu.h"
+#include "econet.h"
+#include "cpu/m6502/m65c02.h"
+#include "machine/6522via.h"
+#include "machine/ctronics.h"
+#include "machine/mc146818.h"
+#include "machine/mc6854.h"
+#include "machine/ram.h"
+#include "machine/scsicb.h"
+#include "machine/wd_fdc.h"
+
+class e01_device : public device_t,
+ public device_econet_interface
+{
+public:
+ // construction/destruction
+ e01_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);
+ e01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ enum
+ {
+ TYPE_E01 = 0,
+ TYPE_E01S
+ };
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_READ8_MEMBER( ram_select_r );
+ DECLARE_WRITE8_MEMBER( floppy_w );
+ DECLARE_READ8_MEMBER( network_irq_disable_r );
+ DECLARE_WRITE8_MEMBER( network_irq_disable_w );
+ DECLARE_READ8_MEMBER( network_irq_enable_r );
+ DECLARE_WRITE8_MEMBER( network_irq_enable_w );
+ DECLARE_READ8_MEMBER( hdc_data_r );
+ DECLARE_WRITE8_MEMBER( hdc_data_w );
+ DECLARE_READ8_MEMBER( hdc_status_r );
+ DECLARE_WRITE8_MEMBER( hdc_select_w );
+ DECLARE_WRITE8_MEMBER( hdc_irq_enable_w );
+ DECLARE_READ8_MEMBER( rtc_address_r );
+ DECLARE_WRITE8_MEMBER( rtc_address_w );
+ DECLARE_READ8_MEMBER( rtc_data_r );
+ DECLARE_WRITE8_MEMBER( rtc_data_w );
+ DECLARE_WRITE_LINE_MEMBER( rtc_irq_w );
+ DECLARE_WRITE_LINE_MEMBER( adlc_irq_w );
+ DECLARE_READ_LINE_MEMBER( econet_data_r );
+ DECLARE_WRITE_LINE_MEMBER( econet_data_w );
+ DECLARE_WRITE_LINE_MEMBER( via_irq_w );
+ DECLARE_WRITE_LINE_MEMBER( clk_en_w );
+ DECLARE_WRITE_LINE_MEMBER( fdc_irq_w );
+ DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
+ DECLARE_WRITE_LINE_MEMBER( scsi_bsy_w );
+ DECLARE_WRITE_LINE_MEMBER( scsi_req_w );
+ void fdc_irq_w(bool state);
+ void fdc_drq_w(bool state);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+
+ // device_econet_interface overrides
+ virtual void econet_clk(int state);
+
+ required_device<m65c02_device> m_maincpu;
+ required_device<wd2793_t> m_fdc;
+ required_device<mc6854_device> m_adlc;
+ required_device<mc146818_device> m_rtc;
+ required_device<ram_device> m_ram;
+ required_device<scsicb_device> m_scsibus;
+ required_device<floppy_connector> m_floppy0;
+ required_device<floppy_connector> m_floppy1;
+ required_memory_region m_rom;
+
+ inline void update_interrupts();
+ inline void network_irq_enable(int enabled);
+ inline void hdc_irq_enable(int enabled);
+
+ // interrupt state
+ int m_adlc_ie;
+ int m_hdc_ie;
+ int m_rtc_irq;
+ int m_via_irq;
+ int m_hdc_irq;
+ int m_fdc_irq;
+ bool m_fdc_drq;
+ int m_adlc_irq;
+ int m_clk_en;
+ bool m_ram_en;
+
+ int m_variant;
+
+ // timers
+ emu_timer *m_clk_timer;
+};
+
+
+// ======================> e01s_device
+
+class e01s_device : public e01_device
+{
+public:
+ // construction/destruction
+ e01s_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// device type definition
+extern const device_type E01;
+extern const device_type E01S;
+
+
+
+#endif
diff --git a/src/emu/bus/econet/econet.c b/src/emu/bus/econet/econet.c
new file mode 100644
index 00000000000..0e901795d4b
--- /dev/null
+++ b/src/emu/bus/econet/econet.c
@@ -0,0 +1,367 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Acorn Computers Econet local area network emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "econet.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+static const char *const SIGNAL_NAME[] = { "CLK", "DATA" };
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type ECONET = &device_creator<econet_device>;
+const device_type ECONET_SLOT = &device_creator<econet_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_econet_interface - constructor
+//-------------------------------------------------
+
+device_econet_interface::device_econet_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_econet_interface - destructor
+//-------------------------------------------------
+
+device_econet_interface::~device_econet_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// econet_slot_device - constructor
+//-------------------------------------------------
+
+econet_slot_device::econet_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, ECONET_SLOT, "Econet station", tag, owner, clock, "econet_slot", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// static_set_slot -
+//-------------------------------------------------
+
+void econet_slot_device::static_set_slot(device_t &device, int address)
+{
+ econet_slot_device &econet_card = dynamic_cast<econet_slot_device &>(device);
+ econet_card.m_address = address;
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void econet_slot_device::device_start()
+{
+ m_econet = machine().device<econet_device>(ECONET_TAG);
+ device_econet_interface *dev = dynamic_cast<device_econet_interface *>(get_card_device());
+ if (dev) m_econet->add_device(get_card_device(), m_address);
+}
+
+
+
+//**************************************************************************
+// DEVICE CONFIGURATION
+//**************************************************************************
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void econet_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const econet_interface *intf = reinterpret_cast<const econet_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<econet_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_clk_cb, 0, sizeof(m_out_clk_cb));
+ memset(&m_out_data_cb, 0, sizeof(m_out_data_cb));
+ }
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_signal -
+//-------------------------------------------------
+
+inline void econet_device::set_signal(device_t *device, int signal, int state)
+{
+ bool changed = false;
+
+ if (device == this)
+ {
+ if (m_line[signal] != state)
+ {
+ if (LOG) logerror("Econet: '%s' %s %u\n", tag(), SIGNAL_NAME[signal], state);
+ m_line[signal] = state;
+ changed = true;
+ }
+ }
+ else
+ {
+ daisy_entry *entry = m_device_list.first();
+
+ while (entry)
+ {
+ if (!strcmp(entry->m_device->tag(), device->tag()))
+ {
+ if (entry->m_line[signal] != state)
+ {
+ if (LOG) logerror("Econet: '%s' %s %u\n", device->tag(), SIGNAL_NAME[signal], state);
+ entry->m_line[signal] = state;
+ changed = true;
+ }
+ }
+
+ entry = entry->next();
+ }
+ }
+
+ if (changed)
+ {
+ switch (signal)
+ {
+ case CLK: m_out_clk_func(state); break;
+ case DATA: m_out_data_func(state); break;
+ }
+
+ daisy_entry *entry = m_device_list.first();
+
+ while (entry)
+ {
+ switch (signal)
+ {
+ case CLK:
+ entry->m_interface->econet_clk(state);
+ break;
+
+ case DATA:
+ entry->m_interface->econet_data(state);
+ break;
+ }
+
+ entry = entry->next();
+ }
+
+ if (LOG) logerror("Econet: CLK %u DATA %u\n", get_signal(CLK), get_signal(DATA));
+ }
+}
+
+
+//-------------------------------------------------
+// get_signal -
+//-------------------------------------------------
+
+inline int econet_device::get_signal(int signal)
+{
+ int state = m_line[signal];
+
+ if (state)
+ {
+ daisy_entry *entry = m_device_list.first();
+
+ while (entry)
+ {
+ if (!entry->m_line[signal])
+ {
+ state = 0;
+ break;
+ }
+
+ entry = entry->next();
+ }
+ }
+
+ return state;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// econet_device - constructor
+//-------------------------------------------------
+
+econet_device::econet_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, ECONET, "Econet", tag, owner, clock, "econet", __FILE__)
+{
+ for (int i = 0; i < SIGNAL_COUNT; i++)
+ {
+ m_line[i] = 1;
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void econet_device::device_start()
+{
+ // resolve callbacks
+ m_out_clk_func.resolve(m_out_clk_cb, *this);
+ m_out_data_func.resolve(m_out_data_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_stop - device-specific stop
+//-------------------------------------------------
+
+void econet_device::device_stop()
+{
+ m_device_list.reset();
+}
+
+
+//-------------------------------------------------
+// add_device -
+//-------------------------------------------------
+
+void econet_device::add_device(device_t *target, int address)
+{
+ daisy_entry *entry = auto_alloc(machine(), daisy_entry(target));
+
+ entry->m_interface->m_econet = this;
+ entry->m_interface->m_address = address;
+
+ m_device_list.append(*entry);
+}
+
+
+//-------------------------------------------------
+// daisy_entry - constructor
+//-------------------------------------------------
+
+econet_device::daisy_entry::daisy_entry(device_t *device)
+ : m_next(NULL),
+ m_device(device),
+ m_interface(NULL)
+{
+ for (int i = 0; i < SIGNAL_COUNT; i++)
+ {
+ m_line[i] = 1;
+ }
+
+ device->interface(m_interface);
+}
+
+
+//-------------------------------------------------
+// clk_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( econet_device::clk_r )
+{
+ return get_signal(CLK);
+}
+
+
+//-------------------------------------------------
+// data_r -
+//-------------------------------------------------
+
+READ_LINE_MEMBER( econet_device::data_r )
+{
+ return get_signal(DATA);
+}
+
+
+//-------------------------------------------------
+// clk_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( econet_device::clk_w )
+{
+ set_signal(this, CLK, state);
+}
+
+
+//-------------------------------------------------
+// data_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( econet_device::data_w )
+{
+ set_signal(this, DATA, state);
+}
+
+
+//-------------------------------------------------
+// clk_w -
+//-------------------------------------------------
+
+void econet_device::clk_w(device_t *device, int state)
+{
+ set_signal(device, CLK, state);
+}
+
+
+//-------------------------------------------------
+// data_w -
+//-------------------------------------------------
+
+void econet_device::data_w(device_t *device, int state)
+{
+ set_signal(device, DATA, state);
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( econet_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( econet_devices )
+ SLOT_INTERFACE("e01", E01)
+ SLOT_INTERFACE("e01s", E01S)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/econet/econet.h b/src/emu/bus/econet/econet.h
new file mode 100644
index 00000000000..d851acdb1d7
--- /dev/null
+++ b/src/emu/bus/econet/econet.h
@@ -0,0 +1,183 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Acorn Computers Econet local area network emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __ECONET__
+#define __ECONET__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define ECONET_TAG "econet"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_ECONET_ADD(_config) \
+ MCFG_DEVICE_ADD(ECONET_TAG, ECONET, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+
+#define ECONET_INTERFACE(_name) \
+ const econet_interface (_name) =
+
+
+#define MCFG_ECONET_SLOT_ADD(_tag, _num, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, ECONET_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+ econet_slot_device::static_set_slot(*device, _num);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> econet_interface
+
+struct econet_interface
+{
+ devcb_write_line m_out_clk_cb;
+ devcb_write_line m_out_data_cb;
+};
+
+
+// ======================> econet_device
+
+class device_econet_interface;
+
+class econet_device : public device_t,
+ public econet_interface
+{
+public:
+ // construction/destruction
+ econet_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ void add_device(device_t *target, int address);
+
+ // reads for both host and peripherals
+ DECLARE_READ_LINE_MEMBER( clk_r );
+ DECLARE_READ_LINE_MEMBER( data_r );
+
+ // writes for host (driver_device)
+ DECLARE_WRITE_LINE_MEMBER( clk_w );
+ DECLARE_WRITE_LINE_MEMBER( data_w );
+
+ // writes for peripherals (device_t)
+ void clk_w(device_t *device, int state);
+ void data_w(device_t *device, int state);
+
+protected:
+ enum
+ {
+ CLK = 0,
+ DATA,
+ SIGNAL_COUNT
+ };
+
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_stop();
+
+ class daisy_entry
+ {
+ public:
+ daisy_entry(device_t *device);
+ daisy_entry *next() const { return m_next; }
+
+ daisy_entry * m_next; // next device
+ device_t * m_device; // associated device
+ device_econet_interface * m_interface; // associated device's daisy interface
+
+ int m_line[SIGNAL_COUNT];
+ };
+
+ simple_list<daisy_entry> m_device_list;
+
+private:
+ devcb_resolved_write_line m_out_clk_func;
+ devcb_resolved_write_line m_out_data_func;
+
+ inline void set_signal(device_t *device, int signal, int state);
+ inline int get_signal(int signal);
+
+ int m_line[SIGNAL_COUNT];
+};
+
+
+// ======================> econet_slot_device
+
+class econet_slot_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ econet_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+
+ // inline configuration
+ static void static_set_slot(device_t &device, int address);
+
+private:
+ // configuration
+ UINT8 m_address;
+ econet_device *m_econet;
+};
+
+
+// ======================> device_econet_interface
+
+class device_econet_interface : public device_slot_card_interface
+{
+ friend class econet_device;
+
+public:
+ // construction/destruction
+ device_econet_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_econet_interface();
+
+ device_econet_interface *next() const { return m_next; }
+ device_econet_interface *m_next;
+
+ // optional operation overrides
+ virtual void econet_clk(int state) = 0;
+ virtual void econet_data(int state) { };
+
+ econet_device *m_econet;
+ UINT8 m_address;
+};
+
+
+// device type definition
+extern const device_type ECONET;
+extern const device_type ECONET_SLOT;
+
+
+// slot devices
+#include "e01.h"
+
+SLOT_INTERFACE_EXTERN( econet_devices );
+
+
+
+#endif
diff --git a/src/emu/bus/ep64/exdos.c b/src/emu/bus/ep64/exdos.c
new file mode 100644
index 00000000000..893e46fc71b
--- /dev/null
+++ b/src/emu/bus/ep64/exdos.c
@@ -0,0 +1,246 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Intelligent Software EXDOS Disk Controller Module emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+Floppy Drive Controller PCB Layout
+----------------------------------
+
+INTELLIGENT SOFTWARE LTD DISK CONTROLLER
+ISS1
+ |--------------------------------------------|
+ | |
+ | |
+|-| 7438 74LS273 WD1770 |
+|I| |
+|D| |
+|C| EPROM.IC2|
+|3| 74LS32 74LS02 74LS266 |
+|4| 7438 |
+|-| 74LS126 74LS10 74LS245 74LS266 |
+ | |
+ | |
+ |----------------------------|||||||||||||||||
+ |---------------|
+Notes: (All IC's shown)
+
+This PCB plugs into the external expansion connector on the right side of the mainboard
+
+ EPROM.IC2 - 16k x8-bit EPROM labelled 'EXDOS V1.0 P/N 08-60' (DIP28)
+ WD1770 - Western Digital WD1770 Floppy Drive Controller (DIP28)
+ 74LS02 - Quad 2-Input NOR Gate (DIP14)
+ 74LS10 - Triple 3-input NAND Gate (DIP14)
+ 74LS32 - Quad 2-Input Positive OR Gate (DIP14)
+ 7438 - Quad 2-input NAND Buffer (DIP14)
+ 74LS126 - Quad Bus Buffer (DIP14)
+ 74LS245 - Octal Bus Tranceiver with Tri-State Outputs (DIP20)
+ 74LS266 - Quad EXCLUSIVE-NOR Gate (DIP14)
+ 74LS273 - Octal D-Type Flip-Flop With Clear (DIP20)
+ IDC34 - IDC 34-way flat cable connector for floppy drive data cable
+
+*/
+
+#include "exdos.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define WD1770_TAG "u1"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type EP64_EXDOS = &device_creator<ep64_exdos_device>;
+
+
+//-------------------------------------------------
+// ROM( ep64_exdos )
+//-------------------------------------------------
+
+ROM_START( ep64_exdos )
+ ROM_REGION( 0x8000, "rom", 0 )
+ ROM_LOAD( "exdos13.rom", 0x0000, 0x8000, CRC(d1d7e157) SHA1(31c8be089526aa8aa019c380cdf51ddd3ee76454) )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *ep64_exdos_device::device_rom_region() const
+{
+ return ROM_NAME( ep64_exdos );
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( ep64_exdos_floppies )
+//-------------------------------------------------
+
+FLOPPY_FORMATS_MEMBER( ep64_exdos_device::floppy_formats )
+ FLOPPY_EP64_FORMAT
+FLOPPY_FORMATS_END
+
+static SLOT_INTERFACE_START( ep64_exdos_floppies )
+ SLOT_INTERFACE( "35dd", FLOPPY_35_DD )
+SLOT_INTERFACE_END
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( ep64_exdos )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( ep64_exdos )
+ MCFG_WD1770x_ADD(WD1770_TAG, XTAL_8MHz)
+
+ MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":0", ep64_exdos_floppies, "35dd", ep64_exdos_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":1", ep64_exdos_floppies, NULL, ep64_exdos_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":2", ep64_exdos_floppies, NULL, ep64_exdos_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(WD1770_TAG":3", ep64_exdos_floppies, NULL, ep64_exdos_device::floppy_formats)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor ep64_exdos_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( ep64_exdos );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// ep64_exdos_device - constructor
+//-------------------------------------------------
+
+ep64_exdos_device::ep64_exdos_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, EP64_EXDOS, "EXDOS", tag, owner, clock, "ep64_exdos", __FILE__),
+ device_ep64_expansion_bus_card_interface(mconfig, *this),
+ m_fdc(*this, WD1770_TAG),
+ m_floppy0(*this, WD1770_TAG":0"),
+ m_floppy1(*this, WD1770_TAG":1"),
+ m_floppy2(*this, WD1770_TAG":2"),
+ m_floppy3(*this, WD1770_TAG":3"),
+ m_floppy(NULL),
+ m_rom(*this, "rom")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void ep64_exdos_device::device_start()
+{
+ m_slot->program().install_rom(0x080000, 0x087fff, 0, 0, m_rom->base());
+
+ m_slot->io().install_readwrite_handler(0x10, 0x13, 0, 0x04, READ8_DEVICE_DELEGATE(m_fdc, wd_fdc_t, read), WRITE8_DEVICE_DELEGATE(m_fdc, wd_fdc_t, write));
+ m_slot->io().install_readwrite_handler(0x18, 0x18, 0, 0x04, READ8_DELEGATE(ep64_exdos_device, read), WRITE8_DELEGATE(ep64_exdos_device, write));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void ep64_exdos_device::device_reset()
+{
+ m_fdc->reset();
+
+ m_floppy = NULL;
+ m_fdc->set_floppy(m_floppy);
+ m_fdc->dden_w(0);
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( ep64_exdos_device::read )
+{
+ /*
+
+ bit description
+
+ 0
+ 1 INTRQ
+ 2
+ 3
+ 4
+ 5
+ 6 DCHG
+ 7 DRQ
+
+ */
+
+ UINT8 data = 0;
+
+ data |= m_fdc->intrq_r() << 1;
+ data |= m_fdc->drq_r() << 7;
+
+ data |= (m_floppy ? m_floppy->dskchg_r() : 1) << 6;
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( ep64_exdos_device::write )
+{
+ /*
+
+ bit description
+
+ 0 SELECT 0
+ 1 SELECT 1
+ 2 SELECT 2
+ 3 SELECT 3
+ 4 SIDE 1
+ 5 _DDEN
+ 6 DISK CHANGE RESET
+ 7 IN USE
+
+ */
+
+ m_floppy = NULL;
+
+ if (BIT(data, 0)) m_floppy = m_floppy0->get_device();
+ if (BIT(data, 1)) m_floppy = m_floppy1->get_device();
+ if (BIT(data, 2)) m_floppy = m_floppy2->get_device();
+ if (BIT(data, 3)) m_floppy = m_floppy3->get_device();
+
+ m_fdc->set_floppy(m_floppy);
+
+ if (m_floppy)
+ {
+ m_floppy->ss_w(BIT(data, 4));
+ }
+
+ m_fdc->dden_w(BIT(data, 5));
+}
diff --git a/src/emu/bus/ep64/exdos.h b/src/emu/bus/ep64/exdos.h
new file mode 100644
index 00000000000..c7fa267710b
--- /dev/null
+++ b/src/emu/bus/ep64/exdos.h
@@ -0,0 +1,67 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Intelligent Software EXDOS Disk Controller Module emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __EP64_EXDOS__
+#define __EP64_EXDOS__
+
+#include "emu.h"
+#include "exp.h"
+#include "formats/ep64_dsk.h"
+#include "machine/wd_fdc.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> ep64_exdos_device
+
+class ep64_exdos_device : public device_t,
+ public device_ep64_expansion_bus_card_interface
+{
+public:
+ // construction/destruction
+ ep64_exdos_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+
+ DECLARE_FLOPPY_FORMATS( floppy_formats );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+private:
+ required_device<wd1770_t> m_fdc;
+ required_device<floppy_connector> m_floppy0;
+ required_device<floppy_connector> m_floppy1;
+ required_device<floppy_connector> m_floppy2;
+ required_device<floppy_connector> m_floppy3;
+ floppy_image_device *m_floppy;
+ required_memory_region m_rom;
+};
+
+
+// device type definition
+extern const device_type EP64_EXDOS;
+
+
+
+#endif
diff --git a/src/emu/bus/ep64/exp.c b/src/emu/bus/ep64/exp.c
new file mode 100644
index 00000000000..c5e0cfb175f
--- /dev/null
+++ b/src/emu/bus/ep64/exp.c
@@ -0,0 +1,90 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Enterprise Sixty Four / One Two Eight Expansion Bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type EP64_EXPANSION_BUS_SLOT = &device_creator<ep64_expansion_bus_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE EP64_EXPANSION_BUS CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_ep64_expansion_bus_card_interface - constructor
+//-------------------------------------------------
+
+device_ep64_expansion_bus_card_interface::device_ep64_expansion_bus_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+ m_slot = dynamic_cast<ep64_expansion_bus_slot_device *>(device.owner());
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// ep64_expansion_bus_slot_device - constructor
+//-------------------------------------------------
+
+ep64_expansion_bus_slot_device::ep64_expansion_bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, EP64_EXPANSION_BUS_SLOT, "Enterprise Sixty Four expansion bus slot", tag, owner, clock, "ep64_expansion_bus_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_write_irq(*this),
+ m_write_nmi(*this),
+ m_write_wait(*this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void ep64_expansion_bus_slot_device::device_start()
+{
+ m_dave = dynamic_cast<dave_device *>(m_owner->subdevice(m_dave_tag));
+ m_card = dynamic_cast<device_ep64_expansion_bus_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_write_irq.resolve_safe();
+ m_write_nmi.resolve_safe();
+ m_write_wait.resolve_safe();
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void ep64_expansion_bus_slot_device::device_reset()
+{
+ if (m_card) get_card_device()->reset();
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( ep64_expansion_bus_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( ep64_expansion_bus_cards )
+ SLOT_INTERFACE("exdos", EP64_EXDOS)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/ep64/exp.h b/src/emu/bus/ep64/exp.h
new file mode 100644
index 00000000000..7f20fbe71db
--- /dev/null
+++ b/src/emu/bus/ep64/exp.h
@@ -0,0 +1,152 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Enterprise Sixty Four / One Two Eight Expansion Bus emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ LH SOUND IN B1 A1 RH SOUND IN
+ _WR B2 A2 _RFSH
+ _IORQ B3 A3 _RD
+ +17V* B4 A4 +17V*
+ _NMI B5 A5 _MREQ
+ A9 B6 A6 A8
+ A11 B7 A7 A10
+ A13 B8 A8 A12
+ A15 B9 A9 A14
+ A1 B10 A10 A0
+ A3 B11 A11 A2
+ A5 B12 A12 A4
+ A7 B13 A13 A6
+ D1 B14 A14 D0
+ D3 B15 A15 D2
+ D5 B16 A16 D4
+ D7 B17 A17 D6
+ _INT B18 A18 _RESET
+ GND B19 A19 _WAIT
+ GND B20 A20 _M1
+ GND B21 A21 1M
+ GND B22 A22 phi
+ GND B23 A23 8M
+ EC1 B24 A24 EC0
+ EC3 B25 A25 EC2
+ A16 B26 A26 _EXTC
+ A18 B27 A27 A17
+ A20 B28 A28 A19
+ 14M B29 A29 A21
+ VSYNC B30 A30 _LOCATE
+ _EXP B31 A31 GND
+ GND B32 A32 HSYNC
+ +9V B33 A33 +9V
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __EP64_EXPANSION_BUS__
+#define __EP64_EXPANSION_BUS__
+
+#include "emu.h"
+#include "audio/dave.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define EP64_EXPANSION_BUS_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_EP64_EXPANSION_BUS_SLOT_ADD(_tag, _dave_tag, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, EP64_EXPANSION_BUS_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(ep64_expansion_bus_cards, _def_slot, false) \
+ downcast<ep64_expansion_bus_slot_device *>(device)->set_dave_tag(_dave_tag);
+
+#define MCFG_EP64_EXPANSION_BUS_CALLBACKS(_irq, _nmi, _wait) \
+ downcast<ep64_expansion_bus_slot_device *>(device)->set_irq_callback(DEVCB2_##_irq); \
+ downcast<ep64_expansion_bus_slot_device *>(device)->set_nmi_callback(DEVCB2_##_nmi); \
+ downcast<ep64_expansion_bus_slot_device *>(device)->set_wait_callback(DEVCB2_##_wait);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> ep64_expansion_bus_slot_device
+
+class device_ep64_expansion_bus_card_interface;
+
+class ep64_expansion_bus_slot_device : public device_t,
+ public device_slot_interface
+{
+ friend class device_ep64_expansion_bus_card_interface;
+
+public:
+ // construction/destruction
+ ep64_expansion_bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ void set_dave_tag(const char* dave_tag) { m_dave_tag = dave_tag; }
+ template<class _irq> void set_irq_callback(_irq irq) { m_write_irq.set_callback(irq); }
+ template<class _nmi> void set_nmi_callback(_nmi nmi) { m_write_nmi.set_callback(nmi); }
+ template<class _wait> void set_wait_callback(_wait wait) { m_write_wait.set_callback(wait); }
+
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_write_irq(state); }
+ DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_write_nmi(state); }
+ DECLARE_WRITE_LINE_MEMBER( wait_w ) { m_write_wait(state); }
+
+ address_space& program() { return m_dave->space(AS_PROGRAM); }
+ address_space& io() { return m_dave->space(AS_IO); }
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+private:
+ devcb2_write_line m_write_irq;
+ devcb2_write_line m_write_nmi;
+ devcb2_write_line m_write_wait;
+
+ const char *m_dave_tag;
+ dave_device *m_dave;
+
+ device_ep64_expansion_bus_card_interface *m_card;
+};
+
+
+// ======================> device_ep64_expansion_bus_card_interface
+
+class device_ep64_expansion_bus_card_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_ep64_expansion_bus_card_interface(const machine_config &mconfig, device_t &device);
+
+protected:
+ ep64_expansion_bus_slot_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type EP64_EXPANSION_BUS_SLOT;
+
+
+// slot devices
+#include "exdos.h"
+
+SLOT_INTERFACE_EXTERN( ep64_expansion_bus_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/pet/64k.c b/src/emu/bus/pet/64k.c
new file mode 100644
index 00000000000..f0057cf6b36
--- /dev/null
+++ b/src/emu/bus/pet/64k.c
@@ -0,0 +1,206 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET 64KB RAM Expansion emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "64k.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type PET_64K = &device_creator<pet_64k_expansion_device>;
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// read_ram -
+//-------------------------------------------------
+
+inline UINT8 pet_64k_expansion_device::read_ram(offs_t offset)
+{
+ UINT8 data = 0;
+
+ if (offset < 0xc000)
+ {
+ data = m_ram[(BIT(m_ctrl, 2) << 14) | (offset & 0x3fff)];
+ }
+ else
+ {
+ data = m_ram[0x8000 | (BIT(m_ctrl, 3) << 14) | (offset & 0x3fff)];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write_ram -
+//-------------------------------------------------
+
+inline void pet_64k_expansion_device::write_ram(offs_t offset, UINT8 data)
+{
+ if (offset < 0xc000)
+ {
+ if (!BIT(m_ctrl, 0))
+ {
+ m_ram[(BIT(m_ctrl, 2) << 14) | (offset & 0x3fff)] = data;
+ }
+ }
+ else
+ {
+ if (!BIT(m_ctrl, 1))
+ {
+ m_ram[0x8000 | (BIT(m_ctrl, 3) << 14) | (offset & 0x3fff)] = data;
+ }
+ }
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// pet_64k_expansion_device - constructor
+//-------------------------------------------------
+
+pet_64k_expansion_device::pet_64k_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PET_64K, "PET 64KB RAM", tag, owner, clock, "pet_64k", __FILE__),
+ device_pet_expansion_card_interface(mconfig, *this),
+ m_ram(*this, "ram"),
+ m_ctrl(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void pet_64k_expansion_device::device_start()
+{
+ // allocate memory
+ m_ram.allocate(0x10000);
+
+ // state saving
+ save_item(NAME(m_ctrl));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void pet_64k_expansion_device::device_reset()
+{
+ m_ctrl = 0;
+}
+
+
+//-------------------------------------------------
+// pet_norom_r - NO ROM read
+//-------------------------------------------------
+
+int pet_64k_expansion_device::pet_norom_r(address_space &space, offs_t offset, int sel)
+{
+ return !BIT(m_ctrl, 7);
+}
+
+
+//-------------------------------------------------
+// pet_bd_r - buffered data read
+//-------------------------------------------------
+
+UINT8 pet_64k_expansion_device::pet_bd_r(address_space &space, offs_t offset, UINT8 data, int &sel)
+{
+ if (BIT(m_ctrl, 7))
+ {
+ switch (sel)
+ {
+ case pet_expansion_slot_device::SEL8:
+ if (!BIT(m_ctrl, 5))
+ {
+ data = read_ram(offset);
+ sel = pet_expansion_slot_device::SEL_NONE;
+ }
+ break;
+
+ case pet_expansion_slot_device::SELE:
+ if (!BIT(m_ctrl, 6) || !BIT(offset, 11))
+ {
+ data = read_ram(offset);
+ sel = pet_expansion_slot_device::SEL_NONE;
+ }
+ break;
+
+ case pet_expansion_slot_device::SEL9:
+ case pet_expansion_slot_device::SELA:
+ case pet_expansion_slot_device::SELB:
+ case pet_expansion_slot_device::SELC:
+ case pet_expansion_slot_device::SELD:
+ case pet_expansion_slot_device::SELF:
+ data = read_ram(offset);
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// pet_bd_w - buffered data write
+//-------------------------------------------------
+
+void pet_64k_expansion_device::pet_bd_w(address_space &space, offs_t offset, UINT8 data, int &sel)
+{
+ if (BIT(m_ctrl, 7))
+ {
+ switch (sel)
+ {
+ case pet_expansion_slot_device::SEL8:
+ if (!BIT(m_ctrl, 5))
+ {
+ write_ram(offset, data);
+ sel = pet_expansion_slot_device::SEL_NONE;
+ }
+ break;
+
+ case pet_expansion_slot_device::SELE:
+ if (!BIT(m_ctrl, 6) || !BIT(offset, 11))
+ {
+ write_ram(offset, data);
+ sel = pet_expansion_slot_device::SEL_NONE;
+ }
+ break;
+
+ case pet_expansion_slot_device::SEL9:
+ case pet_expansion_slot_device::SELA:
+ case pet_expansion_slot_device::SELB:
+ case pet_expansion_slot_device::SELC:
+ case pet_expansion_slot_device::SELD:
+ case pet_expansion_slot_device::SELF:
+ write_ram(offset, data);
+ break;
+ }
+ }
+
+ if (offset == 0xfff0)
+ {
+ m_ctrl = data;
+ }
+}
diff --git a/src/emu/bus/pet/64k.h b/src/emu/bus/pet/64k.h
new file mode 100644
index 00000000000..96971fd83ba
--- /dev/null
+++ b/src/emu/bus/pet/64k.h
@@ -0,0 +1,59 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET 64KB RAM Expansion emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PET_64K__
+#define __PET_64K__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> pet_64k_expansion_device
+
+class pet_64k_expansion_device : public device_t,
+ public device_pet_expansion_card_interface
+{
+public:
+ // construction/destruction
+ pet_64k_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_pet_expansion_card_interface overrides
+ virtual int pet_norom_r(address_space &space, offs_t offset, int sel);
+ virtual UINT8 pet_bd_r(address_space &space, offs_t offset, UINT8 data, int &sel);
+ virtual void pet_bd_w(address_space &space, offs_t offset, UINT8 data, int &sel);
+
+private:
+ inline UINT8 read_ram(offs_t offset);
+ inline void write_ram(offs_t offset, UINT8 data);
+
+ optional_shared_ptr<UINT8> m_ram;
+
+ UINT8 m_ctrl;
+};
+
+
+// device type definition
+extern const device_type PET_64K;
+
+
+#endif
diff --git a/src/emu/bus/pet/c2n.c b/src/emu/bus/pet/c2n.c
new file mode 100644
index 00000000000..ad139e7730d
--- /dev/null
+++ b/src/emu/bus/pet/c2n.c
@@ -0,0 +1,174 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore C2N/1530/1531 Datassette emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "c2n.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type C2N = &device_creator<c2n_device>;
+const device_type C1530 = &device_creator<c1530_device>;
+const device_type C1531 = &device_creator<c1531_device>;
+
+
+//-------------------------------------------------
+// cassette_interface cbm_cassette_interface
+//-------------------------------------------------
+
+const cassette_interface cbm_cassette_interface =
+{
+ cbm_cassette_formats,
+ NULL,
+ (cassette_state) (CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED),
+ "cbm_cass",
+ NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG( c2n )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( c2n )
+ MCFG_CASSETTE_ADD("cassette", cbm_cassette_interface )
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor c2n_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( c2n );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// c2n_device - constructor
+//-------------------------------------------------
+
+c2n_device::c2n_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_pet_datassette_port_interface(mconfig, *this),
+ m_cassette(*this, "cassette"),
+ m_motor(false)
+{
+}
+
+c2n_device::c2n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, C2N, "C2N Datassette", tag, owner, clock, "c2n", __FILE__),
+ device_pet_datassette_port_interface(mconfig, *this),
+ m_cassette(*this, "cassette"),
+ m_motor(false)
+{
+}
+
+
+//-------------------------------------------------
+// c1530_device - constructor
+//-------------------------------------------------
+
+c1530_device::c1530_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : c2n_device(mconfig, C1530, "C1530 Datassette", tag, owner, clock, "c1530", __FILE__) { }
+
+
+//-------------------------------------------------
+// c1531_device - constructor
+//-------------------------------------------------
+
+c1531_device::c1531_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : c2n_device(mconfig, C1531, "C1531 Datassette", tag, owner, clock, "c1531", __FILE__) { }
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void c2n_device::device_start()
+{
+ // allocate timers
+ m_read_timer = timer_alloc();
+ m_read_timer->adjust(attotime::from_hz(44100), 0, attotime::from_hz(44100));
+}
+
+
+//-------------------------------------------------
+// device_timer - handler timer events
+//-------------------------------------------------
+
+void c2n_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if (m_motor)
+ {
+ m_slot->read_w(datassette_read());
+ }
+}
+
+
+//-------------------------------------------------
+// datassette_read - read data
+//-------------------------------------------------
+
+int c2n_device::datassette_read()
+{
+ return (m_cassette->input() > +0.0) ? 1 : 0;
+}
+
+
+//-------------------------------------------------
+// datassette_write - write data
+//-------------------------------------------------
+
+void c2n_device::datassette_write(int state)
+{
+ m_cassette->output(state ? -(0x5a9e >> 1) : +(0x5a9e >> 1));
+}
+
+
+//-------------------------------------------------
+// datassette_sense - switch sense
+//-------------------------------------------------
+
+int c2n_device::datassette_sense()
+{
+ return (m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED;
+}
+
+
+//-------------------------------------------------
+// datassette_motor - motor
+//-------------------------------------------------
+
+void c2n_device::datassette_motor(int state)
+{
+ if (!state)
+ {
+ m_cassette->change_state(CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
+ m_motor = true;
+ }
+ else
+ {
+ m_cassette->change_state(CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
+ m_motor = false;
+ }
+
+ m_slot->read_w(datassette_read());
+}
diff --git a/src/emu/bus/pet/c2n.h b/src/emu/bus/pet/c2n.h
new file mode 100644
index 00000000000..5d2edc746c9
--- /dev/null
+++ b/src/emu/bus/pet/c2n.h
@@ -0,0 +1,89 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore C2N/1530/1531 Datassette emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __C2N__
+#define __C2N__
+
+#include "emu.h"
+#include "cass.h"
+#include "formats/cbm_tap.h"
+#include "imagedev/cassette.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> c2n_device
+
+class c2n_device : public device_t,
+ public device_pet_datassette_port_interface
+{
+public:
+ // construction/destruction
+ c2n_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);
+ c2n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+
+ // device_pet_datassette_port_interface overrides
+ virtual int datassette_read();
+ virtual void datassette_write(int state);
+ virtual int datassette_sense();
+ virtual void datassette_motor(int state);
+
+private:
+ required_device<cassette_image_device> m_cassette;
+
+ bool m_motor;
+
+ // timers
+ emu_timer *m_read_timer;
+};
+
+
+// ======================> c1530_device
+
+class c1530_device : public c2n_device
+{
+public:
+ // construction/destruction
+ c1530_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// ======================> c1531_device
+
+class c1531_device : public c2n_device
+{
+public:
+ // construction/destruction
+ c1531_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+// device type definition
+extern const device_type C2N;
+extern const device_type C1530;
+extern const device_type C1531;
+
+
+
+#endif
diff --git a/src/emu/bus/pet/cass.c b/src/emu/bus/pet/cass.c
new file mode 100644
index 00000000000..8ceb01d7c54
--- /dev/null
+++ b/src/emu/bus/pet/cass.c
@@ -0,0 +1,102 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET/VIC-20/C64/Plus-4 Datassette Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "cass.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type PET_DATASSETTE_PORT = &device_creator<pet_datassette_port_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_pet_datassette_port_interface - constructor
+//-------------------------------------------------
+
+device_pet_datassette_port_interface::device_pet_datassette_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_slot = dynamic_cast<pet_datassette_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_pet_datassette_port_interface - destructor
+//-------------------------------------------------
+
+device_pet_datassette_port_interface::~device_pet_datassette_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// pet_datassette_port_device - constructor
+//-------------------------------------------------
+
+pet_datassette_port_device::pet_datassette_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PET_DATASSETTE_PORT, "Datassette Port", tag, owner, clock, "pet_datassette_port", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_read_handler(*this)
+{
+}
+
+
+//-------------------------------------------------
+// pet_datassette_port_device - destructor
+//-------------------------------------------------
+
+pet_datassette_port_device::~pet_datassette_port_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void pet_datassette_port_device::device_start()
+{
+ m_cart = dynamic_cast<device_pet_datassette_port_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_read_handler.resolve_safe();
+}
+
+
+READ_LINE_MEMBER( pet_datassette_port_device::read ) { int state = 1; if (m_cart != NULL) state = m_cart->datassette_read(); return state; }
+WRITE_LINE_MEMBER( pet_datassette_port_device::write ) { if (m_cart != NULL) m_cart->datassette_write(state); }
+READ_LINE_MEMBER( pet_datassette_port_device::sense_r ) { int state = 1; if (m_cart != NULL) state = m_cart->datassette_sense(); return state; }
+WRITE_LINE_MEMBER( pet_datassette_port_device::motor_w ) { if (m_cart != NULL) m_cart->datassette_motor(state); }
+
+WRITE_LINE_MEMBER( pet_datassette_port_device::read_w ) { m_read_handler(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( cbm_datassette_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( cbm_datassette_devices )
+ SLOT_INTERFACE("c2n", C2N)
+ SLOT_INTERFACE("c1530", C1530)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/pet/cass.h b/src/emu/bus/pet/cass.h
new file mode 100644
index 00000000000..495ed31d195
--- /dev/null
+++ b/src/emu/bus/pet/cass.h
@@ -0,0 +1,120 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET/VIC-20/C64/Plus-4 Datassette Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ +5V 2 B +5V
+ MOTOR 3 C MOTOR
+ READ 4 D READ
+ WRITE 5 E WRITE
+ SENSE 6 F SENSE
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PET_DATASSETTE_PORT__
+#define __PET_DATASSETTE_PORT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define PET_DATASSETTE_PORT_TAG "tape"
+#define PET_DATASSETTE_PORT2_TAG "tape2"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_PET_DATASSETTE_PORT_ADD(_tag, _slot_intf, _def_slot, _devcb) \
+ MCFG_DEVICE_ADD(_tag, PET_DATASSETTE_PORT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+ devcb = &pet_datassette_port_device::set_read_handler(*device, DEVCB2_##_devcb);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> pet_datassette_port_device
+
+class device_pet_datassette_port_interface;
+
+class pet_datassette_port_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ pet_datassette_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~pet_datassette_port_device();
+
+ // static configuration helpers
+ template<class _Object> static devcb2_base &set_read_handler(device_t &device, _Object object) { return downcast<pet_datassette_port_device &>(device).m_read_handler.set_callback(object); }
+
+ // computer interface
+ DECLARE_READ_LINE_MEMBER( read );
+ DECLARE_WRITE_LINE_MEMBER( write );
+ DECLARE_READ_LINE_MEMBER( sense_r );
+ DECLARE_WRITE_LINE_MEMBER( motor_w );
+
+ // device interface
+ DECLARE_WRITE_LINE_MEMBER( read_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ devcb2_write_line m_read_handler;
+
+ device_pet_datassette_port_interface *m_cart;
+};
+
+
+// ======================> device_pet_datassette_port_interface
+
+// class representing interface-specific live c64_expansion card
+class device_pet_datassette_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_pet_datassette_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_pet_datassette_port_interface();
+
+ virtual int datassette_read() { return 1; };
+ virtual void datassette_write(int state) { };
+ virtual int datassette_sense() { return 1; };
+ virtual void datassette_motor(int state) { };
+
+protected:
+ pet_datassette_port_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type PET_DATASSETTE_PORT;
+
+
+// slot devices
+#include "c2n.h"
+#include "diag264_lb_tape.h"
+
+SLOT_INTERFACE_EXTERN( cbm_datassette_devices );
+
+
+
+#endif
diff --git a/src/emu/bus/pet/diag264_lb_tape.c b/src/emu/bus/pet/diag264_lb_tape.c
new file mode 100644
index 00000000000..110fc937a70
--- /dev/null
+++ b/src/emu/bus/pet/diag264_lb_tape.c
@@ -0,0 +1,86 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Diag264 Cassette Loop Back Connector emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "diag264_lb_tape.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type DIAG264_CASSETTE_LOOPBACK = &device_creator<diag264_cassette_loopback_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// diag264_cassette_loopback_device - constructor
+//-------------------------------------------------
+
+diag264_cassette_loopback_device::diag264_cassette_loopback_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, DIAG264_CASSETTE_LOOPBACK, "Diag264 Cassette Loopback", tag, owner, clock, "diag264_loopback_cassette", __FILE__),
+ device_pet_datassette_port_interface(mconfig, *this),
+ m_read(1),
+ m_sense(0)
+{ }
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void diag264_cassette_loopback_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// datassette_read - read data
+//-------------------------------------------------
+
+int diag264_cassette_loopback_device::datassette_read()
+{
+ return m_read;
+}
+
+
+//-------------------------------------------------
+// datassette_write - write data
+//-------------------------------------------------
+
+void diag264_cassette_loopback_device::datassette_write(int state)
+{
+ m_read = state;
+}
+
+
+//-------------------------------------------------
+// datassette_sense - switch sense
+//-------------------------------------------------
+
+int diag264_cassette_loopback_device::datassette_sense()
+{
+ return m_sense;
+}
+
+
+//-------------------------------------------------
+// datassette_motor - motor
+//-------------------------------------------------
+
+void diag264_cassette_loopback_device::datassette_motor(int state)
+{
+ m_sense = !state;
+}
diff --git a/src/emu/bus/pet/diag264_lb_tape.h b/src/emu/bus/pet/diag264_lb_tape.h
new file mode 100644
index 00000000000..8fc749e66fc
--- /dev/null
+++ b/src/emu/bus/pet/diag264_lb_tape.h
@@ -0,0 +1,56 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Diag264 Cassette Loop Back Connector emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __DIAG264_CASSETTE_LOOPBACK__
+#define __DIAG264_CASSETTE_LOOPBACK__
+
+#include "emu.h"
+#include "cass.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> diag264_cassette_loopback_device
+
+class diag264_cassette_loopback_device : public device_t,
+ public device_pet_datassette_port_interface
+{
+public:
+ // construction/destruction
+ diag264_cassette_loopback_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_pet_datassette_port_interface overrides
+ virtual int datassette_read();
+ virtual void datassette_write(int state);
+ virtual int datassette_sense();
+ virtual void datassette_motor(int state);
+
+private:
+ int m_read;
+ int m_sense;
+};
+
+
+// device type definition
+extern const device_type DIAG264_CASSETTE_LOOPBACK;
+
+
+
+#endif
diff --git a/src/emu/bus/pet/exp.c b/src/emu/bus/pet/exp.c
new file mode 100644
index 00000000000..33f2ccef16a
--- /dev/null
+++ b/src/emu/bus/pet/exp.c
@@ -0,0 +1,200 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET Memory Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type PET_EXPANSION_SLOT = &device_creator<pet_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// pet_expansion_slot_device - constructor
+//-------------------------------------------------
+
+pet_expansion_slot_device::pet_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PET_EXPANSION_SLOT, "PET memory expansion port", tag, owner, clock, "pet_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_read_dma(*this),
+ m_write_dma(*this)
+{
+}
+
+
+//-------------------------------------------------
+// pet_expansion_slot_device - destructor
+//-------------------------------------------------
+
+pet_expansion_slot_device::~pet_expansion_slot_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_pet_expansion_card_interface - constructor
+//-------------------------------------------------
+
+device_pet_expansion_card_interface::device_pet_expansion_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+ m_slot = dynamic_cast<pet_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_pet_expansion_card_interface - destructor
+//-------------------------------------------------
+
+device_pet_expansion_card_interface::~device_pet_expansion_card_interface()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void pet_expansion_slot_device::device_start()
+{
+ m_card = dynamic_cast<device_pet_expansion_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_read_dma.resolve_safe(0);
+ m_write_dma.resolve_safe();
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void pet_expansion_slot_device::device_reset()
+{
+ if (m_card != NULL)
+ {
+ get_card_device()->reset();
+ }
+}
+
+
+//-------------------------------------------------
+// norom_r - NO ROM read
+//-------------------------------------------------
+
+int pet_expansion_slot_device::norom_r(address_space &space, offs_t offset, int sel)
+{
+ return m_card ? m_card->pet_norom_r(space, offset, sel) : 1;
+}
+
+
+//-------------------------------------------------
+// read - buffered data read
+//-------------------------------------------------
+
+UINT8 pet_expansion_slot_device::read(address_space &space, offs_t offset, UINT8 data, int &sel)
+{
+ if (m_card != NULL)
+ {
+ data = m_card->pet_bd_r(space, offset, data, sel);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write - buffered data write
+//-------------------------------------------------
+
+void pet_expansion_slot_device::write(address_space &space, offs_t offset, UINT8 data, int &sel)
+{
+ if (m_card != NULL)
+ {
+ m_card->pet_bd_w(space, offset, data, sel);
+ }
+}
+
+
+//-------------------------------------------------
+// diag_r - DIAG read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( pet_expansion_slot_device::diag_r )
+{
+ return m_card ? m_card->pet_diag_r() : 1;
+}
+
+
+//-------------------------------------------------
+// irq_w - IRQ write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( pet_expansion_slot_device::irq_w )
+{
+ if (m_card) m_card->pet_irq_w(state);
+}
+
+
+//-------------------------------------------------
+// dma_bd_r - DMA read
+//-------------------------------------------------
+
+UINT8 pet_expansion_slot_device::dma_bd_r(offs_t offset)
+{
+ return m_read_dma(offset);
+}
+
+
+//-------------------------------------------------
+// dma_bd_w - DMA write
+//-------------------------------------------------
+
+void pet_expansion_slot_device::dma_bd_w(offs_t offset, UINT8 data)
+{
+ m_write_dma(offset, data);
+}
+
+
+//-------------------------------------------------
+// phi2 - system clock frequency
+//-------------------------------------------------
+
+int pet_expansion_slot_device::phi2()
+{
+ return clock();
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( pet_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( pet_expansion_cards )
+ SLOT_INTERFACE("64k", PET_64K)
+ SLOT_INTERFACE("superpet", SUPERPET)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/pet/exp.h b/src/emu/bus/pet/exp.h
new file mode 100644
index 00000000000..a871a53c8a2
--- /dev/null
+++ b/src/emu/bus/pet/exp.h
@@ -0,0 +1,146 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET Memory Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PET_EXPANSION_SLOT__
+#define __PET_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define PET_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_PET_EXPANSION_SLOT_ADD(_tag, _clock, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, PET_EXPANSION_SLOT, _clock) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+#define MCFG_PET_EXPANSION_SLOT_DMA_CALLBACKS(_read, _write) \
+ downcast<pet_expansion_slot_device *>(device)->set_callbacks(DEVCB2_##_read, DEVCB2_##_write);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> pet_expansion_slot_device
+
+class device_pet_expansion_card_interface;
+
+class pet_expansion_slot_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ pet_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~pet_expansion_slot_device();
+
+ template<class _read, class _write> void set_callbacks(_read rd, _write wr) {
+ m_read_dma.set_callback(rd);
+ m_write_dma.set_callback(wr);
+ }
+
+ // computer interface
+ int norom_r(address_space &space, offs_t offset, int sel);
+ UINT8 read(address_space &space, offs_t offset, UINT8 data, int &sel);
+ void write(address_space &space, offs_t offset, UINT8 data, int &sel);
+ DECLARE_READ_LINE_MEMBER( diag_r );
+ DECLARE_WRITE_LINE_MEMBER( irq_w );
+
+ // cartridge interface
+ UINT8 dma_bd_r(offs_t offset);
+ void dma_bd_w(offs_t offset, UINT8 data);
+ int phi2();
+
+ enum
+ {
+ SEL_NONE = -1,
+ SEL0 = 0,
+ SEL1,
+ SEL2,
+ SEL3,
+ SEL4,
+ SEL5,
+ SEL6,
+ SEL7,
+ SEL8,
+ SEL9,
+ SELA,
+ SELB,
+ SELC,
+ SELD,
+ SELE,
+ SELF
+ };
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ device_pet_expansion_card_interface *m_card;
+
+ devcb2_read8 m_read_dma;
+ devcb2_write8 m_write_dma;
+};
+
+
+// ======================> device_pet_expansion_card_interface
+
+class device_pet_expansion_card_interface : public device_slot_card_interface
+{
+ friend class pet_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_pet_expansion_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_pet_expansion_card_interface();
+
+protected:
+ // runtime
+ virtual int pet_norom_r(address_space &space, offs_t offset, int sel) { return 1; }
+ virtual UINT8 pet_bd_r(address_space &space, offs_t offset, UINT8 data, int &sel) { return data; };
+ virtual void pet_bd_w(address_space &space, offs_t offset, UINT8 data, int &sel) { };
+ virtual int pet_diag_r() { return 1; }
+ virtual void pet_irq_w(int state) { }
+
+ pet_expansion_slot_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type PET_EXPANSION_SLOT;
+
+
+// slot devices
+#include "64k.h"
+#include "superpet.h"
+
+SLOT_INTERFACE_EXTERN( pet_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/pet/superpet.c b/src/emu/bus/pet/superpet.c
new file mode 100644
index 00000000000..cf8f5f7b3bf
--- /dev/null
+++ b/src/emu/bus/pet/superpet.c
@@ -0,0 +1,445 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore SuperPET emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "superpet.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define M6809_TAG "u4"
+#define MOS6551_TAG "u23"
+#define MOS6702_TAG "u2"
+#define RS232_TAG "rs232"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SUPERPET = &device_creator<superpet_device>;
+
+
+//-------------------------------------------------
+// ROM( superpet )
+//-------------------------------------------------
+
+ROM_START( superpet )
+ ROM_REGION( 0x7000, M6809_TAG, 0 )
+ ROM_LOAD( "901898-01.u17", 0x1000, 0x1000, CRC(728a998b) SHA1(0414b3ab847c8977eb05c2fcc72efcf2f9d92871) )
+ ROM_LOAD( "901898-02.u18", 0x2000, 0x1000, CRC(6beb7c62) SHA1(df154939b934d0aeeb376813ec1ba0d43c2a3378) )
+ ROM_LOAD( "901898-03.u19", 0x3000, 0x1000, CRC(5db4983d) SHA1(6c5b0cce97068f8841112ba6d5cd8e568b562fa3) )
+ ROM_LOAD( "901898-04.u20", 0x4000, 0x1000, CRC(f55fc559) SHA1(b42a2050a319a1ffca7868a8d8d635fadd37ec37) )
+ ROM_LOAD( "901897-01.u21", 0x5000, 0x0800, CRC(b2cee903) SHA1(e8ce8347451a001214a5e71a13081b38b4be23bc) )
+ ROM_LOAD( "901898-05.u22", 0x6000, 0x1000, CRC(f42df0cb) SHA1(9b4a5134d20345171e7303445f87c4e0b9addc96) )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *superpet_device::device_rom_region() const
+{
+ return ROM_NAME( superpet );
+}
+
+
+//-------------------------------------------------
+// rs232_port_interface rs232_intf
+//-------------------------------------------------
+
+static const rs232_port_interface rs232_intf =
+{
+ DEVCB_DEVICE_LINE_MEMBER(MOS6551_TAG, mos6551_device, rxd_w),
+ DEVCB_DEVICE_LINE_MEMBER(MOS6551_TAG, mos6551_device, dcd_w),
+ DEVCB_DEVICE_LINE_MEMBER(MOS6551_TAG, mos6551_device, dsr_w),
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(MOS6551_TAG, mos6551_device, cts_w)
+};
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( superpet_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( superpet_mem, AS_PROGRAM, 8, superpet_device )
+ AM_RANGE(0x0000, 0xffff) AM_READWRITE(read, write)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( superpet )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( superpet )
+ MCFG_CPU_ADD(M6809_TAG, M6809, XTAL_16MHz/16)
+ MCFG_CPU_PROGRAM_MAP(superpet_mem)
+
+ MCFG_MOS6702_ADD(MOS6702_TAG, XTAL_16MHz/16)
+
+ MCFG_MOS6551_ADD(MOS6551_TAG, XTAL_1_8432MHz, WRITELINE(superpet_device, acia_irq_w))
+ MCFG_MOS6551_RXD_TXD_CALLBACKS(NULL, DEVWRITELINE(RS232_TAG, rs232_port_device, tx))
+
+ MCFG_RS232_PORT_ADD(RS232_TAG, rs232_intf, default_rs232_devices, NULL)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor superpet_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( superpet );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( superpet )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( superpet )
+ PORT_START("SW1")
+ PORT_DIPNAME( 0x03, 0x02, "RAM" )
+ PORT_DIPSETTING( 0x00, "Read Only" )
+ PORT_DIPSETTING( 0x01, "Read/Write" )
+ PORT_DIPSETTING( 0x02, "System Port" )
+
+ PORT_START("SW2")
+ PORT_DIPNAME( 0x03, 0x02, "CPU" )
+ PORT_DIPSETTING( 0x00, "6809" )
+ PORT_DIPSETTING( 0x01, "6502" )
+ PORT_DIPSETTING( 0x02, "System Port" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor superpet_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( superpet );
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// update_cpu -
+//-------------------------------------------------
+
+inline void superpet_device::update_cpu()
+{
+ int cpu = (m_sw2 == 2) ? BIT(m_system, 0) : m_sw2;
+
+ if (cpu)
+ {
+ // 6502 active
+ m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
+ machine().firstcpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
+ }
+ else
+ {
+ // 6809 active
+ m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
+ machine().firstcpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
+ }
+}
+
+
+//-------------------------------------------------
+// is_ram_writable -
+//-------------------------------------------------
+
+inline bool superpet_device::is_ram_writable()
+{
+ return (m_sw1 == 2) ? BIT(m_system, 1) : m_sw1;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// superpet_device - constructor
+//-------------------------------------------------
+
+superpet_device::superpet_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SUPERPET, "SuperPET", tag, owner, clock, "pet_superpet", __FILE__),
+ device_pet_expansion_card_interface(mconfig, *this),
+ m_maincpu(*this, M6809_TAG),
+ m_acia(*this, MOS6551_TAG),
+ m_dongle(*this, MOS6702_TAG),
+ m_rom(*this, M6809_TAG),
+ m_ram(*this, "ram"),
+ m_io_sw1(*this, "SW1"),
+ m_io_sw2(*this, "SW2"),
+ m_system(0),
+ m_bank(0),
+ m_sel9_rom(0),
+ m_pet_irq(CLEAR_LINE),
+ m_acia_irq(CLEAR_LINE)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void superpet_device::device_start()
+{
+ // allocate memory
+ m_ram.allocate(0x10000);
+
+ // state saving
+ save_item(NAME(m_system));
+ save_item(NAME(m_bank));
+ save_item(NAME(m_sel9_rom));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void superpet_device::device_reset()
+{
+ m_maincpu->reset();
+ m_acia->reset();
+ m_dongle->reset();
+
+ m_system = 0;
+ m_bank = 0;
+ m_sel9_rom = 0;
+ m_sw1 = m_io_sw1->read();
+ m_sw2 = m_io_sw2->read();
+
+ update_cpu();
+}
+
+
+//-------------------------------------------------
+// pet_norom_r - NO ROM read
+//-------------------------------------------------
+
+int superpet_device::pet_norom_r(address_space &space, offs_t offset, int sel)
+{
+ return BIT(m_system, 0);
+}
+
+
+//-------------------------------------------------
+// pet_bd_r - buffered data read
+//-------------------------------------------------
+
+UINT8 superpet_device::pet_bd_r(address_space &space, offs_t offset, UINT8 data, int &sel)
+{
+ int norom = pet_norom_r(space, offset, sel);
+
+ switch (sel)
+ {
+ case pet_expansion_slot_device::SEL9:
+ if (m_sel9_rom)
+ {
+ data = m_rom->base()[offset - 0x9000];
+ }
+ else
+ {
+ data = m_ram[((m_bank & 0x0f) << 12) | (offset & 0xfff)];
+ }
+ break;
+
+ case pet_expansion_slot_device::SELA:
+ case pet_expansion_slot_device::SELB:
+ case pet_expansion_slot_device::SELC:
+ case pet_expansion_slot_device::SELD:
+ case pet_expansion_slot_device::SELF:
+ if (!norom)
+ {
+ data = m_rom->base()[offset - 0x9000];
+ }
+ break;
+
+ case pet_expansion_slot_device::SELE:
+ if (!norom && !BIT(offset, 11))
+ {
+ data = m_rom->base()[offset - 0x9000];
+ }
+ break;
+ }
+
+ switch (offset)
+ {
+ case 0xefe0:
+ case 0xefe1:
+ case 0xefe2:
+ case 0xefe3:
+ data = m_dongle->read(space, offset & 0x03);
+ break;
+
+ case 0xeff0:
+ case 0xeff1:
+ case 0xeff2:
+ case 0xeff3:
+ data = m_acia->read(space, offset & 0x03);
+ break;
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// pet_bd_w - buffered data write
+//-------------------------------------------------
+
+void superpet_device::pet_bd_w(address_space &space, offs_t offset, UINT8 data, int &sel)
+{
+ switch (sel)
+ {
+ case pet_expansion_slot_device::SEL9:
+ if (!m_sel9_rom && is_ram_writable())
+ {
+ m_ram[((m_bank & 0x0f) << 12) | (offset & 0xfff)] = data;
+ }
+ break;
+ }
+
+ switch (offset)
+ {
+ case 0xefe0:
+ case 0xefe1:
+ case 0xefe2:
+ case 0xefe3:
+ m_dongle->write(space, offset & 0x03, data);
+ printf("6702 %u %02x\n", offset & 0x03, data);
+ break;
+
+ case 0xeff0:
+ case 0xeff1:
+ case 0xeff2:
+ case 0xeff3:
+ m_acia->write(space, offset & 0x03, data);
+ break;
+
+ case 0xeff8:
+ case 0xeff9:
+ if (BIT(m_bank, 7))
+ {
+ /*
+
+ bit description
+
+ 0 SW2 CPU (0=6809, 1=6502)
+ 1 SW1 RAM (0=read only, 1=read/write)
+ 2
+ 3 DIAG
+ 4
+ 5
+ 6
+ 7
+
+ */
+
+ m_system = data;
+ update_cpu();
+ printf("SYSTEM %02x\n", data);
+ }
+ break;
+
+ case 0xeffc:
+ case 0xeffd:
+ /*
+
+ bit description
+
+ 0 A0
+ 1 A1
+ 2 A2
+ 3 SEL A
+ 4 J1 pin 40
+ 5 SEL B
+ 6 J1 pin 39
+ 7 BIT 7
+
+ */
+
+ m_bank = data;
+ printf("BANK %02x\n", data);
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// pet_diag_r - DIAG read
+//-------------------------------------------------
+
+int superpet_device::pet_diag_r()
+{
+ return BIT(m_system, 3);
+}
+
+
+//-------------------------------------------------
+// pet_irq_w - IRQ write
+//-------------------------------------------------
+
+void superpet_device::pet_irq_w(int state)
+{
+ m_pet_irq = state;
+
+ //m_maincpu->set_input_line(M6809_IRQ_LINE, m_pet_irq || m_acia_irq);
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( superpet_device::read )
+{
+ return m_slot->dma_bd_r(offset);
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( superpet_device::write )
+{
+ m_slot->dma_bd_w(offset, data);
+}
+
+
+//-------------------------------------------------
+// acia_irq_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( superpet_device::acia_irq_w )
+{
+ m_acia_irq = state;
+
+ //m_maincpu->set_input_line(M6809_IRQ_LINE, m_pet_irq || m_acia_irq);
+}
diff --git a/src/emu/bus/pet/superpet.h b/src/emu/bus/pet/superpet.h
new file mode 100644
index 00000000000..3aa21a6d33b
--- /dev/null
+++ b/src/emu/bus/pet/superpet.h
@@ -0,0 +1,86 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore SuperPET emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __SUPERPET__
+#define __SUPERPET__
+
+#include "emu.h"
+#include "exp.h"
+#include "cpu/m6809/m6809.h"
+#include "machine/mos6551.h"
+#include "machine/mos6702.h"
+#include "machine/serial.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> superpet_device
+
+class superpet_device : public device_t,
+ public device_pet_expansion_card_interface
+{
+public:
+ // construction/destruction
+ superpet_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_WRITE_LINE_MEMBER( acia_irq_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_pet_expansion_card_interface overrides
+ virtual int pet_norom_r(address_space &space, offs_t offset, int sel);
+ virtual UINT8 pet_bd_r(address_space &space, offs_t offset, UINT8 data, int &sel);
+ virtual void pet_bd_w(address_space &space, offs_t offset, UINT8 data, int &sel);
+ virtual int pet_diag_r();
+ virtual void pet_irq_w(int state);
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<mos6551_device> m_acia;
+ required_device<mos6702_device> m_dongle;
+ required_memory_region m_rom;
+ optional_shared_ptr<UINT8> m_ram;
+ required_ioport m_io_sw1;
+ required_ioport m_io_sw2;
+
+ inline void update_cpu();
+ inline bool is_ram_writable();
+
+ UINT8 m_system;
+ UINT8 m_bank;
+ UINT8 m_sw1;
+ UINT8 m_sw2;
+ int m_sel9_rom;
+ int m_pet_irq;
+ int m_acia_irq;
+};
+
+
+// device type definition
+extern const device_type SUPERPET;
+
+
+#endif
diff --git a/src/emu/bus/pet/user.c b/src/emu/bus/pet/user.c
new file mode 100644
index 00000000000..14a87ea9e21
--- /dev/null
+++ b/src/emu/bus/pet/user.c
@@ -0,0 +1,124 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "user.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type PET_USER_PORT = &device_creator<pet_user_port_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_pet_user_port_interface - constructor
+//-------------------------------------------------
+
+device_pet_user_port_interface::device_pet_user_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_slot = dynamic_cast<pet_user_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_pet_user_port_interface - destructor
+//-------------------------------------------------
+
+device_pet_user_port_interface::~device_pet_user_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// pet_user_port_device - constructor
+//-------------------------------------------------
+
+pet_user_port_device::pet_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PET_USER_PORT, "PET user port", tag, owner, clock, "pet_user_port", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void pet_user_port_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const pet_user_port_interface *intf = reinterpret_cast<const pet_user_port_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<pet_user_port_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_ca1_cb, 0, sizeof(m_out_ca1_cb));
+ memset(&m_out_cb2_cb, 0, sizeof(m_out_cb2_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void pet_user_port_device::device_start()
+{
+ m_card = dynamic_cast<device_pet_user_port_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_out_ca1_func.resolve(m_out_ca1_cb, *this);
+ m_out_cb2_func.resolve(m_out_cb2_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void pet_user_port_device::device_reset()
+{
+}
+
+
+READ8_MEMBER( pet_user_port_device::pa_r ) { UINT8 data = 0xff; if (m_card != NULL) data = m_card->pet_pa_r(space, offset); return data; }
+WRITE8_MEMBER( pet_user_port_device::pa_w ) { if (m_card != NULL) m_card->pet_pa_w(space, offset, data); }
+READ_LINE_MEMBER( pet_user_port_device::ca1_r ) { int state = 1; if (m_card != NULL) state = m_card->pet_ca1_r(); return state; }
+WRITE_LINE_MEMBER( pet_user_port_device::ca1_w ) { if (m_card != NULL) m_card->pet_ca1_w(state); }
+READ_LINE_MEMBER( pet_user_port_device::cb2_r ) { int state = 1; if (m_card != NULL) state = m_card->pet_cb2_r(); return state; }
+WRITE_LINE_MEMBER( pet_user_port_device::cb2_w ) { if (m_card != NULL) m_card->pet_cb2_w(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( pet_user_port_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( pet_user_port_cards )
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/pet/user.h b/src/emu/bus/pet/user.h
new file mode 100644
index 00000000000..585268eb913
--- /dev/null
+++ b/src/emu/bus/pet/user.h
@@ -0,0 +1,141 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore PET User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ VIDEO 2 B CA1
+ _SRQ IN 3 C PA0
+ EOI 4 D PA1
+ DIAG 5 E PA2
+ #2 CASS READ 6 F PA3
+ CASS WRITE 7 H PA4
+ #1 CASS READ 8 J PA5
+ VERT DRIVE 9 K PA6
+ HORZ DRIVE 10 L PA7
+ GND 11 M CB2
+ GND 12 N GND
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PET_USER_PORT__
+#define __PET_USER_PORT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define PET_USER_PORT_TAG "user"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define PET_USER_PORT_INTERFACE(_name) \
+ const pet_user_port_interface (_name) =
+
+
+#define MCFG_PET_USER_PORT_ADD(_tag, _config, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, PET_USER_PORT, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> pet_user_port_interface
+
+struct pet_user_port_interface
+{
+ devcb_write_line m_out_ca1_cb;
+ devcb_write_line m_out_cb2_cb;
+};
+
+
+// ======================> pet_user_port_device
+
+class device_pet_user_port_interface;
+
+class pet_user_port_device : public device_t,
+ public pet_user_port_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ pet_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // computer interface
+ DECLARE_READ8_MEMBER( pa_r );
+ DECLARE_WRITE8_MEMBER( pa_w );
+ DECLARE_READ_LINE_MEMBER( ca1_r );
+ DECLARE_WRITE_LINE_MEMBER( ca1_w );
+ DECLARE_READ_LINE_MEMBER( cb2_r );
+ DECLARE_WRITE_LINE_MEMBER( cb2_w );
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( via_ca1_w ) { m_out_ca1_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( via_cb2_w ) { m_out_cb2_func(state); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+
+ devcb_resolved_write_line m_out_ca1_func;
+ devcb_resolved_write_line m_out_cb2_func;
+
+ device_pet_user_port_interface *m_card;
+};
+
+
+// ======================> device_pet_user_port_interface
+
+// class representing interface-specific live pet_expansion card
+class device_pet_user_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_pet_user_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_pet_user_port_interface();
+
+ virtual UINT8 pet_pa_r(address_space &space, offs_t offset) { return 0xff; };
+ virtual void pet_pa_w(address_space &space, offs_t offset, UINT8 data) { };
+
+ virtual int pet_ca1_r() { return 1; };
+ virtual void pet_ca1_w(int state) { };
+ virtual int pet_cb2_r() { return 1; };
+ virtual void pet_cb2_w(int state) { };
+
+protected:
+ pet_user_port_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type PET_USER_PORT;
+
+
+// slot devices
+SLOT_INTERFACE_EXTERN( pet_user_port_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/plus4/c1551.c b/src/emu/bus/plus4/c1551.c
new file mode 100644
index 00000000000..56cb71d2adf
--- /dev/null
+++ b/src/emu/bus/plus4/c1551.c
@@ -0,0 +1,598 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore 1551 Single Disk Drive emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "c1551.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define M6510T_TAG "u2"
+#define M6523_0_TAG "u3"
+#define M6523_1_TAG "ci_u2"
+#define C64H156_TAG "u6"
+#define PLA_TAG "u1"
+
+
+enum
+{
+ LED_POWER = 0,
+ LED_ACT
+};
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type C1551 = &device_creator<c1551_device>;
+
+
+//-------------------------------------------------
+// ROM( c1551 )
+//-------------------------------------------------
+
+ROM_START( c1551 ) // schematic 251860
+ ROM_REGION( 0x4000, M6510T_TAG, 0 )
+ ROM_LOAD( "318001-01.u4", 0x0000, 0x4000, CRC(6d16d024) SHA1(fae3c788ad9a6cc2dbdfbcf6c0264b2ca921d55e) )
+
+ ROM_REGION( 0xf5, PLA_TAG, 0 ) // schematic 251925
+ ROM_LOAD( "251641-03.u1", 0x00, 0xf5, NO_DUMP )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *c1551_device::device_rom_region() const
+{
+ return ROM_NAME( c1551 );
+}
+
+
+//-------------------------------------------------
+// M6510_INTERFACE( cpu_intf )
+//-------------------------------------------------
+
+READ8_MEMBER( c1551_device::port_r )
+{
+ /*
+
+ bit description
+
+ P0
+ P1
+ P2
+ P3
+ P4 WPS
+ P5
+ P6
+ P7 BYTE LTCHED
+
+ */
+
+ UINT8 data = 0;
+
+ // write protect sense
+ data |= !floppy_wpt_r(m_image) << 4;
+
+ // byte latched
+ data |= m_ga->atn_r() << 7;
+
+ return data;
+}
+
+WRITE8_MEMBER( c1551_device::port_w )
+{
+ /*
+
+ bit description
+
+ P0 STP0A
+ P1 STP0B
+ P2 MTR0
+ P3 ACT0
+ P4
+ P5 DS0
+ P6 DS1
+ P7
+
+ */
+
+ // stepper motor
+ m_ga->stp_w(data & 0x03);
+
+ // spindle motor
+ m_ga->mtr_w(BIT(data, 2));
+
+ // activity LED
+ output_set_led_value(LED_ACT, BIT(data, 3));
+
+ // density select
+ m_ga->ds_w((data >> 5) & 0x03);
+}
+
+//-------------------------------------------------
+// tpi6525_interface tpi0_intf
+//-------------------------------------------------
+
+READ8_MEMBER( c1551_device::tcbm_data_r )
+{
+ /*
+
+ bit description
+
+ PA0 TCBM PA0
+ PA1 TCBM PA1
+ PA2 TCBM PA2
+ PA3 TCBM PA3
+ PA4 TCBM PA4
+ PA5 TCBM PA5
+ PA6 TCBM PA6
+ PA7 TCBM PA7
+
+ */
+
+ return m_tcbm_data;
+}
+
+WRITE8_MEMBER( c1551_device::tcbm_data_w )
+{
+ /*
+
+ bit description
+
+ PA0 TCBM PA0
+ PA1 TCBM PA1
+ PA2 TCBM PA2
+ PA3 TCBM PA3
+ PA4 TCBM PA4
+ PA5 TCBM PA5
+ PA6 TCBM PA6
+ PA7 TCBM PA7
+
+ */
+
+ m_tcbm_data = data;
+}
+
+READ8_MEMBER( c1551_device::tpi0_r )
+{
+ UINT8 data = m_tpi0->read(space, offset);
+
+ m_ga->ted_w(0);
+ m_ga->ted_w(1);
+
+ return data;
+}
+
+WRITE8_MEMBER( c1551_device::tpi0_w )
+{
+ m_tpi0->write(space, offset, data);
+
+ m_ga->ted_w(0);
+ m_ga->ted_w(1);
+}
+
+READ8_MEMBER( c1551_device::tpi0_pc_r )
+{
+ /*
+
+ bit description
+
+ PC0
+ PC1
+ PC2
+ PC3
+ PC4
+ PC5 JP1
+ PC6 _SYNC
+ PC7 TCBM DAV
+
+ */
+
+ UINT8 data = 0;
+
+ // JP1
+ data |= m_jp1->read() << 5;
+
+ // SYNC detect line
+ data |= m_ga->sync_r() << 6;
+
+ // TCBM data valid
+ data |= m_dav << 7;
+
+ return data;
+}
+
+WRITE8_MEMBER( c1551_device::tpi0_pc_w )
+{
+ /*
+
+ bit description
+
+ PC0 TCBM STATUS0
+ PC1 TCBM STATUS1
+ PC2 TCBM DEV
+ PC3 TCBM ACK
+ PC4 MODE
+ PC5
+ PC6
+ PC7
+
+ */
+
+ // TCBM status
+ m_status = data & 0x03;
+
+ // TCBM device number
+ m_dev = BIT(data, 2);
+
+ // TCBM acknowledge
+ m_ack = BIT(data, 3);
+
+ // read/write mode
+ m_ga->oe_w(BIT(data, 4));
+}
+
+static const tpi6525_interface tpi0_intf =
+{
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tcbm_data_r),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tcbm_data_w),
+ DEVCB_DEVICE_MEMBER(C64H156_TAG, c64h156_device, yb_r),
+ DEVCB_DEVICE_MEMBER(C64H156_TAG, c64h156_device, yb_w),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tpi0_pc_r),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tpi0_pc_w),
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// tpi6525_interface tpi1_intf
+//-------------------------------------------------
+
+READ8_MEMBER( c1551_device::tpi1_pb_r )
+{
+ /*
+
+ bit description
+
+ PB0 STATUS0
+ PB1 STATUS1
+ PB2
+ PB3
+ PB4
+ PB5
+ PB6
+ PB7
+
+ */
+
+ return m_status & 0x03;
+}
+
+READ8_MEMBER( c1551_device::tpi1_pc_r )
+{
+ /*
+
+ bit description
+
+ PC0
+ PC1
+ PC2
+ PC3
+ PC4
+ PC5
+ PC6
+ PC7 TCBM ACK
+
+ */
+
+ UINT8 data = 0;
+
+ // TCBM acknowledge
+ data |= m_ack << 7;
+
+ return data;
+}
+
+WRITE8_MEMBER( c1551_device::tpi1_pc_w )
+{
+ /*
+
+ bit description
+
+ PC0
+ PC1
+ PC2
+ PC3
+ PC4
+ PC5
+ PC6 TCBM DAV
+ PC7
+
+ */
+
+ // TCBM data valid
+ m_dav = BIT(data, 6);
+}
+
+static const tpi6525_interface tpi1_intf =
+{
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tcbm_data_r),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tcbm_data_w),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tpi1_pb_r),
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tpi1_pc_r),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1551_device, tpi1_pc_w),
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( c1551_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( c1551_mem, AS_PROGRAM, 8, c1551_device )
+ AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x0800) AM_RAM
+ AM_RANGE(0x4000, 0x4007) AM_MIRROR(0x3ff8) AM_READWRITE(tpi0_r, tpi0_w)
+ AM_RANGE(0xc000, 0xffff) AM_ROM AM_REGION(M6510T_TAG, 0)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// C64H156_INTERFACE( ga_intf )
+//-------------------------------------------------
+
+static C64H156_INTERFACE( ga_intf )
+{
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF, c64h156_device, atni_w)
+};
+
+
+//-------------------------------------------------
+// LEGACY_FLOPPY_OPTIONS( c1541 )
+//-------------------------------------------------
+
+static LEGACY_FLOPPY_OPTIONS_START( c1541 )
+ LEGACY_FLOPPY_OPTION( c1541, "g64", "Commodore 1541 GCR Disk Image", g64_dsk_identify, g64_dsk_construct, NULL, NULL )
+ LEGACY_FLOPPY_OPTION( c1541, "d64", "Commodore 1541 Disk Image", d64_dsk_identify, d64_dsk_construct, NULL, NULL )
+LEGACY_FLOPPY_OPTIONS_END
+
+
+//-------------------------------------------------
+// floppy_interface c1551_floppy_interface
+//-------------------------------------------------
+
+static const floppy_interface c1551_floppy_interface =
+{
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ FLOPPY_STANDARD_5_25_SSDD,
+ LEGACY_FLOPPY_OPTIONS_NAME(c1541),
+ "floppy_5_25",
+ NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( c1551 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( c1551 )
+ MCFG_CPU_ADD(M6510T_TAG, M6510T, XTAL_16MHz/8)
+ MCFG_CPU_PROGRAM_MAP(c1551_mem)
+ MCFG_M6510T_PORT_CALLBACKS(READ8(c1551_device, port_r), WRITE8(c1551_device, port_w))
+ MCFG_QUANTUM_PERFECT_CPU(M6510T_TAG)
+
+ MCFG_PLS100_ADD(PLA_TAG)
+ MCFG_TPI6525_ADD(M6523_0_TAG, tpi0_intf)
+ MCFG_TPI6525_ADD(M6523_1_TAG, tpi1_intf)
+
+ MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, c1551_floppy_interface)
+ MCFG_64H156_ADD(C64H156_TAG, XTAL_16MHz, ga_intf)
+
+ MCFG_PLUS4_PASSTHRU_EXPANSION_SLOT_ADD()
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor c1551_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( c1551 );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( c1551 )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( c1551 )
+ PORT_START("JP1")
+ PORT_DIPNAME( 0x01, 0x00, "Device Number" )
+ PORT_DIPSETTING( 0x00, "8" )
+ PORT_DIPSETTING( 0x01, "9" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor c1551_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( c1551 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// c1551_device - constructor
+//-------------------------------------------------
+
+c1551_device::c1551_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, C1551, "C1551", tag, owner, clock, "c1551", __FILE__),
+ device_plus4_expansion_card_interface(mconfig, *this),
+ m_maincpu(*this, M6510T_TAG),
+ m_tpi0(*this, M6523_0_TAG),
+ m_tpi1(*this, M6523_1_TAG),
+ m_ga(*this, C64H156_TAG),
+ m_pla(*this, PLA_TAG),
+ m_image(*this, FLOPPY_0),
+ m_exp(*this, PLUS4_EXPANSION_SLOT_TAG),
+ m_jp1(*this, "JP1"),
+ m_tcbm_data(0xff),
+ m_status(1),
+ m_dav(1),
+ m_ack(1),
+ m_dev(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void c1551_device::device_start()
+{
+ // allocate timers
+ m_irq_timer = timer_alloc();
+ m_irq_timer->adjust(attotime::zero, CLEAR_LINE);
+
+ // install image callbacks
+ m_ga->set_floppy(m_image);
+
+ // register for state saving
+ save_item(NAME(m_tcbm_data));
+ save_item(NAME(m_status));
+ save_item(NAME(m_dav));
+ save_item(NAME(m_ack));
+ save_item(NAME(m_dev));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void c1551_device::device_reset()
+{
+ m_maincpu->reset();
+
+ m_tpi0->reset();
+
+ m_exp->reset();
+
+ // initialize gate array
+ m_ga->test_w(1);
+ m_ga->soe_w(1);
+ m_ga->accl_w(1);
+ m_ga->atna_w(1);
+}
+
+
+//-------------------------------------------------
+// device_timer - handler timer events
+//-------------------------------------------------
+
+void c1551_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_maincpu->set_input_line(M6502_IRQ_LINE, param);
+
+ if (param == ASSERT_LINE)
+ {
+ // Ts = 0.7*R2*C1 = 0.7*100R*0.1uF = 7us
+ m_irq_timer->adjust(attotime::from_usec(7), CLEAR_LINE);
+ }
+ else
+ {
+ // Tm = 0.7*(R1+R2)*C1 = 0.7*(120K+100R)*0.1uF = 0.008407s
+ m_irq_timer->adjust(attotime::from_usec(8407), ASSERT_LINE);
+ }
+}
+
+
+//-------------------------------------------------
+// tpi1_selected -
+//-------------------------------------------------
+
+bool c1551_device::tpi1_selected(offs_t offset)
+{
+#ifdef PLA_DUMPED
+ int mux = 0, ras = 0, phi0 = 0, f7 = 0;
+ UINT16 input = A5 << 15 | A6 << 14 | A7 << 13 | A8 << 12 | A9 << 11 | mux << 10 | A10 << 9 | m_dev << 8 | ras << 7 | phi0 << 6 | A15 << 5 | A14 << 4 | A13 << 3 | A12 << 2 | A11 << 1 | f7;
+ UINT8 data = m_pla->read(input);
+ return BIT(data, 0) ? true : false;
+#endif
+
+ offs_t start_address = m_dev ? 0xfee0 : 0xfec0;
+
+ if (offset >= start_address && offset < (start_address + 0x20))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+//-------------------------------------------------
+// plus4_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 c1551_device::plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ data = m_exp->cd_r(space, offset, data, ba, cs0, c1l, c2l, cs1, c1h, c2h);
+
+ if (tpi1_selected(offset))
+ {
+ data = m_tpi1->read(space, offset & 0x07);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// plus4_cd_w - cartridge data write
+//-------------------------------------------------
+
+void c1551_device::plus4_cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ if (tpi1_selected(offset))
+ {
+ m_tpi1->write(space, offset & 0x07, data);
+ }
+
+ m_exp->cd_w(space, offset, data, ba, cs0, c1l, c2l, cs1, c1h, c2h);
+}
diff --git a/src/emu/bus/plus4/c1551.h b/src/emu/bus/plus4/c1551.h
new file mode 100644
index 00000000000..7090b962a68
--- /dev/null
+++ b/src/emu/bus/plus4/c1551.h
@@ -0,0 +1,106 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore 1551 Single Disk Drive emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __C1551__
+#define __C1551__
+
+
+#include "emu.h"
+#include "exp.h"
+#include "cpu/m6502/m6510t.h"
+#include "imagedev/flopdrv.h"
+#include "formats/d64_dsk.h"
+#include "formats/g64_dsk.h"
+#include "machine/64h156.h"
+#include "machine/6525tpi.h"
+#include "machine/pla.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> c1551_device
+
+class c1551_device : public device_t,
+ public device_plus4_expansion_card_interface
+{
+public:
+ // construction/destruction
+ c1551_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual ioport_constructor device_input_ports() const;
+
+ DECLARE_READ8_MEMBER( port_r );
+ DECLARE_WRITE8_MEMBER( port_w );
+
+ DECLARE_READ8_MEMBER( tcbm_data_r );
+ DECLARE_WRITE8_MEMBER( tcbm_data_w );
+ DECLARE_READ8_MEMBER( tpi0_r );
+ DECLARE_WRITE8_MEMBER( tpi0_w );
+ DECLARE_READ8_MEMBER( yb_r );
+ DECLARE_WRITE8_MEMBER( yb_w );
+ DECLARE_READ8_MEMBER( tpi0_pc_r );
+ DECLARE_WRITE8_MEMBER( tpi0_pc_w );
+
+ DECLARE_READ8_MEMBER( tpi1_pa_r );
+ DECLARE_WRITE8_MEMBER( tpi1_pa_w );
+ DECLARE_READ8_MEMBER( tpi1_pb_r );
+ DECLARE_READ8_MEMBER( tpi1_pc_r );
+ DECLARE_WRITE8_MEMBER( tpi1_pc_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+
+ // device_plus4_expansion_card_interface overrides
+ virtual UINT8 plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+ virtual void plus4_cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+
+private:
+ bool tpi1_selected(offs_t offset);
+
+ required_device<m6510t_device> m_maincpu;
+ required_device<tpi6525_device> m_tpi0;
+ required_device<tpi6525_device> m_tpi1;
+ required_device<c64h156_device> m_ga;
+ required_device<pls100_device> m_pla;
+ required_device<legacy_floppy_image_device> m_image;
+ required_device<plus4_expansion_slot_device> m_exp;
+ required_ioport m_jp1;
+
+ // TCBM bus
+ UINT8 m_tcbm_data; // data
+ int m_status; // status
+ int m_dav; // data valid
+ int m_ack; // acknowledge
+ int m_dev; // device number
+
+ // timers
+ emu_timer *m_irq_timer;
+};
+
+
+
+// device type definition
+extern const device_type C1551;
+
+
+
+#endif
diff --git a/src/emu/bus/plus4/diag264_lb_user.c b/src/emu/bus/plus4/diag264_lb_user.c
new file mode 100644
index 00000000000..747ce877082
--- /dev/null
+++ b/src/emu/bus/plus4/diag264_lb_user.c
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Diag264 User Port Loop Back Connector emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "diag264_lb_user.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type DIAG264_USER_PORT_LOOPBACK = &device_creator<diag264_user_port_loopback_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// diag264_user_port_loopback_device - constructor
+//-------------------------------------------------
+
+diag264_user_port_loopback_device::diag264_user_port_loopback_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, DIAG264_USER_PORT_LOOPBACK, "Diag264 User Port Loopback", tag, owner, clock, "diag264_user_port_loopback", __FILE__),
+ device_plus4_user_port_interface(mconfig, *this),
+ m_p(0),
+ m_txd(0),
+ m_rts(0),
+ m_dtr(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void diag264_user_port_loopback_device::device_start()
+{
+}
diff --git a/src/emu/bus/plus4/diag264_lb_user.h b/src/emu/bus/plus4/diag264_lb_user.h
new file mode 100644
index 00000000000..70e86634369
--- /dev/null
+++ b/src/emu/bus/plus4/diag264_lb_user.h
@@ -0,0 +1,63 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Diag264 User Port Loop Back Connector emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __DIAG264_USER_PORT_LOOPBACK__
+#define __DIAG264_USER_PORT_LOOPBACK__
+
+#include "emu.h"
+#include "user.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> diag264_user_port_loopback_device
+
+class diag264_user_port_loopback_device : public device_t,
+ public device_plus4_user_port_interface
+{
+public:
+ // construction/destruction
+ diag264_user_port_loopback_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_plus4_user_port_interface overrides
+ virtual UINT8 plus4_p_r() { logerror("P read %02x\n", ((m_p << 4) & 0xf0) | (m_p >> 4)); return ((m_p << 4) & 0xf0) | (m_p >> 4); }
+ virtual void plus4_p_w(UINT8 data) { logerror("P write %02x\n", data); m_p = data; }
+ virtual int plus4_rxd_r() { return m_txd; }
+ virtual int plus4_dcd_r() { return m_dtr; }
+ virtual int plus4_dsr_r() { return m_rts; }
+ virtual void plus4_txd_w(int state) { m_txd = state; }
+ virtual void plus4_dtr_w(int state) { m_dtr = state; }
+ virtual void plus4_rts_w(int state) { m_rts = state; }
+
+private:
+ UINT8 m_p;
+
+ int m_txd;
+ int m_rts;
+ int m_dtr;
+};
+
+
+// device type definition
+extern const device_type DIAG264_USER_PORT_LOOPBACK;
+
+
+
+#endif
diff --git a/src/emu/bus/plus4/exp.c b/src/emu/bus/plus4/exp.c
new file mode 100644
index 00000000000..5be58be399e
--- /dev/null
+++ b/src/emu/bus/plus4/exp.c
@@ -0,0 +1,329 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type PLUS4_EXPANSION_SLOT = &device_creator<plus4_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE PLUS4_EXPANSION CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_plus4_expansion_card_interface - constructor
+//-------------------------------------------------
+
+device_plus4_expansion_card_interface::device_plus4_expansion_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_c1l(NULL),
+ m_c1h(NULL),
+ m_c2l(NULL),
+ m_c2h(NULL),
+ m_ram(NULL),
+ m_nvram(NULL),
+ m_nvram_size(0),
+ m_c1l_mask(0),
+ m_c1h_mask(0),
+ m_c2l_mask(0),
+ m_c2h_mask(0),
+ m_ram_mask(0)
+{
+ m_slot = dynamic_cast<plus4_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_plus4_expansion_card_interface - destructor
+//-------------------------------------------------
+
+device_plus4_expansion_card_interface::~device_plus4_expansion_card_interface()
+{
+}
+
+
+//-------------------------------------------------
+// plus4_c1l_pointer - get low ROM 1 pointer
+//-------------------------------------------------
+
+UINT8* device_plus4_expansion_card_interface::plus4_c1l_pointer(running_machine &machine, size_t size)
+{
+ if (m_c1l == NULL)
+ {
+ m_c1l = auto_alloc_array(machine, UINT8, size);
+
+ m_c1l_mask = size - 1;
+ }
+
+ return m_c1l;
+}
+
+
+//-------------------------------------------------
+// plus4_c1h_pointer - get low ROM 1 pointer
+//-------------------------------------------------
+
+UINT8* device_plus4_expansion_card_interface::plus4_c1h_pointer(running_machine &machine, size_t size)
+{
+ if (m_c1h == NULL)
+ {
+ m_c1h = auto_alloc_array(machine, UINT8, size);
+
+ m_c1h_mask = size - 1;
+ }
+
+ return m_c1h;
+}
+
+
+//-------------------------------------------------
+// plus4_c2l_pointer - get low ROM 1 pointer
+//-------------------------------------------------
+
+UINT8* device_plus4_expansion_card_interface::plus4_c2l_pointer(running_machine &machine, size_t size)
+{
+ if (m_c2l == NULL)
+ {
+ m_c2l = auto_alloc_array(machine, UINT8, size);
+
+ m_c2l_mask = size - 1;
+ }
+
+ return m_c2l;
+}
+
+
+//-------------------------------------------------
+// plus4_c2h_pointer - get low ROM 1 pointer
+//-------------------------------------------------
+
+UINT8* device_plus4_expansion_card_interface::plus4_c2h_pointer(running_machine &machine, size_t size)
+{
+ if (m_c2h == NULL)
+ {
+ m_c2h = auto_alloc_array(machine, UINT8, size);
+
+ m_c2h_mask = size - 1;
+ }
+
+ return m_c2h;
+}
+
+
+//-------------------------------------------------
+// plus4_ram_pointer - get RAM pointer
+//-------------------------------------------------
+
+UINT8* device_plus4_expansion_card_interface::plus4_ram_pointer(running_machine &machine, size_t size)
+{
+ if (m_ram == NULL)
+ {
+ m_ram = auto_alloc_array(machine, UINT8, size);
+
+ m_ram_mask = size - 1;
+ }
+
+ return m_ram;
+}
+
+
+//-------------------------------------------------
+// plus4_ram_pointer - get NVRAM pointer
+//-------------------------------------------------
+
+UINT8* device_plus4_expansion_card_interface::plus4_nvram_pointer(running_machine &machine, size_t size)
+{
+ if (m_nvram == NULL)
+ {
+ m_nvram = auto_alloc_array(machine, UINT8, size);
+
+ m_nvram_mask = size - 1;
+ m_nvram_size = size;
+ }
+
+ return m_nvram;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// plus4_expansion_slot_device - constructor
+//-------------------------------------------------
+
+plus4_expansion_slot_device::plus4_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PLUS4_EXPANSION_SLOT, "Expansion Port", tag, owner, clock, "plus4_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ device_image_interface(mconfig, *this),
+ m_write_irq(*this),
+ m_read_dma_cd(*this),
+ m_write_dma_cd(*this),
+ m_write_aec(*this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void plus4_expansion_slot_device::device_start()
+{
+ m_card = dynamic_cast<device_plus4_expansion_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_write_irq.resolve_safe();
+ m_read_dma_cd.resolve_safe(0xff);
+ m_write_dma_cd.resolve_safe();
+ m_write_aec.resolve_safe();
+
+ // inherit bus clock
+ if (clock() == 0)
+ {
+ plus4_expansion_slot_device *root = machine().device<plus4_expansion_slot_device>(PLUS4_EXPANSION_SLOT_TAG);
+ assert(root);
+ set_unscaled_clock(root->clock());
+ }
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void plus4_expansion_slot_device::device_reset()
+{
+ if (get_card_device())
+ {
+ get_card_device()->reset();
+ }
+}
+
+
+//-------------------------------------------------
+// call_load -
+//-------------------------------------------------
+
+bool plus4_expansion_slot_device::call_load()
+{
+ if (m_card)
+ {
+ size_t size = 0;
+
+ if (software_entry() == NULL)
+ {
+ // TODO
+ }
+ else
+ {
+ size = get_software_region_length("c1l");
+ if (size) memcpy(m_card->plus4_c1l_pointer(machine(), size), get_software_region("c1l"), size);
+
+ size = get_software_region_length("c1h");
+ if (size) memcpy(m_card->plus4_c1h_pointer(machine(), size), get_software_region("c1h"), size);
+
+ size = get_software_region_length("c2l");
+ if (size) memcpy(m_card->plus4_c2l_pointer(machine(), size), get_software_region("c2l"), size);
+
+ size = get_software_region_length("c2h");
+ if (size) memcpy(m_card->plus4_c2h_pointer(machine(), size), get_software_region("c2h"), size);
+
+ size = get_software_region_length("ram");
+ if (size) memset(m_card->plus4_ram_pointer(machine(), size), 0, size);
+
+ size = get_software_region_length("nvram");
+ if (size) memset(m_card->plus4_nvram_pointer(machine(), size), 0, size);
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+//-------------------------------------------------
+// call_softlist_load -
+//-------------------------------------------------
+
+bool plus4_expansion_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
+{
+ load_software_part_region(this, swlist, swname, start_entry);
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// get_default_card_software -
+//-------------------------------------------------
+
+const char * plus4_expansion_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
+{
+ return software_get_default_slot(config, options, this, "standard");
+}
+
+
+//-------------------------------------------------
+// cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 plus4_expansion_slot_device::cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ if (m_card != NULL)
+ {
+ data = m_card->plus4_cd_r(space, offset, data, ba, cs0, c1l, c1h, cs1, c2l, c2h);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cd_w - cartridge data write
+//-------------------------------------------------
+
+void plus4_expansion_slot_device::cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ if (m_card != NULL)
+ {
+ m_card->plus4_cd_w(space, offset, data, ba, cs0, c1l, c1h, cs1, c2l, c2h);
+ }
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( plus4_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( plus4_expansion_cards )
+ SLOT_INTERFACE("c1551", C1551)
+ SLOT_INTERFACE("sid", PLUS4_SID)
+
+ // the following need ROMs from the software list
+ SLOT_INTERFACE_INTERNAL("standard", PLUS4_STD)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/plus4/exp.h b/src/emu/bus/plus4/exp.h
new file mode 100644
index 00000000000..153d1d57331
--- /dev/null
+++ b/src/emu/bus/plus4/exp.h
@@ -0,0 +1,201 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ +5V 2 B C1 LOW
+ +5V 3 C _BRESET
+ _IRQ 4 D _RAS
+ R/_W 5 E phi0
+ C1 HIGH 6 F A15
+ C2 LOW 7 H A14
+ C2 HIGH 8 J A13
+ _CS1 9 K A12
+ _CS0 10 L A11
+ _CAS 11 M A10
+ MUX 12 N A9
+ BA 13 P A8
+ D7 14 R A7
+ D6 15 S A6
+ D5 16 T A5
+ D4 17 U A4
+ D3 18 V A3
+ D2 19 W A2
+ D1 20 X A1
+ D0 21 Y A0
+ AEC 22 Z N.C. (RAMEN)
+ EXT AUDIO 23 AA N.C.
+ phi2 24 BB N.C.
+ GND 25 CC GND
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PLUS4_EXPANSION_SLOT__
+#define __PLUS4_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define PLUS4_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_PLUS4_EXPANSION_SLOT_ADD(_tag, _clock, _slot_intf, _def_slot, _irq) \
+ MCFG_DEVICE_ADD(_tag, PLUS4_EXPANSION_SLOT, _clock) \
+ downcast<plus4_expansion_slot_device *>(device)->set_irq_callback(DEVCB2_##_irq); \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+#define MCFG_PLUS4_PASSTHRU_EXPANSION_SLOT_ADD() \
+ MCFG_PLUS4_EXPANSION_SLOT_ADD(PLUS4_EXPANSION_SLOT_TAG, 0, plus4_expansion_cards, NULL, DEVWRITELINE(DEVICE_SELF_OWNER, plus4_expansion_slot_device, irq_w)) \
+ MCFG_PLUS4_EXPANSION_SLOT_DMA_CALLBACKS(DEVREAD8(DEVICE_SELF_OWNER, plus4_expansion_slot_device, dma_cd_r), DEVWRITE8(DEVICE_SELF_OWNER, plus4_expansion_slot_device, dma_cd_w), DEVWRITELINE(DEVICE_SELF_OWNER, plus4_expansion_slot_device, aec_w))
+
+
+#define MCFG_PLUS4_EXPANSION_SLOT_DMA_CALLBACKS(_read, _write, _aec) \
+ downcast<plus4_expansion_slot_device *>(device)->set_dma_callbacks(DEVCB2_##_read, DEVCB2_##_write, DEVCB2_##_aec);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> plus4_expansion_slot_device
+
+class device_plus4_expansion_card_interface;
+
+class plus4_expansion_slot_device : public device_t,
+ public device_slot_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ plus4_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ template<class _irq> void set_irq_callback(_irq irq) { m_write_irq.set_callback(irq); }
+
+ template<class _read, class _write, class _aec> void set_dma_callbacks(_read read, _write write, _aec aec) {
+ m_read_dma_cd.set_callback(read);
+ m_write_dma_cd.set_callback(write);
+ m_write_aec.set_callback(aec);
+ }
+
+ // computer interface
+ UINT8 cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+ void cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+
+ // cartridge interface
+ DECLARE_READ8_MEMBER( dma_cd_r ) { return m_read_dma_cd(offset); }
+ DECLARE_WRITE8_MEMBER( dma_cd_w ) { m_write_dma_cd(offset, data); }
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_write_irq(state); }
+ DECLARE_WRITE_LINE_MEMBER( aec_w ) { m_write_aec(state); }
+ int phi2() { return clock(); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete() { update_names(); }
+ virtual void device_start();
+ virtual void device_reset();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
+
+ 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 char *image_interface() const { return "plus4_cart"; }
+ virtual const char *file_extensions() const { return "rom,bin"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // slot interface overrides
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
+
+ devcb2_write_line m_write_irq;
+ devcb2_read8 m_read_dma_cd;
+ devcb2_write8 m_write_dma_cd;
+ devcb2_write_line m_write_aec;
+
+ device_plus4_expansion_card_interface *m_card;
+};
+
+
+// ======================> device_plus4_expansion_card_interface
+
+class device_plus4_expansion_card_interface : public device_slot_card_interface
+{
+ friend class plus4_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_plus4_expansion_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_plus4_expansion_card_interface();
+
+ // initialization
+ virtual UINT8* plus4_c1l_pointer(running_machine &machine, size_t size);
+ virtual UINT8* plus4_c1h_pointer(running_machine &machine, size_t size);
+ virtual UINT8* plus4_c2l_pointer(running_machine &machine, size_t size);
+ virtual UINT8* plus4_c2h_pointer(running_machine &machine, size_t size);
+ virtual UINT8* plus4_ram_pointer(running_machine &machine, size_t size);
+ virtual UINT8* plus4_nvram_pointer(running_machine &machine, size_t size);
+
+ // runtime
+ virtual UINT8 plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h) { return data; };
+ virtual void plus4_cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h) { };
+
+protected:
+ plus4_expansion_slot_device *m_slot;
+
+ UINT8 *m_c1l;
+ UINT8 *m_c1h;
+ UINT8 *m_c2l;
+ UINT8 *m_c2h;
+ UINT8 *m_ram;
+ UINT8 *m_nvram;
+
+ size_t m_nvram_size;
+
+ size_t m_c1l_mask;
+ size_t m_c1h_mask;
+ size_t m_c2l_mask;
+ size_t m_c2h_mask;
+ size_t m_ram_mask;
+ size_t m_nvram_mask;
+};
+
+
+// device type definition
+extern const device_type PLUS4_EXPANSION_SLOT;
+
+
+// slot devices
+#include "c1551.h"
+#include "sid.h"
+#include "std.h"
+
+SLOT_INTERFACE_EXTERN( plus4_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/plus4/sid.c b/src/emu/bus/plus4/sid.c
new file mode 100644
index 00000000000..a5e0a7a6ac9
--- /dev/null
+++ b/src/emu/bus/plus4/sid.c
@@ -0,0 +1,168 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 SID cartridge emulation
+
+ http://solder.dyndns.info/cgi-bin/showdir.pl?dir=files/commodore/plus4/hardware/SID-Card
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ - GAL16V8 dump
+ - get SID clock from expansion port
+
+*/
+
+#include "sid.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define MOS8580_TAG "mos8580"
+#define CONTROL1_TAG "joy1"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type PLUS4_SID = &device_creator<plus4_sid_cartridge_device>;
+
+
+//-------------------------------------------------
+// ROM( plus4_sid )
+//-------------------------------------------------
+
+ROM_START( plus4_sid )
+ ROM_REGION( 0x100, "pld", 0 )
+ ROM_LOAD( "gal16v8", 0x000, 0x100, NO_DUMP )
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *plus4_sid_cartridge_device::device_rom_region() const
+{
+ return ROM_NAME( plus4_sid );
+}
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG_FRAGMENT( plus4_sid )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( plus4_sid )
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(MOS8580_TAG, MOS8580, XTAL_17_73447MHz/20)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+ MCFG_SOUND_ADD("dac", DAC, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
+
+ MCFG_VCS_CONTROL_PORT_ADD(CONTROL1_TAG, vcs_control_port_devices, NULL)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor plus4_sid_cartridge_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( plus4_sid );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// plus4_sid_cartridge_device - constructor
+//-------------------------------------------------
+
+plus4_sid_cartridge_device::plus4_sid_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PLUS4_SID, "Plus/4 SID cartridge", tag, owner, clock, "plus4_sid", __FILE__),
+ device_plus4_expansion_card_interface(mconfig, *this),
+ m_sid(*this, MOS8580_TAG),
+ m_joy(*this, CONTROL1_TAG)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void plus4_sid_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void plus4_sid_cartridge_device::device_reset()
+{
+ m_sid->reset();
+}
+
+
+//-------------------------------------------------
+// plus4_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 plus4_sid_cartridge_device::plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ if ((offset >= 0xfe80 && offset < 0xfea0) || (offset >= 0xfd40 && offset < 0xfd60))
+ {
+ data = m_sid->read(space, offset & 0x1f);
+ }
+ else if (offset >= 0xfd80 && offset < 0xfd90)
+ {
+ data = m_joy->joy_r(space, 0);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// plus4_cd_w - cartridge data write
+//-------------------------------------------------
+
+void plus4_sid_cartridge_device::plus4_cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ if ((offset >= 0xfe80 && offset < 0xfea0) || (offset >= 0xfd40 && offset < 0xfd60))
+ {
+ m_sid->write(space, offset & 0x1f, data);
+ }
+}
+
+
+//-------------------------------------------------
+// plus4_breset_w - buffered reset write
+//-------------------------------------------------
+
+void plus4_sid_cartridge_device::plus4_breset_w(int state)
+{
+ if (state == ASSERT_LINE)
+ {
+ device_reset();
+ }
+}
diff --git a/src/emu/bus/plus4/sid.h b/src/emu/bus/plus4/sid.h
new file mode 100644
index 00000000000..830a2fe0f42
--- /dev/null
+++ b/src/emu/bus/plus4/sid.h
@@ -0,0 +1,62 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 SID cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PLUS4_SID_CARTRIDGE__
+#define __PLUS4_SID_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+#include "bus/vcs/ctrl.h"
+#include "sound/dac.h"
+#include "sound/mos6581.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> plus4_sid_cartridge_device
+
+class plus4_sid_cartridge_device : public device_t,
+ public device_plus4_expansion_card_interface
+{
+public:
+ // construction/destruction
+ plus4_sid_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_plus4_expansion_card_interface overrides
+ virtual UINT8 plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+ virtual void plus4_cd_w(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+ virtual void plus4_breset_w(int state);
+
+private:
+ required_device<mos6581_device> m_sid;
+ required_device<vcs_control_port_device> m_joy;
+};
+
+
+// device type definition
+extern const device_type PLUS4_SID;
+
+
+#endif
diff --git a/src/emu/bus/plus4/std.c b/src/emu/bus/plus4/std.c
new file mode 100644
index 00000000000..39174d183d1
--- /dev/null
+++ b/src/emu/bus/plus4/std.c
@@ -0,0 +1,72 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 standard cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "std.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type PLUS4_STD = &device_creator<plus4_standard_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// plus4_standard_cartridge_device - constructor
+//-------------------------------------------------
+
+plus4_standard_cartridge_device::plus4_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PLUS4_STD, "Plus/4 standard cartridge", tag, owner, clock, "plus4_standard", __FILE__),
+ device_plus4_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void plus4_standard_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// plus4_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 plus4_standard_cartridge_device::plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h)
+{
+ if (!c1l && m_c1l_mask)
+ {
+ data = m_c1l[offset & m_c1l_mask];
+ }
+ else if (!c1h && m_c1h_mask)
+ {
+ data = m_c1h[offset & m_c1h_mask];
+ }
+ else if (!c2l && m_c2l_mask)
+ {
+ data = m_c2l[offset & m_c2l_mask];
+ }
+ else if (!c2h && m_c2h_mask)
+ {
+ data = m_c2h[offset & m_c2h_mask];
+ }
+
+ return data;
+}
diff --git a/src/emu/bus/plus4/std.h b/src/emu/bus/plus4/std.h
new file mode 100644
index 00000000000..6a50a762ce2
--- /dev/null
+++ b/src/emu/bus/plus4/std.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 standard cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PLUS4_STANDARD_CARTRIDGE__
+#define __PLUS4_STANDARD_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+#include "imagedev/cartslot.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> plus4_standard_cartridge_device
+
+class plus4_standard_cartridge_device : public device_t,
+ public device_plus4_expansion_card_interface
+{
+public:
+ // construction/destruction
+ plus4_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_plus4_expansion_card_interface overrides
+ virtual UINT8 plus4_cd_r(address_space &space, offs_t offset, UINT8 data, int ba, int cs0, int c1l, int c2l, int cs1, int c1h, int c2h);
+};
+
+
+// device type definition
+extern const device_type PLUS4_STD;
+
+
+#endif
diff --git a/src/emu/bus/plus4/user.c b/src/emu/bus/plus4/user.c
new file mode 100644
index 00000000000..89dedda4dab
--- /dev/null
+++ b/src/emu/bus/plus4/user.c
@@ -0,0 +1,105 @@
+/**********************************************************************
+
+ Commodore Plus/4 User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "user.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type PLUS4_USER_PORT = &device_creator<plus4_user_port_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_plus4_user_port_interface - constructor
+//-------------------------------------------------
+
+device_plus4_user_port_interface::device_plus4_user_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_slot = dynamic_cast<plus4_user_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_plus4_user_port_interface - destructor
+//-------------------------------------------------
+
+device_plus4_user_port_interface::~device_plus4_user_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// plus4_user_port_device - constructor
+//-------------------------------------------------
+
+plus4_user_port_device::plus4_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, PLUS4_USER_PORT, "User Port", tag, owner, clock, "plus4_user_port", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void plus4_user_port_device::device_start()
+{
+ m_cart = dynamic_cast<device_plus4_user_port_interface *>(get_card_device());
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void plus4_user_port_device::device_reset()
+{
+ if (get_card_device())
+ {
+ get_card_device()->reset();
+ }
+}
+
+
+READ8_MEMBER( plus4_user_port_device::p_r ) { UINT8 data = 0xff; if (m_cart != NULL) data = m_cart->plus4_p_r(); return data; }
+WRITE8_MEMBER( plus4_user_port_device::p_w ) { if (m_cart != NULL) m_cart->plus4_p_w(data); }
+
+READ_LINE_MEMBER( plus4_user_port_device::rxd_r ) { int state = 1; if (m_cart != NULL) state = m_cart->plus4_rxd_r(); return state; }
+READ_LINE_MEMBER( plus4_user_port_device::dcd_r ) { int state = 1; if (m_cart != NULL) state = m_cart->plus4_dcd_r(); return state; }
+READ_LINE_MEMBER( plus4_user_port_device::dsr_r ) { int state = 1; if (m_cart != NULL) state = m_cart->plus4_dsr_r(); return state; }
+
+WRITE_LINE_MEMBER( plus4_user_port_device::txd_w ) { if (m_cart != NULL) m_cart->plus4_txd_w(state); }
+WRITE_LINE_MEMBER( plus4_user_port_device::dtr_w ) { if (m_cart != NULL) m_cart->plus4_dtr_w(state); }
+WRITE_LINE_MEMBER( plus4_user_port_device::rts_w ) { if (m_cart != NULL) m_cart->plus4_rts_w(state); }
+WRITE_LINE_MEMBER( plus4_user_port_device::rxc_w ) { if (m_cart != NULL) m_cart->plus4_rxc_w(state); }
+WRITE_LINE_MEMBER( plus4_user_port_device::atn_w ) { if (m_cart != NULL) m_cart->plus4_atn_w(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( plus4_user_port_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( plus4_user_port_cards )
+ SLOT_INTERFACE("diag264", DIAG264_USER_PORT_LOOPBACK)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/plus4/user.h b/src/emu/bus/plus4/user.h
new file mode 100644
index 00000000000..0f948356cd6
--- /dev/null
+++ b/src/emu/bus/plus4/user.h
@@ -0,0 +1,129 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore Plus/4 User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ +5V 2 B P0
+ _BRESET 3 C RxD
+ P2 4 D RTS
+ P3 5 E DTR
+ P4 6 F P7
+ P5 7 H DCD
+ P0 8 J P6
+ ATN 9 K P1
+ +9VAC 10 L DSR
+ +9VAC 11 M TxD
+ GND 12 N GND
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __PLUS4_USER_PORT__
+#define __PLUS4_USER_PORT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define PLUS4_USER_PORT_TAG "user"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_PLUS4_USER_PORT_ADD(_tag, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, PLUS4_USER_PORT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> plus4_user_port_device
+
+class device_plus4_user_port_interface;
+
+class plus4_user_port_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ plus4_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // computer interface
+ DECLARE_READ8_MEMBER( p_r );
+ DECLARE_WRITE8_MEMBER( p_w );
+ DECLARE_READ_LINE_MEMBER( rxd_r );
+ DECLARE_READ_LINE_MEMBER( dcd_r );
+ DECLARE_READ_LINE_MEMBER( dsr_r );
+ DECLARE_WRITE_LINE_MEMBER( txd_w );
+ DECLARE_WRITE_LINE_MEMBER( dtr_w );
+ DECLARE_WRITE_LINE_MEMBER( rts_w );
+ DECLARE_WRITE_LINE_MEMBER( rxc_w );
+ DECLARE_WRITE_LINE_MEMBER( atn_w );
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete() { };
+ virtual void device_start();
+ virtual void device_reset();
+
+ device_plus4_user_port_interface *m_cart;
+};
+
+
+// ======================> device_plus4_user_port_interface
+
+// class representing interface-specific live plus4_expansion card
+class device_plus4_user_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_plus4_user_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_plus4_user_port_interface();
+
+ virtual UINT8 plus4_p_r() { return 0xff; };
+ virtual void plus4_p_w(UINT8 data) { };
+
+ virtual int plus4_rxd_r() { return 1; };
+ virtual int plus4_dcd_r() { return 0; };
+ virtual int plus4_dsr_r() { return 0; };
+ virtual void plus4_txd_w(int state) { };
+ virtual void plus4_dtr_w(int state) { };
+ virtual void plus4_rts_w(int state) { };
+ virtual void plus4_rxc_w(int state) { };
+ virtual void plus4_atn_w(int state) { };
+
+protected:
+ plus4_user_port_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type PLUS4_USER_PORT;
+
+
+// slot devices
+#include "diag264_lb_user.h"
+
+SLOT_INTERFACE_EXTERN( plus4_user_port_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/vcs/ctrl.c b/src/emu/bus/vcs/ctrl.c
new file mode 100644
index 00000000000..6effedc9512
--- /dev/null
+++ b/src/emu/bus/vcs/ctrl.c
@@ -0,0 +1,114 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System controller port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type VCS_CONTROL_PORT = &device_creator<vcs_control_port_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_vcs_control_port_interface - constructor
+//-------------------------------------------------
+
+device_vcs_control_port_interface::device_vcs_control_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_port = dynamic_cast<vcs_control_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_vcs_control_port_interface - destructor
+//-------------------------------------------------
+
+device_vcs_control_port_interface::~device_vcs_control_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_control_port_device - constructor
+//-------------------------------------------------
+
+vcs_control_port_device::vcs_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_CONTROL_PORT, "Atari VCS control port", tag, owner, clock, "vcs_control_port", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_trigger_handler(*this)
+{
+}
+
+
+//-------------------------------------------------
+// vcs_control_port_device - destructor
+//-------------------------------------------------
+
+vcs_control_port_device::~vcs_control_port_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_control_port_device::device_start()
+{
+ m_device = dynamic_cast<device_vcs_control_port_interface *>(get_card_device());
+
+ m_trigger_handler.resolve_safe();
+}
+
+
+UINT8 vcs_control_port_device::joy_r() { UINT8 data = 0xff; if (exists()) data = m_device->vcs_joy_r(); return data; }
+READ8_MEMBER( vcs_control_port_device::joy_r ) { return joy_r(); }
+UINT8 vcs_control_port_device::pot_x_r() { UINT8 data = 0xff; if (exists()) data = m_device->vcs_pot_x_r(); return data; }
+READ8_MEMBER( vcs_control_port_device::pot_x_r ) { return pot_x_r(); }
+UINT8 vcs_control_port_device::pot_y_r() { UINT8 data = 0xff; if (exists()) data = m_device->vcs_pot_y_r(); return data; }
+READ8_MEMBER( vcs_control_port_device::pot_y_r ) { return pot_y_r(); }
+void vcs_control_port_device::joy_w( UINT8 data ) { if ( exists() ) m_device->vcs_joy_w( data ); }
+WRITE8_MEMBER( vcs_control_port_device::joy_w ) { joy_w(data); }
+bool vcs_control_port_device::exists() { return m_device != NULL; }
+bool vcs_control_port_device::has_pot_x() { return exists() && m_device->has_pot_x(); }
+bool vcs_control_port_device::has_pot_y() { return exists() && m_device->has_pot_y(); }
+
+void vcs_control_port_device::trigger_w(int state)
+{
+ m_trigger_handler(state);
+}
+
+//-------------------------------------------------
+// SLOT_INTERFACE( vcs_control_port_devices )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( vcs_control_port_devices )
+ SLOT_INTERFACE("joy", VCS_JOYSTICK)
+ SLOT_INTERFACE("pad", VCS_PADDLES)
+ SLOT_INTERFACE("lp", VCS_LIGHTPEN)
+ SLOT_INTERFACE("joybstr", VCS_JOYSTICK_BOOSTER)
+ SLOT_INTERFACE("wheel", VCS_WHEEL)
+ SLOT_INTERFACE("keypad", VCS_KEYPAD)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/vcs/ctrl.h b/src/emu/bus/vcs/ctrl.h
new file mode 100644
index 00000000000..cbf80f609a7
--- /dev/null
+++ b/src/emu/bus/vcs/ctrl.h
@@ -0,0 +1,135 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System controller port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_CONTROL_PORT__
+#define __VCS_CONTROL_PORT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_VCS_CONTROL_PORT_ADD(_tag, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, VCS_CONTROL_PORT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+#define MCFG_VCS_CONTROL_PORT_TRIGGER_HANDLER(_devcb) \
+ devcb = &vcs_control_port_device::set_trigger_handler(*device, DEVCB2_##_devcb);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_control_port_device
+
+class device_vcs_control_port_interface;
+
+class vcs_control_port_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ vcs_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~vcs_control_port_device();
+
+ // static configuration helpers
+ template<class _Object> static devcb2_base &set_trigger_handler(device_t &device, _Object object) { return downcast<vcs_control_port_device &>(device).m_trigger_handler.set_callback(object); }
+
+ // computer interface
+
+ // Data returned by the joy_r methods:
+ // bit 0 - pin 1 - Up
+ // bit 1 - pin 2 - Down
+ // bit 2 - pin 3 - Left
+ // bit 3 - pin 4 - Right
+ // bit 4 - pin 5 -
+ // bit 5 - pin 6 - Button
+ // pin 7 - +5V
+ // pin 8 - GND
+ // bit 6 - pin 9 -
+ //
+ UINT8 joy_r();
+ DECLARE_READ8_MEMBER( joy_r );
+ UINT8 pot_x_r();
+ DECLARE_READ8_MEMBER( pot_x_r );
+ UINT8 pot_y_r();
+ DECLARE_READ8_MEMBER( pot_y_r );
+
+ void joy_w( UINT8 data );
+ DECLARE_WRITE8_MEMBER( joy_w );
+
+ bool exists();
+ bool has_pot_x();
+ bool has_pot_y();
+
+ void trigger_w(int state);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ device_vcs_control_port_interface *m_device;
+
+private:
+ devcb2_write_line m_trigger_handler;
+};
+
+
+// ======================> device_vcs_control_port_interface
+
+// class representing interface-specific live vcs_expansion card
+class device_vcs_control_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_vcs_control_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_vcs_control_port_interface();
+
+ virtual UINT8 vcs_joy_r() { return 0xff; };
+ virtual UINT8 vcs_pot_x_r() { return 0xff; };
+ virtual UINT8 vcs_pot_y_r() { return 0xff; };
+ virtual void vcs_joy_w(UINT8 data) { };
+
+ virtual bool has_pot_x() { return false; }
+ virtual bool has_pot_y() { return false; }
+
+protected:
+ vcs_control_port_device *m_port;
+};
+
+
+// device type definition
+extern const device_type VCS_CONTROL_PORT;
+
+
+// slot devices
+#include "joybooster.h"
+#include "joystick.h"
+#include "keypad.h"
+#include "lightpen.h"
+#include "paddles.h"
+#include "wheel.h"
+
+SLOT_INTERFACE_EXTERN( vcs_control_port_devices );
+
+
+#endif
diff --git a/src/emu/bus/vcs/joybooster.c b/src/emu/bus/vcs/joybooster.c
new file mode 100644
index 00000000000..e2654968dc8
--- /dev/null
+++ b/src/emu/bus/vcs/joybooster.c
@@ -0,0 +1,96 @@
+/**********************************************************************
+
+ Atari Video Computer System digital joystick emulation with
+ boostergrip adapter
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "joybooster.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VCS_JOYSTICK_BOOSTER = &device_creator<vcs_joystick_booster_device>;
+
+
+static INPUT_PORTS_START( vcs_joystick_booster )
+ PORT_START("JOY")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY // Pin 1
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY // Pin 2
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY // Pin 3
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY // Pin 4
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // Pin 6
+ PORT_BIT( 0xd0, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ // Pin 5
+ PORT_START("POTX")
+ PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_BUTTON2 )
+
+ // Pin 9
+ PORT_START("POTY")
+ PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_BUTTON3 )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vcs_joystick_booster_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vcs_joystick_booster );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_joystick_booster_device - constructor
+//-------------------------------------------------
+
+vcs_joystick_booster_device::vcs_joystick_booster_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_JOYSTICK_BOOSTER, "Digital joystick with Boostergrip", tag, owner, clock, "vcs_joystick_booster", __FILE__),
+ device_vcs_control_port_interface(mconfig, *this),
+ m_joy(*this, "JOY"),
+ m_potx(*this, "POTX"),
+ m_poty(*this, "POTY")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_joystick_booster_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vcs_joy_r - joystick read
+//-------------------------------------------------
+
+UINT8 vcs_joystick_booster_device::vcs_joy_r()
+{
+ return m_joy->read();
+}
+
+UINT8 vcs_joystick_booster_device::vcs_pot_x_r()
+{
+ return m_potx->read();
+}
+
+UINT8 vcs_joystick_booster_device::vcs_pot_y_r()
+{
+ return m_poty->read();
+}
diff --git a/src/emu/bus/vcs/joybooster.h b/src/emu/bus/vcs/joybooster.h
new file mode 100644
index 00000000000..8f4c3bf9ca2
--- /dev/null
+++ b/src/emu/bus/vcs/joybooster.h
@@ -0,0 +1,60 @@
+/**********************************************************************
+
+ Atari Video Computer System digital joystick emulation with
+ boostergrip adapter
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_JOYSTICKBOOSTER__
+#define __VCS_JOYSTICKBOOSTER__
+
+#include "emu.h"
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_joystick_booster_device
+
+class vcs_joystick_booster_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ vcs_joystick_booster_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vcs_control_port_interface overrides
+ virtual UINT8 vcs_joy_r();
+ virtual UINT8 vcs_pot_x_r();
+ virtual UINT8 vcs_pot_y_r();
+
+ virtual bool has_pot_x() { return true; }
+ virtual bool has_pot_y() { return true; }
+
+private:
+ required_ioport m_joy;
+ required_ioport m_potx;
+ required_ioport m_poty;
+};
+
+
+// device type definition
+extern const device_type VCS_JOYSTICK_BOOSTER;
+
+
+#endif
diff --git a/src/emu/bus/vcs/joystick.c b/src/emu/bus/vcs/joystick.c
new file mode 100644
index 00000000000..3ef46b0246c
--- /dev/null
+++ b/src/emu/bus/vcs/joystick.c
@@ -0,0 +1,77 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System digital joystick emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "joystick.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VCS_JOYSTICK = &device_creator<vcs_joystick_device>;
+
+
+static INPUT_PORTS_START( vcs_joystick )
+ PORT_START("JOY")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0xd0, IP_ACTIVE_LOW, IPT_UNUSED )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vcs_joystick_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vcs_joystick );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_joystick_device - constructor
+//-------------------------------------------------
+
+vcs_joystick_device::vcs_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_JOYSTICK, "Digital joystick", tag, owner, clock, "vcs_joystick", __FILE__),
+ device_vcs_control_port_interface(mconfig, *this),
+ m_joy(*this, "JOY")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_joystick_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vcs_joy_r - joystick read
+//-------------------------------------------------
+
+UINT8 vcs_joystick_device::vcs_joy_r()
+{
+ return m_joy->read();
+}
diff --git a/src/emu/bus/vcs/joystick.h b/src/emu/bus/vcs/joystick.h
new file mode 100644
index 00000000000..7de13ff3c36
--- /dev/null
+++ b/src/emu/bus/vcs/joystick.h
@@ -0,0 +1,54 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System digital joystick emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_JOYSTICK__
+#define __VCS_JOYSTICK__
+
+#include "emu.h"
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_joystick_device
+
+class vcs_joystick_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ vcs_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vcs_control_port_interface overrides
+ virtual UINT8 vcs_joy_r();
+
+private:
+ required_ioport m_joy;
+};
+
+
+// device type definition
+extern const device_type VCS_JOYSTICK;
+
+
+#endif
diff --git a/src/emu/bus/vcs/keypad.c b/src/emu/bus/vcs/keypad.c
new file mode 100644
index 00000000000..a41db6d400a
--- /dev/null
+++ b/src/emu/bus/vcs/keypad.c
@@ -0,0 +1,140 @@
+/**********************************************************************
+
+ Atari Video Computer System keypad emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "keypad.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VCS_KEYPAD = &device_creator<vcs_keypad_device>;
+
+
+static INPUT_PORTS_START( vcs_keypad )
+ PORT_START("KEYPAD")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 1") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 2") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 3") PORT_CODE(KEYCODE_9_PAD)
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 4") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 5") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 6") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 7") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 8") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 9") PORT_CODE(KEYCODE_3_PAD)
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad *") PORT_CODE(KEYCODE_0_PAD)
+ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad 0") PORT_CODE(KEYCODE_DEL_PAD)
+ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("keypad #") PORT_CODE(KEYCODE_ENTER_PAD)
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vcs_keypad_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vcs_keypad );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_keypad_device - constructor
+//-------------------------------------------------
+
+vcs_keypad_device::vcs_keypad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_KEYPAD, "Keypad", tag, owner, clock, "vcs_keypad", __FILE__),
+ device_vcs_control_port_interface(mconfig, *this),
+ m_keypad(*this, "KEYPAD")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_keypad_device::device_start()
+{
+ m_column = 0;
+ save_item(NAME(m_column));
+}
+
+
+//-------------------------------------------------
+// vcs_joy_w - joystick write
+//-------------------------------------------------
+
+UINT8 vcs_keypad_device::vcs_joy_r()
+{
+ for ( int i = 0; i < 4; i++ )
+ {
+ if ( ! ( ( m_column >> i ) & 0x01 ) )
+ {
+ if ( ( m_keypad->read() >> 3*i ) & 0x04 )
+ {
+ return 0xff;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ return 0xff;
+}
+
+void vcs_keypad_device::vcs_joy_w( UINT8 data )
+{
+ m_column = data & 0x0F;
+}
+
+UINT8 vcs_keypad_device::vcs_pot_x_r()
+{
+ for ( int i = 0; i < 4; i++ )
+ {
+ if ( ! ( ( m_column >> i ) & 0x01 ) )
+ {
+ if ( ( m_keypad->read() >> 3*i ) & 0x01 )
+ {
+ return 0;
+ }
+ else
+ {
+ return 0xff;
+ }
+ }
+ }
+ return 0;
+}
+
+UINT8 vcs_keypad_device::vcs_pot_y_r()
+{
+ for ( int i = 0; i < 4; i++ )
+ {
+ if ( ! ( ( m_column >> i ) & 0x01 ) )
+ {
+ if ( ( m_keypad->read() >> 3*i ) & 0x02 )
+ {
+ return 0;
+ }
+ else
+ {
+ return 0xff;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/src/emu/bus/vcs/keypad.h b/src/emu/bus/vcs/keypad.h
new file mode 100644
index 00000000000..628731b2350
--- /dev/null
+++ b/src/emu/bus/vcs/keypad.h
@@ -0,0 +1,60 @@
+/**********************************************************************
+
+ Atari Video Computer System Keypad emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_KEYPAD__
+#define __VCS_KEYPAD__
+
+#include "emu.h"
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_keypad_device
+
+class vcs_keypad_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ vcs_keypad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vcs_control_port_interface overrides
+ virtual UINT8 vcs_joy_r();
+ virtual void vcs_joy_w( UINT8 data );
+ virtual UINT8 vcs_pot_x_r();
+ virtual UINT8 vcs_pot_y_r();
+
+ virtual bool has_pot_x() { return true; }
+ virtual bool has_pot_y() { return true; }
+
+private:
+ required_ioport m_keypad;
+
+ UINT8 m_column;
+};
+
+
+// device type definition
+extern const device_type VCS_KEYPAD;
+
+
+#endif
diff --git a/src/emu/bus/vcs/lightpen.c b/src/emu/bus/vcs/lightpen.c
new file mode 100644
index 00000000000..bf5a82997c0
--- /dev/null
+++ b/src/emu/bus/vcs/lightpen.c
@@ -0,0 +1,88 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System lightpen emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "lightpen.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VCS_LIGHTPEN = &device_creator<vcs_lightpen_device>;
+
+
+INPUT_CHANGED_MEMBER( vcs_lightpen_device::trigger )
+{
+ // TODO trigger timer at correct screen position
+ m_port->trigger_w(newval);
+}
+
+
+static INPUT_PORTS_START( vcs_lightpen )
+ PORT_START("JOY")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vcs_lightpen_device, trigger, 0)
+ PORT_BIT( 0xdf, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("LIGHTX")
+ PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
+
+ PORT_START("LIGHTY")
+ PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vcs_lightpen_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vcs_lightpen );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_lightpen_device - constructor
+//-------------------------------------------------
+
+vcs_lightpen_device::vcs_lightpen_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_LIGHTPEN, "Light Pen", tag, owner, clock, "vcs_lightpen", __FILE__),
+ device_vcs_control_port_interface(mconfig, *this),
+ m_joy(*this, "JOY"),
+ m_lightx(*this, "LIGHTX"),
+ m_lighty(*this, "LIGHTY")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_lightpen_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vcs_joy_r - lightpen read
+//-------------------------------------------------
+
+UINT8 vcs_lightpen_device::vcs_joy_r()
+{
+ return m_joy->read();
+}
diff --git a/src/emu/bus/vcs/lightpen.h b/src/emu/bus/vcs/lightpen.h
new file mode 100644
index 00000000000..c18a2a4a368
--- /dev/null
+++ b/src/emu/bus/vcs/lightpen.h
@@ -0,0 +1,58 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System lightpen emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_LIGHTPEN__
+#define __VCS_LIGHTPEN__
+
+#include "emu.h"
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_lightpen_device
+
+class vcs_lightpen_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ vcs_lightpen_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+ DECLARE_INPUT_CHANGED_MEMBER( trigger );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vcs_control_port_interface overrides
+ virtual UINT8 vcs_joy_r();
+
+private:
+ required_ioport m_joy;
+ required_ioport m_lightx;
+ required_ioport m_lighty;
+};
+
+
+// device type definition
+extern const device_type VCS_LIGHTPEN;
+
+
+#endif
diff --git a/src/emu/bus/vcs/paddles.c b/src/emu/bus/vcs/paddles.c
new file mode 100644
index 00000000000..61bc71c8bdf
--- /dev/null
+++ b/src/emu/bus/vcs/paddles.c
@@ -0,0 +1,102 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System analog paddles emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "paddles.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VCS_PADDLES = &device_creator<vcs_paddles_device>;
+
+
+static INPUT_PORTS_START( vcs_paddles )
+ PORT_START("JOY")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0xf3, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("POTX")
+ PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(1) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255)
+
+ PORT_START("POTY")
+ PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(2) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255)
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vcs_paddles_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vcs_paddles );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_paddles_device - constructor
+//-------------------------------------------------
+
+vcs_paddles_device::vcs_paddles_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_PADDLES, "Digital paddles", tag, owner, clock, "vcs_paddles", __FILE__),
+ device_vcs_control_port_interface(mconfig, *this),
+ m_joy(*this, "JOY"),
+ m_potx(*this, "POTX"),
+ m_poty(*this, "POTY")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_paddles_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vcs_joy_r - joystick read
+//-------------------------------------------------
+
+UINT8 vcs_paddles_device::vcs_joy_r()
+{
+ return m_joy->read();
+}
+
+
+//-------------------------------------------------
+// vcs_pot_x_r - potentiometer X read
+//-------------------------------------------------
+
+UINT8 vcs_paddles_device::vcs_pot_x_r()
+{
+ return m_potx->read();
+}
+
+
+//-------------------------------------------------
+// vcs_pot_y_r - potentiometer Y read
+//-------------------------------------------------
+
+UINT8 vcs_paddles_device::vcs_pot_y_r()
+{
+ return m_poty->read();
+}
diff --git a/src/emu/bus/vcs/paddles.h b/src/emu/bus/vcs/paddles.h
new file mode 100644
index 00000000000..7363d05bf25
--- /dev/null
+++ b/src/emu/bus/vcs/paddles.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Atari Video Computer System analog paddles emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_PADDLES__
+#define __VCS_PADDLES__
+
+#include "emu.h"
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_paddles_device
+
+class vcs_paddles_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ vcs_paddles_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vcs_control_port_interface overrides
+ virtual UINT8 vcs_joy_r();
+ virtual UINT8 vcs_pot_x_r();
+ virtual UINT8 vcs_pot_y_r();
+
+ virtual bool has_pot_x() { return true; }
+ virtual bool has_pot_y() { return true; }
+
+private:
+ required_ioport m_joy;
+ required_ioport m_potx;
+ required_ioport m_poty;
+};
+
+
+// device type definition
+extern const device_type VCS_PADDLES;
+
+
+#endif
diff --git a/src/emu/bus/vcs/wheel.c b/src/emu/bus/vcs/wheel.c
new file mode 100644
index 00000000000..ee8b6cb2987
--- /dev/null
+++ b/src/emu/bus/vcs/wheel.c
@@ -0,0 +1,77 @@
+/**********************************************************************
+
+ Atari Video Computer System Driving Wheel emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "wheel.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VCS_WHEEL = &device_creator<vcs_wheel_device>;
+
+
+static INPUT_PORTS_START( vcs_wheel )
+ PORT_START("JOY")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // Pin 6
+ PORT_BIT( 0xdc, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("WHEEL")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(40) PORT_KEYDELTA(5)
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vcs_wheel_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vcs_wheel );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vcs_wheel_device - constructor
+//-------------------------------------------------
+
+vcs_wheel_device::vcs_wheel_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VCS_WHEEL, "Driving Wheel", tag, owner, clock, "vcs_wheel", __FILE__),
+ device_vcs_control_port_interface(mconfig, *this),
+ m_joy(*this, "JOY"),
+ m_wheel(*this, "WHEEL")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vcs_wheel_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vcs_joy_r - joystick read
+//-------------------------------------------------
+
+UINT8 vcs_wheel_device::vcs_joy_r()
+{
+ static const UINT8 driving_lookup[4] = { 0x00, 0x02, 0x03, 0x01 };
+
+ return m_joy->read() | driving_lookup[ ( m_wheel->read() & 0x18 ) >> 3 ];
+}
diff --git a/src/emu/bus/vcs/wheel.h b/src/emu/bus/vcs/wheel.h
new file mode 100644
index 00000000000..07bcafd0534
--- /dev/null
+++ b/src/emu/bus/vcs/wheel.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+
+ Atari Video Computer System Driving Wheel emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VCS_WHEEL__
+#define __VCS_WHEEL__
+
+#include "emu.h"
+#include "ctrl.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vcs_wheel_device
+
+class vcs_wheel_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ vcs_wheel_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vcs_control_port_interface overrides
+ virtual UINT8 vcs_joy_r();
+
+private:
+ required_ioport m_joy;
+ required_ioport m_wheel;
+};
+
+
+// device type definition
+extern const device_type VCS_WHEEL;
+
+
+#endif
diff --git a/src/emu/bus/vic10/exp.c b/src/emu/bus/vic10/exp.c
new file mode 100644
index 00000000000..67f4b39b195
--- /dev/null
+++ b/src/emu/bus/vic10/exp.c
@@ -0,0 +1,287 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-10 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "emuopts.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC10_EXPANSION_SLOT = &device_creator<vic10_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE VIC10_EXPANSION CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_vic10_expansion_card_interface - constructor
+//-------------------------------------------------
+
+device_vic10_expansion_card_interface::device_vic10_expansion_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device),
+ m_exram(NULL),
+ m_lorom(NULL),
+ m_uprom(NULL)
+{
+ m_slot = dynamic_cast<vic10_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_vic10_expansion_card_interface - destructor
+//-------------------------------------------------
+
+device_vic10_expansion_card_interface::~device_vic10_expansion_card_interface()
+{
+}
+
+
+
+//-------------------------------------------------
+// vic10_lorom_pointer - get lower ROM pointer
+//-------------------------------------------------
+
+UINT8* device_vic10_expansion_card_interface::vic10_lorom_pointer(running_machine &machine, size_t size)
+{
+ if (m_lorom == NULL)
+ {
+ m_lorom = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_lorom;
+}
+
+
+//-------------------------------------------------
+// vic10_uprom_pointer - get upper ROM pointer
+//-------------------------------------------------
+
+UINT8* device_vic10_expansion_card_interface::vic10_uprom_pointer(running_machine &machine, size_t size)
+{
+ if (m_uprom == NULL)
+ {
+ m_uprom = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_uprom;
+}
+
+
+//-------------------------------------------------
+// vic10_exram_pointer - get expanded RAM pointer
+//-------------------------------------------------
+
+UINT8* device_vic10_expansion_card_interface::vic10_exram_pointer(running_machine &machine, size_t size)
+{
+ if (m_exram == NULL)
+ {
+ m_exram = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_exram;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic10_expansion_slot_device - constructor
+//-------------------------------------------------
+
+vic10_expansion_slot_device::vic10_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VIC10_EXPANSION_SLOT, "VIC-10 expansion port", tag, owner, clock, "vic10_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ device_image_interface(mconfig, *this),
+ m_write_irq(*this),
+ m_write_res(*this),
+ m_write_cnt(*this),
+ m_write_sp(*this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic10_expansion_slot_device::device_start()
+{
+ m_card = dynamic_cast<device_vic10_expansion_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_write_irq.resolve_safe();
+ m_write_res.resolve_safe();
+ m_write_cnt.resolve_safe();
+ m_write_sp.resolve_safe();
+
+ // inherit bus clock
+ if (clock() == 0)
+ {
+ vic10_expansion_slot_device *root = machine().device<vic10_expansion_slot_device>(VIC10_EXPANSION_SLOT_TAG);
+ assert(root);
+ set_unscaled_clock(root->clock());
+ }
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vic10_expansion_slot_device::device_reset()
+{
+ if (get_card_device())
+ {
+ get_card_device()->reset();
+ }
+}
+
+
+//-------------------------------------------------
+// call_load -
+//-------------------------------------------------
+
+bool vic10_expansion_slot_device::call_load()
+{
+ if (m_card)
+ {
+ size_t size = 0;
+
+ if (software_entry() == NULL)
+ {
+ size = length();
+
+ if (!mame_stricmp(filetype(), "80"))
+ {
+ fread(m_card->vic10_lorom_pointer(machine(), 0x2000), 0x2000);
+
+ if (size == 0x4000)
+ {
+ fread(m_card->vic10_uprom_pointer(machine(), 0x2000), 0x2000);
+ }
+ }
+ else if (!mame_stricmp(filetype(), "e0")) fread(m_card->vic10_uprom_pointer(machine(), size), size);
+ else if (!mame_stricmp(filetype(), "crt"))
+ {
+ size_t roml_size = 0;
+ size_t romh_size = 0;
+ int exrom = 1;
+ int game = 1;
+
+ if (cbm_crt_read_header(m_file, &roml_size, &romh_size, &exrom, &game))
+ {
+ UINT8 *roml = NULL;
+ UINT8 *romh = NULL;
+
+ if (roml_size) roml = m_card->vic10_lorom_pointer(machine(), roml_size);
+ if (romh_size) romh = m_card->vic10_uprom_pointer(machine(), romh_size);
+
+ cbm_crt_read_data(m_file, roml, romh);
+ }
+ }
+ }
+ else
+ {
+ size = get_software_region_length("lorom");
+ if (size) memcpy(m_card->vic10_lorom_pointer(machine(), size), get_software_region("lorom"), size);
+
+ size = get_software_region_length("uprom");
+ if (size) memcpy(m_card->vic10_uprom_pointer(machine(), size), get_software_region("uprom"), size);
+
+ size = get_software_region_length("exram");
+ if (size) m_card->vic10_exram_pointer(machine(), size);
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+//-------------------------------------------------
+// call_softlist_load -
+//-------------------------------------------------
+
+bool vic10_expansion_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
+{
+ load_software_part_region(this, swlist, swname, start_entry);
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// get_default_card_software -
+//-------------------------------------------------
+
+const char * vic10_expansion_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
+{
+ if (open_image_file(options))
+ {
+ if (!mame_stricmp(filetype(), "crt"))
+ {
+ return cbm_crt_get_card(m_file);
+ }
+
+ clear();
+ }
+
+ return software_get_default_slot(config, options, this, "standard");
+}
+
+
+//-------------------------------------------------
+// cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic10_expansion_slot_device::cd_r(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram)
+{
+ if (m_card != NULL)
+ {
+ data = m_card->vic10_cd_r(space, offset, data, lorom, uprom, exram);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic10_expansion_slot_device::cd_w(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram)
+{
+ if (m_card != NULL)
+ {
+ m_card->vic10_cd_w(space, offset, data, lorom, uprom, exram);
+ }
+}
+
+READ_LINE_MEMBER( vic10_expansion_slot_device::p0_r ) { int state = 0; if (m_card != NULL) state = m_card->vic10_p0_r(); return state; }
+WRITE_LINE_MEMBER( vic10_expansion_slot_device::p0_w ) { if (m_card != NULL) m_card->vic10_p0_w(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( vic10_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( vic10_expansion_cards )
+ // the following need ROMs from the software list
+ SLOT_INTERFACE_INTERNAL("standard", VIC10_STD)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/vic10/exp.h b/src/emu/bus/vic10/exp.h
new file mode 100644
index 00000000000..68236430fea
--- /dev/null
+++ b/src/emu/bus/vic10/exp.h
@@ -0,0 +1,188 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-10 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ +5V 2 B _UPROM
+ +5V 3 C _RESET
+ _IRQ 4 D _NMI
+ _CR/W 5 E Sphi2
+ SP 6 F CA15
+ _EXRAM 7 H CA14
+ CNT 8 J CA13
+ _CIA 9 K CA12
+ _CIA PLA 10 L CA11
+ _LOROM 11 M CA10
+ BA 12 N CA9
+ R/_W PLA 13 P CA8
+ CD7 14 R CA7
+ CD6 15 S CA6
+ CD5 16 T CA5
+ CD4 17 U CA4
+ CD3 18 V CA3
+ CD2 19 W CA2
+ CD1 20 X CA1
+ CD0 21 Y CA0
+ P2 22 Z GND
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC10_EXPANSION_SLOT__
+#define __VIC10_EXPANSION_SLOT__
+
+#include "emu.h"
+#include "formats/cbm_crt.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define VIC10_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_VIC10_EXPANSION_SLOT_ADD(_tag, _clock, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, VIC10_EXPANSION_SLOT, _clock) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+#define MCFG_VIC10_EXPANSION_SLOT_IRQ_CALLBACKS(_irq, _res) \
+ downcast<vic10_expansion_slot_device *>(device)->set_irq_callbacks(DEVCB2_##_irq, DEVCB2_##_res);
+
+#define MCFG_VIC10_EXPANSION_SLOT_SERIAL_CALLBACKS(_cnt, _sp) \
+ downcast<vic10_expansion_slot_device *>(device)->set_serial_callbacks(DEVCB2_##_cnt, DEVCB2_##_sp);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic10_expansion_slot_device
+
+class device_vic10_expansion_card_interface;
+
+class vic10_expansion_slot_device : public device_t,
+ public device_slot_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ vic10_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ template<class _irq, class _res> void set_irq_callbacks(_irq irq, _res res) {
+ m_write_irq.set_callback(irq);
+ m_write_res.set_callback(res);
+ }
+
+ template<class _cnt, class _sp> void set_serial_callbacks(_cnt cnt, _sp sp) {
+ m_write_cnt.set_callback(cnt);
+ m_write_sp.set_callback(sp);
+ }
+
+ // computer interface
+ UINT8 cd_r(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram);
+ void cd_w(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram);
+ DECLARE_READ_LINE_MEMBER( p0_r );
+ DECLARE_WRITE_LINE_MEMBER( p0_w );
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_write_irq(state); }
+ DECLARE_WRITE_LINE_MEMBER( res_w ) { m_write_res(state); }
+ DECLARE_WRITE_LINE_MEMBER( cnt_w ) { m_write_cnt(state); }
+ DECLARE_WRITE_LINE_MEMBER( sp_w ) { m_write_sp(state); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete() { update_names(); }
+ virtual void device_start();
+ virtual void device_reset();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
+
+ 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 1; }
+ virtual bool is_reset_on_load() const { return 1; }
+ virtual const char *image_interface() const { return "vic10_cart"; }
+ virtual const char *file_extensions() const { return "80,e0"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // slot interface overrides
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
+
+ devcb2_write_line m_write_irq;
+ devcb2_write_line m_write_res;
+ devcb2_write_line m_write_cnt;
+ devcb2_write_line m_write_sp;
+
+ device_vic10_expansion_card_interface *m_card;
+};
+
+
+// ======================> device_vic10_expansion_card_interface
+
+// class representing interface-specific live vic10_expansion card
+class device_vic10_expansion_card_interface : public device_slot_card_interface
+{
+ friend class vic10_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_vic10_expansion_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_vic10_expansion_card_interface();
+
+protected:
+ // initialization
+ virtual UINT8* vic10_exram_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic10_lorom_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic10_uprom_pointer(running_machine &machine, size_t size);
+
+ // runtime
+ virtual UINT8 vic10_cd_r(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram) { return data; };
+ virtual void vic10_cd_w(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram) { };
+ virtual int vic10_p0_r() { return 0; };
+ virtual void vic10_p0_w(int state) { };
+ virtual void vic10_sp_w(int state) { };
+ virtual void vic10_cnt_w(int state) { };
+
+ vic10_expansion_slot_device *m_slot;
+
+ UINT8 *m_exram;
+ UINT8 *m_lorom;
+ UINT8 *m_uprom;
+};
+
+
+// device type definition
+extern const device_type VIC10_EXPANSION_SLOT;
+
+
+// slot devices
+#include "std.h"
+
+SLOT_INTERFACE_EXTERN( vic10_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/vic10/std.c b/src/emu/bus/vic10/std.c
new file mode 100644
index 00000000000..f7afdcf7c3c
--- /dev/null
+++ b/src/emu/bus/vic10/std.c
@@ -0,0 +1,81 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-10 Standard 8K/16K ROM Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "std.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC10_STD = &device_creator<vic10_standard_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic10_standard_cartridge_device - constructor
+//-------------------------------------------------
+
+vic10_standard_cartridge_device::vic10_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC10_STD, "VIC-10 Standard Cartridge", tag, owner, clock, "vic10_standard", __FILE__),
+ device_vic10_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic10_standard_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vic10_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic10_standard_cartridge_device::vic10_cd_r(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram)
+{
+ if (!lorom && (m_lorom != NULL))
+ {
+ data = m_lorom[offset & 0x1fff];
+ }
+ else if (!exram && (m_exram != NULL))
+ {
+ data = m_exram[offset & 0x7ff];
+ }
+ else if (!uprom && (m_uprom != NULL))
+ {
+ data = m_uprom[offset & 0x1fff];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic10_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic10_standard_cartridge_device::vic10_cd_w(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram)
+{
+ if (!exram && (m_exram != NULL))
+ {
+ m_exram[offset & 0x7ff] = data;
+ }
+}
diff --git a/src/emu/bus/vic10/std.h b/src/emu/bus/vic10/std.h
new file mode 100644
index 00000000000..ca5fc55f593
--- /dev/null
+++ b/src/emu/bus/vic10/std.h
@@ -0,0 +1,50 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-10 Standard 8K/16K ROM Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC10_STD__
+#define __VIC10_STD__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic10_standard_cartridge_device
+
+class vic10_standard_cartridge_device : public device_t,
+ public device_vic10_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic10_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vic10_expansion_card_interface overrides
+ virtual UINT8 vic10_cd_r(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram);
+ virtual void vic10_cd_w(address_space &space, offs_t offset, UINT8 data, int lorom, int uprom, int exram);
+};
+
+
+// device type definition
+extern const device_type VIC10_STD;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/exp.c b/src/emu/bus/vic20/exp.c
new file mode 100644
index 00000000000..4dcd2de9e56
--- /dev/null
+++ b/src/emu/bus/vic20/exp.c
@@ -0,0 +1,334 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-20 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "exp.h"
+#include "emuopts.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC20_EXPANSION_SLOT = &device_creator<vic20_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE VIC20_EXPANSION CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_vic20_expansion_card_interface - constructor
+//-------------------------------------------------
+
+device_vic20_expansion_card_interface::device_vic20_expansion_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_blk1(NULL),
+ m_blk2(NULL),
+ m_blk3(NULL),
+ m_blk5(NULL),
+ m_ram(NULL),
+ m_nvram(NULL),
+ m_nvram_size(0)
+{
+ m_slot = dynamic_cast<vic20_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// vic20_blk1_pointer - get block 1 pointer
+//-------------------------------------------------
+
+UINT8* device_vic20_expansion_card_interface::vic20_blk1_pointer(running_machine &machine, size_t size)
+{
+ if (m_blk1 == NULL)
+ {
+ m_blk1 = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_blk1;
+}
+
+
+//-------------------------------------------------
+// vic20_blk2_pointer - get block 2 pointer
+//-------------------------------------------------
+
+UINT8* device_vic20_expansion_card_interface::vic20_blk2_pointer(running_machine &machine, size_t size)
+{
+ if (m_blk2 == NULL)
+ {
+ m_blk2 = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_blk2;
+}
+
+
+//-------------------------------------------------
+// vic20_blk3_pointer - get block 3 pointer
+//-------------------------------------------------
+
+UINT8* device_vic20_expansion_card_interface::vic20_blk3_pointer(running_machine &machine, size_t size)
+{
+ if (m_blk3 == NULL)
+ {
+ m_blk3 = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_blk3;
+}
+
+
+//-------------------------------------------------
+// vic20_blk5_pointer - get block 5 pointer
+//-------------------------------------------------
+
+UINT8* device_vic20_expansion_card_interface::vic20_blk5_pointer(running_machine &machine, size_t size)
+{
+ if (m_blk5 == NULL)
+ {
+ m_blk5 = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_blk5;
+}
+
+
+//-------------------------------------------------
+// vic20_ram_pointer - get RAM pointer
+//-------------------------------------------------
+
+UINT8* device_vic20_expansion_card_interface::vic20_ram_pointer(running_machine &machine, size_t size)
+{
+ if (m_ram == NULL)
+ {
+ m_ram = auto_alloc_array(machine, UINT8, size);
+ }
+
+ return m_ram;
+}
+
+
+//-------------------------------------------------
+// vic20_nvram_pointer - get NVRAM pointer
+//-------------------------------------------------
+
+UINT8* device_vic20_expansion_card_interface::vic20_nvram_pointer(running_machine &machine, size_t size)
+{
+ if (m_nvram == NULL)
+ {
+ m_nvram = auto_alloc_array(machine, UINT8, size);
+
+ m_nvram_mask = size - 1;
+ m_nvram_size = size;
+ }
+
+ return m_nvram;
+}
+
+
+//-------------------------------------------------
+// ~device_vic20_expansion_card_interface - destructor
+//-------------------------------------------------
+
+device_vic20_expansion_card_interface::~device_vic20_expansion_card_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic20_expansion_slot_device - constructor
+//-------------------------------------------------
+
+vic20_expansion_slot_device::vic20_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VIC20_EXPANSION_SLOT, "VIC-20 expansion port", tag, owner, clock, "vic20_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ device_image_interface(mconfig, *this),
+ m_write_irq(*this),
+ m_write_nmi(*this),
+ m_write_res(*this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic20_expansion_slot_device::device_start()
+{
+ m_card = dynamic_cast<device_vic20_expansion_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_write_irq.resolve_safe();
+ m_write_nmi.resolve_safe();
+ m_write_res.resolve_safe();
+
+ // inherit bus clock
+ if (clock() == 0)
+ {
+ vic20_expansion_slot_device *root = machine().device<vic20_expansion_slot_device>(VIC20_EXPANSION_SLOT_TAG);
+ assert(root);
+ set_unscaled_clock(root->clock());
+ }
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vic20_expansion_slot_device::device_reset()
+{
+ if (get_card_device())
+ {
+ get_card_device()->reset();
+ }
+}
+
+
+//-------------------------------------------------
+// call_load -
+//-------------------------------------------------
+
+bool vic20_expansion_slot_device::call_load()
+{
+ if (m_card)
+ {
+ size_t size = 0;
+
+ if (software_entry() == NULL)
+ {
+ if (!mame_stricmp(filetype(), "20")) fread(m_card->vic20_blk1_pointer(machine(), 0x2000), 0x2000);
+ else if (!mame_stricmp(filetype(), "40")) fread(m_card->vic20_blk2_pointer(machine(), 0x2000), 0x2000);
+ else if (!mame_stricmp(filetype(), "60")) fread(m_card->vic20_blk3_pointer(machine(), 0x2000), 0x2000);
+ else if (!mame_stricmp(filetype(), "70")) fread(m_card->vic20_blk3_pointer(machine(), 0x2000) + 0x1000, 0x1000);
+ else if (!mame_stricmp(filetype(), "a0")) fread(m_card->vic20_blk5_pointer(machine(), 0x2000), 0x2000);
+ else if (!mame_stricmp(filetype(), "b0")) fread(m_card->vic20_blk5_pointer(machine(), 0x2000) + 0x1000, 0x1000);
+ else if (!mame_stricmp(filetype(), "crt"))
+ {
+ // read the header
+ UINT8 header[2];
+ fread(&header, 2);
+ UINT16 address = pick_integer_le(header, 0, 2);
+
+ switch (address)
+ {
+ case 0x2000: fread(m_card->vic20_blk1_pointer(machine(), 0x2000), 0x2000); break;
+ case 0x4000: fread(m_card->vic20_blk2_pointer(machine(), 0x2000), 0x2000); break;
+ case 0x6000: fread(m_card->vic20_blk3_pointer(machine(), 0x2000), 0x2000); break;
+ case 0x7000: fread(m_card->vic20_blk3_pointer(machine(), 0x2000) + 0x1000, 0x1000); break;
+ case 0xa000: fread(m_card->vic20_blk5_pointer(machine(), 0x2000), 0x2000); break;
+ case 0xb000: fread(m_card->vic20_blk5_pointer(machine(), 0x2000) + 0x1000, 0x1000); break;
+ default: return IMAGE_INIT_FAIL;
+ }
+ }
+ }
+ else
+ {
+ size = get_software_region_length("blk1");
+ if (size) memcpy(m_card->vic20_blk1_pointer(machine(), size), get_software_region("blk1"), size);
+
+ size = get_software_region_length("blk2");
+ if (size) memcpy(m_card->vic20_blk2_pointer(machine(), size), get_software_region("blk2"), size);
+
+ size = get_software_region_length("blk3");
+ if (size) memcpy(m_card->vic20_blk3_pointer(machine(), size), get_software_region("blk3"), size);
+
+ size = get_software_region_length("blk5");
+ if (size) memcpy(m_card->vic20_blk5_pointer(machine(), size), get_software_region("blk5"), size);
+
+ size = get_software_region_length("ram");
+ if (size) memcpy(m_card->vic20_ram_pointer(machine(), size), get_software_region("ram"), size);
+
+ size = get_software_region_length("nvram");
+ if (size) memcpy(m_card->vic20_nvram_pointer(machine(), size), get_software_region("nvram"), size);
+
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+//-------------------------------------------------
+// call_softlist_load -
+//-------------------------------------------------
+
+bool vic20_expansion_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
+{
+ load_software_part_region(this, swlist, swname, start_entry);
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// get_default_card_software -
+//-------------------------------------------------
+
+const char * vic20_expansion_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
+{
+ return software_get_default_slot(config, options, this, "standard");
+}
+
+
+//-------------------------------------------------
+// cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic20_expansion_slot_device::cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (m_card != NULL)
+ {
+ data = m_card->vic20_cd_r(space, offset, data, ram1, ram2, ram3, blk1, blk2, blk3, blk5, io2, io3);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic20_expansion_slot_device::cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (m_card != NULL)
+ {
+ m_card->vic20_cd_w(space, offset, data, ram1, ram2, ram3, blk1, blk2, blk3, blk5, io2, io3);
+ }
+}
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( vic20_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( vic20_expansion_cards )
+ SLOT_INTERFACE("exp", VIC1010)
+ SLOT_INTERFACE("3k", VIC1210)
+ SLOT_INTERFACE("8k", VIC1110)
+ SLOT_INTERFACE("16k", VIC1111)
+
+ // the following need ROMs from the software list
+ SLOT_INTERFACE_INTERNAL("standard", VIC20_STD)
+ SLOT_INTERFACE_INTERNAL("ieee488", VIC1112)
+ SLOT_INTERFACE_INTERNAL("megacart", VIC20_MEGACART)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/vic20/exp.h b/src/emu/bus/vic20/exp.h
new file mode 100644
index 00000000000..099af84dfd1
--- /dev/null
+++ b/src/emu/bus/vic20/exp.h
@@ -0,0 +1,192 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-20 Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ CD0 2 B CA0
+ CD1 3 C CA1
+ CD2 4 D CA2
+ CD3 5 E CA3
+ CD4 6 F CA4
+ CD5 7 H CA5
+ CD6 8 J CA6
+ CD7 9 K CA7
+ _BLK1 10 L CA8
+ _BLK2 11 M CA9
+ _BLK3 12 N CA10
+ _BLK5 13 P CA11
+ _RAM1 14 R CA12
+ _RAM2 15 S CA13
+ _RAM3 16 T _I/O2
+ VR/W 17 U _I/O3
+ CR/W 18 V Sphi2
+ _IRQ 19 W _NMI
+ N.C. 20 X _RES
+ +5V 21 Y N.C.
+ GND 22 Z GND
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC20_EXPANSION_SLOT__
+#define __VIC20_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define VIC20_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_VIC20_EXPANSION_SLOT_ADD(_tag, _clock, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, VIC20_EXPANSION_SLOT, _clock) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+#define MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD(_tag) \
+ MCFG_VIC20_EXPANSION_SLOT_ADD(_tag, 0, vic20_expansion_cards, NULL) \
+ MCFG_VIC20_EXPANSION_SLOT_IRQ_CALLBACKS(DEVWRITELINE(DEVICE_SELF_OWNER, vic20_expansion_slot_device, irq_w), DEVWRITELINE(DEVICE_SELF_OWNER, vic20_expansion_slot_device, nmi_w), DEVWRITELINE(DEVICE_SELF_OWNER, vic20_expansion_slot_device, res_w))
+
+
+#define MCFG_VIC20_EXPANSION_SLOT_IRQ_CALLBACKS(_irq, _nmi, _res) \
+ downcast<vic20_expansion_slot_device *>(device)->set_irq_callbacks(DEVCB2_##_irq, DEVCB2_##_nmi, DEVCB2_##_res);
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic20_expansion_slot_device
+
+class device_vic20_expansion_card_interface;
+
+class vic20_expansion_slot_device : public device_t,
+ public device_slot_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ vic20_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ template<class _irq, class _nmi, class _res> void set_irq_callbacks(_irq irq, _nmi nmi, _res res) {
+ m_write_irq.set_callback(irq);
+ m_write_nmi.set_callback(nmi);
+ m_write_res.set_callback(res);
+ }
+
+ // computer interface
+ UINT8 cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ void cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_write_irq(state); }
+ DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_write_nmi(state); }
+ DECLARE_WRITE_LINE_MEMBER( res_w ) { m_write_res(state); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete() { update_names(); }
+ virtual void device_start();
+ virtual void device_reset();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
+
+ 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 char *image_interface() const { return "vic1001_cart"; }
+ virtual const char *file_extensions() const { return "20,40,60,70,a0,b0,crt"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // slot interface overrides
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
+
+ devcb2_write_line m_write_irq;
+ devcb2_write_line m_write_nmi;
+ devcb2_write_line m_write_res;
+
+ device_vic20_expansion_card_interface *m_card;
+};
+
+
+// ======================> device_vic20_expansion_card_interface
+
+// class representing interface-specific live vic20_expansion card
+class device_vic20_expansion_card_interface : public device_slot_card_interface
+{
+ friend class vic20_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_vic20_expansion_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_vic20_expansion_card_interface();
+
+protected:
+ // initialization
+ virtual UINT8* vic20_blk1_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic20_blk2_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic20_blk3_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic20_blk5_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic20_ram_pointer(running_machine &machine, size_t size);
+ virtual UINT8* vic20_nvram_pointer(running_machine &machine, size_t size);
+
+ // runtime
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3) { return data; };
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3) { };
+
+ vic20_expansion_slot_device *m_slot;
+
+ UINT8 *m_blk1;
+ UINT8 *m_blk2;
+ UINT8 *m_blk3;
+ UINT8 *m_blk5;
+ UINT8 *m_ram;
+ UINT8 *m_nvram;
+
+ size_t m_nvram_size;
+
+ size_t m_nvram_mask;
+};
+
+
+// device type definition
+extern const device_type VIC20_EXPANSION_SLOT;
+
+
+// slot devices
+#include "megacart.h"
+#include "std.h"
+#include "vic1010.h"
+#include "vic1110.h"
+#include "vic1111.h"
+#include "vic1112.h"
+#include "vic1210.h"
+
+SLOT_INTERFACE_EXTERN( vic20_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/megacart.c b/src/emu/bus/vic20/megacart.c
new file mode 100644
index 00000000000..32b562a053c
--- /dev/null
+++ b/src/emu/bus/vic20/megacart.c
@@ -0,0 +1,131 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Mega-Cart cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "megacart.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC20_MEGACART = &device_creator<vic20_megacart_device>;
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( vic1112 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( vic1112 )
+
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor vic20_megacart_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( vic1112 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic20_megacart_device - constructor
+//-------------------------------------------------
+
+vic20_megacart_device::vic20_megacart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC20_MEGACART, "Mega-Cart", tag, owner, clock, "megacart", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this),
+ device_nvram_interface(mconfig, *this),
+ m_nvram_en(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic20_megacart_device::device_start()
+{
+ // state saving
+ save_item(NAME(m_nvram_en));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vic20_megacart_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic20_megacart_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!ram1 || !ram2 || !ram3 || !io2 || !io3)
+ {
+ if (m_nvram_en)
+ {
+ data = m_nvram[offset & 0x1fff];
+ }
+ }
+ else if (!blk1 || !blk2 || !blk3)
+ {
+ }
+ else if (!blk5)
+ {
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic20_megacart_device::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!ram1 || !ram2 || !ram3 || !io2)
+ {
+ if (m_nvram_en)
+ {
+ m_nvram[offset & 0x1fff] = data;
+ }
+ }
+ else if (!blk1 || !blk2 || !blk3)
+ {
+ }
+ else if (!blk5)
+ {
+ }
+ else if (!io3)
+ {
+ if (m_nvram_en)
+ {
+ m_nvram[offset & 0x1fff] = data;
+ }
+ }
+}
diff --git a/src/emu/bus/vic20/megacart.h b/src/emu/bus/vic20/megacart.h
new file mode 100644
index 00000000000..021ae0f56a9
--- /dev/null
+++ b/src/emu/bus/vic20/megacart.h
@@ -0,0 +1,63 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Mega-Cart cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC20_MEGACART__
+#define __VIC20_MEGACART__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic20_megacart_device
+
+class vic20_megacart_device : public device_t,
+ public device_vic20_expansion_card_interface,
+ public device_nvram_interface
+{
+public:
+ // construction/destruction
+ vic20_megacart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_nvram_interface overrides
+ virtual void nvram_default() { }
+ virtual void nvram_read(emu_file &file) { if (m_nvram != NULL) { file.read(m_nvram, m_nvram_size); } }
+ virtual void nvram_write(emu_file &file) { if (m_nvram != NULL) { file.write(m_nvram, m_nvram_size); } }
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+
+private:
+ int m_nvram_en;
+};
+
+
+// device type definition
+extern const device_type VIC20_MEGACART;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/std.c b/src/emu/bus/vic20/std.c
new file mode 100644
index 00000000000..f7729c41b0b
--- /dev/null
+++ b/src/emu/bus/vic20/std.c
@@ -0,0 +1,72 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-20 Standard 8K/16K ROM Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "std.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC20_STD = &device_creator<vic20_standard_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic20_standard_cartridge_device - constructor
+//-------------------------------------------------
+
+vic20_standard_cartridge_device::vic20_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC20_STD, "VIC-20 Standard Cartridge", tag, owner, clock, "vic20_standard", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic20_standard_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic20_standard_cartridge_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!blk1 && (m_blk1 != NULL))
+ {
+ data = m_blk1[offset];
+ }
+ else if (!blk2 && (m_blk2 != NULL))
+ {
+ data = m_blk2[offset];
+ }
+ else if (!blk3 && (m_blk3 != NULL))
+ {
+ data = m_blk3[offset];
+ }
+ else if (!blk5 && (m_blk5 != NULL))
+ {
+ data = m_blk5[offset];
+ }
+
+ return data;
+}
diff --git a/src/emu/bus/vic20/std.h b/src/emu/bus/vic20/std.h
new file mode 100644
index 00000000000..0b74be61779
--- /dev/null
+++ b/src/emu/bus/vic20/std.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-20 Standard 8K/16K ROM Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC20_STD__
+#define __VIC20_STD__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic20_standard_cartridge_device
+
+class vic20_standard_cartridge_device : public device_t,
+ public device_vic20_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic20_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+};
+
+
+// device type definition
+extern const device_type VIC20_STD;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/user.c b/src/emu/bus/vic20/user.c
new file mode 100644
index 00000000000..4bff531c08c
--- /dev/null
+++ b/src/emu/bus/vic20/user.c
@@ -0,0 +1,136 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-20 User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "user.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type VIC20_USER_PORT = &device_creator<vic20_user_port_device>;
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_vic20_user_port_interface - constructor
+//-------------------------------------------------
+
+device_vic20_user_port_interface::device_vic20_user_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+ m_slot = dynamic_cast<vic20_user_port_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_vic20_user_port_interface - destructor
+//-------------------------------------------------
+
+device_vic20_user_port_interface::~device_vic20_user_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic20_user_port_device - constructor
+//-------------------------------------------------
+
+vic20_user_port_device::vic20_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VIC20_USER_PORT, "VIC-20 user port", tag, owner, clock, "vic20_user_port", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void vic20_user_port_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const vic20_user_port_interface *intf = reinterpret_cast<const vic20_user_port_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<vic20_user_port_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_cb1_cb, 0, sizeof(m_out_cb1_cb));
+ memset(&m_out_cb2_cb, 0, sizeof(m_out_cb2_cb));
+ memset(&m_out_reset_cb, 0, sizeof(m_out_reset_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic20_user_port_device::device_start()
+{
+ m_card = dynamic_cast<device_vic20_user_port_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_out_light_pen_func.resolve(m_out_light_pen_cb, *this);
+ m_out_cb1_func.resolve(m_out_cb1_cb, *this);
+ m_out_cb2_func.resolve(m_out_cb2_cb, *this);
+ m_out_reset_func.resolve(m_out_reset_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vic20_user_port_device::device_reset()
+{
+ if (get_card_device())
+ {
+ get_card_device()->reset();
+ }
+}
+
+
+READ8_MEMBER( vic20_user_port_device::pb_r ) { UINT8 data = 0xff; if (m_card != NULL) data = m_card->vic20_pb_r(space, offset); return data; }
+WRITE8_MEMBER( vic20_user_port_device::pb_w ) { if (m_card != NULL) m_card->vic20_pb_w(space, offset, data); }
+READ_LINE_MEMBER( vic20_user_port_device::joy0_r ) { int state = 1; if (m_card != NULL) state = m_card->vic20_joy0_r(); return state; }
+READ_LINE_MEMBER( vic20_user_port_device::joy1_r ) { int state = 1; if (m_card != NULL) state = m_card->vic20_joy1_r(); return state; }
+READ_LINE_MEMBER( vic20_user_port_device::joy2_r ) { int state = 1; if (m_card != NULL) state = m_card->vic20_joy2_r(); return state; }
+READ_LINE_MEMBER( vic20_user_port_device::light_pen_r ) { int state = 1; if (m_card != NULL) state = m_card->vic20_light_pen_r(); return state; }
+READ_LINE_MEMBER( vic20_user_port_device::cassette_switch_r ) { int state = 1; if (m_card != NULL) state = m_card->vic20_cassette_switch_r(); return state; }
+WRITE_LINE_MEMBER( vic20_user_port_device::cb1_w ) { if (m_card != NULL) m_card->vic20_cb1_w(state); }
+WRITE_LINE_MEMBER( vic20_user_port_device::cb2_w ) { if (m_card != NULL) m_card->vic20_cb2_w(state); }
+WRITE_LINE_MEMBER( vic20_user_port_device::atn_w ) { if (m_card != NULL) m_card->vic20_atn_w(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE( vic20_user_port_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( vic20_user_port_cards )
+ SLOT_INTERFACE("rs232", VIC1011)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/vic20/user.h b/src/emu/bus/vic20/user.h
new file mode 100644
index 00000000000..501b1511282
--- /dev/null
+++ b/src/emu/bus/vic20/user.h
@@ -0,0 +1,158 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-20 User Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 A GND
+ +5V 2 B CB1
+ /RESET 3 C PB0
+ JOY0 4 D PB1
+ JOY1 5 E PB2
+ JOY2 6 F PB3
+ LIGHT PEN 7 H PB4
+ CASSETTE SWITCH 8 J PB5
+ ATN 9 K PB6
+ +9VAC 10 L PB7
+ +9VAC 11 M CB2
+ GND 12 N GND
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC20_USER_PORT__
+#define __VIC20_USER_PORT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define VIC20_USER_PORT_TAG "user"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define VIC20_USER_PORT_INTERFACE(_name) \
+ const vic20_user_port_interface (_name) =
+
+
+#define MCFG_VIC20_USER_PORT_ADD(_tag, _config, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, VIC20_USER_PORT, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic20_user_port_interface
+
+struct vic20_user_port_interface
+{
+ devcb_write_line m_out_light_pen_cb;
+ devcb_write_line m_out_cb1_cb;
+ devcb_write_line m_out_cb2_cb;
+ devcb_write_line m_out_reset_cb;
+};
+
+
+// ======================> vic20_user_port_device
+
+class device_vic20_user_port_interface;
+
+class vic20_user_port_device : public device_t,
+ public vic20_user_port_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ vic20_user_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // computer interface
+ DECLARE_READ8_MEMBER( pb_r );
+ DECLARE_WRITE8_MEMBER( pb_w );
+ DECLARE_READ_LINE_MEMBER( joy0_r );
+ DECLARE_READ_LINE_MEMBER( joy1_r );
+ DECLARE_READ_LINE_MEMBER( joy2_r );
+ DECLARE_READ_LINE_MEMBER( light_pen_r );
+ DECLARE_READ_LINE_MEMBER( cassette_switch_r );
+ DECLARE_WRITE_LINE_MEMBER( cb1_w );
+ DECLARE_WRITE_LINE_MEMBER( cb2_w );
+ DECLARE_WRITE_LINE_MEMBER( atn_w );
+ DECLARE_WRITE_LINE_MEMBER( port_reset_w );
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( light_pen_w ) { m_out_light_pen_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( via_cb1_w ) { m_out_cb1_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( via_cb2_w ) { m_out_cb2_func(state); }
+ DECLARE_WRITE_LINE_MEMBER( reset_w ) { m_out_reset_func(state); }
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+
+ devcb_resolved_write_line m_out_light_pen_func;
+ devcb_resolved_write_line m_out_cb1_func;
+ devcb_resolved_write_line m_out_cb2_func;
+ devcb_resolved_write_line m_out_reset_func;
+
+ device_vic20_user_port_interface *m_card;
+};
+
+
+// ======================> device_vic20_user_port_interface
+
+// class representing interface-specific live vic20_expansion card
+class device_vic20_user_port_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_vic20_user_port_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_vic20_user_port_interface();
+
+ virtual UINT8 vic20_pb_r(address_space &space, offs_t offset) { return 0xff; };
+ virtual void vic20_pb_w(address_space &space, offs_t offset, UINT8 data) { };
+
+ virtual int vic20_joy0_r() { return 1; };
+ virtual int vic20_joy1_r() { return 1; };
+ virtual int vic20_joy2_r() { return 1; };
+ virtual int vic20_light_pen_r() { return 1; };
+ virtual int vic20_cassette_switch_r() { return 1; };
+ virtual void vic20_cb1_w(int state) { };
+ virtual void vic20_cb2_w(int state) { };
+ virtual void vic20_atn_w(int state) { };
+
+protected:
+ vic20_user_port_device *m_slot;
+};
+
+
+// device type definition
+extern const device_type VIC20_USER_PORT;
+
+
+// slot devices
+#include "vic1011.h"
+
+SLOT_INTERFACE_EXTERN( vic20_user_port_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/vic1010.c b/src/emu/bus/vic20/vic1010.c
new file mode 100644
index 00000000000..4dc380d29ab
--- /dev/null
+++ b/src/emu/bus/vic20/vic1010.c
@@ -0,0 +1,129 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1010 Expansion Module emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "vic1010.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC1010 = &device_creator<vic1010_device>;
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( vic1010 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( vic1010 )
+ MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD("slot1")
+ MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD("slot2")
+ MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD("slot3")
+ MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD("slot4")
+ MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD("slot5")
+ MCFG_VIC20_PASSTHRU_EXPANSION_SLOT_ADD("slot6")
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor vic1010_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( vic1010 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic1010_device - constructor
+//-------------------------------------------------
+
+vic1010_device::vic1010_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC1010, "VIC1010", tag, owner, clock, "vic1010", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this),
+ m_slot1(*this, "slot1"),
+ m_slot2(*this, "slot2"),
+ m_slot3(*this, "slot3"),
+ m_slot4(*this, "slot4"),
+ m_slot5(*this, "slot5"),
+ m_slot6(*this, "slot6")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic1010_device::device_start()
+{
+ // find devices
+ m_expansion_slot[0] = m_slot1;
+ m_expansion_slot[1] = m_slot2;
+ m_expansion_slot[2] = m_slot3;
+ m_expansion_slot[3] = m_slot4;
+ m_expansion_slot[4] = m_slot5;
+ m_expansion_slot[5] = m_slot6;
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vic1010_device::device_reset()
+{
+ for (int i = 0; i < MAX_SLOTS; i++)
+ {
+ m_expansion_slot[i]->reset();
+ }
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic1010_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ for (int i = 0; i < MAX_SLOTS; i++)
+ {
+ UINT8 slot_data = m_expansion_slot[i]->cd_r(space, offset, data, ram1, ram2, ram3, blk1, blk2, blk3, blk5, io2, io3);
+
+ if (data != slot_data)
+ {
+ data = slot_data;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic1010_device::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ for (int i = 0; i < MAX_SLOTS; i++)
+ {
+ m_expansion_slot[i]->cd_w(space, offset, data, ram1, ram2, ram3, blk1, blk2, blk3, blk5, io2, io3);
+ }
+}
diff --git a/src/emu/bus/vic20/vic1010.h b/src/emu/bus/vic20/vic1010.h
new file mode 100644
index 00000000000..ea6e3dae9dd
--- /dev/null
+++ b/src/emu/bus/vic20/vic1010.h
@@ -0,0 +1,72 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1010 Expansion Module emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC1010__
+#define __VIC1010__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define MAX_SLOTS 6
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic1010_device
+
+class vic1010_device : public device_t,
+ public device_vic20_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic1010_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+
+private:
+ required_device<vic20_expansion_slot_device> m_slot1;
+ required_device<vic20_expansion_slot_device> m_slot2;
+ required_device<vic20_expansion_slot_device> m_slot3;
+ required_device<vic20_expansion_slot_device> m_slot4;
+ required_device<vic20_expansion_slot_device> m_slot5;
+ required_device<vic20_expansion_slot_device> m_slot6;
+
+ vic20_expansion_slot_device *m_expansion_slot[MAX_SLOTS];
+};
+
+
+// device type definition
+extern const device_type VIC1010;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/vic1011.c b/src/emu/bus/vic20/vic1011.c
new file mode 100644
index 00000000000..312b50a5b6b
--- /dev/null
+++ b/src/emu/bus/vic20/vic1011.c
@@ -0,0 +1,166 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1011A/B RS-232C Adapter emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "vic1011.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define RS232_TAG "rs232"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC1011 = &device_creator<vic1011_device>;
+
+
+//-------------------------------------------------
+// rs232_port_interface rs232_intf
+//-------------------------------------------------
+
+static const rs232_port_interface rs232_intf =
+{
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, vic1011_device, rxd_w),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL
+};
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( vic1011 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( vic1011 )
+ MCFG_RS232_PORT_ADD(RS232_TAG, rs232_intf, default_rs232_devices, NULL)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor vic1011_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( vic1011 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic1011_device - constructor
+//-------------------------------------------------
+
+vic1011_device::vic1011_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC1011, "VIC1011", tag, owner, clock, "vic1011", __FILE__),
+ device_vic20_user_port_interface(mconfig, *this),
+ m_rs232(*this, RS232_TAG)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic1011_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vic20_pb_r - port B read
+//-------------------------------------------------
+
+UINT8 vic1011_device::vic20_pb_r(address_space &space, offs_t offset)
+{
+ /*
+
+ bit description
+
+ 0 Sin
+ 1
+ 2
+ 3
+ 4 DCDin
+ 5
+ 6 CTS
+ 7 DSR
+
+ */
+
+ UINT8 data = 0;
+
+ data |= !m_rs232->rx();
+ data |= m_rs232->dcd_r() << 4;
+ data |= m_rs232->cts_r() << 6;
+ data |= m_rs232->dsr_r() << 7;
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_pb_w - port B write
+//-------------------------------------------------
+
+void vic1011_device::vic20_pb_w(address_space &space, offs_t offset, UINT8 data)
+{
+ /*
+
+ bit description
+
+ 0
+ 1 RTS
+ 2 DTR
+ 3
+ 4
+ 5 DCDout
+ 6
+ 7
+
+ */
+
+ m_rs232->rts_w(BIT(data, 1));
+ m_rs232->dtr_w(BIT(data, 2));
+}
+
+
+//-------------------------------------------------
+// vic20_cb2_w - CB2 write
+//-------------------------------------------------
+
+void vic1011_device::vic20_cb2_w(int state)
+{
+ m_rs232->tx(!state);
+}
+
+
+//-------------------------------------------------
+// rxd_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( vic1011_device::rxd_w )
+{
+ m_slot->via_cb1_w(!state);
+}
diff --git a/src/emu/bus/vic20/vic1011.h b/src/emu/bus/vic20/vic1011.h
new file mode 100644
index 00000000000..ed034a33900
--- /dev/null
+++ b/src/emu/bus/vic20/vic1011.h
@@ -0,0 +1,60 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1011A/B RS-232C Adapter emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC1011__
+#define __VIC1011__
+
+#include "emu.h"
+#include "user.h"
+#include "machine/serial.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic1011_device
+
+class vic1011_device : public device_t,
+ public device_vic20_user_port_interface
+{
+public:
+ // construction/destruction
+ vic1011_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ DECLARE_WRITE_LINE_MEMBER( rxd_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vic20_user_port_interface overrides
+ virtual UINT8 vic20_pb_r(address_space &space, offs_t offset);
+ virtual void vic20_pb_w(address_space &space, offs_t offset, UINT8 data);
+ virtual void vic20_cb2_w(int state);
+
+private:
+ required_device<rs232_port_device> m_rs232;
+};
+
+
+// device type definition
+extern const device_type VIC1011;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/vic1110.c b/src/emu/bus/vic20/vic1110.c
new file mode 100644
index 00000000000..b387489667d
--- /dev/null
+++ b/src/emu/bus/vic20/vic1110.c
@@ -0,0 +1,119 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1110 8K RAM Expansion Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "vic1110.h"
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+enum
+{
+ BLK1 = 0x07,
+ BLK2 = 0x0b,
+ BLK3 = 0x0d,
+ BLK5 = 0x0e
+};
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC1110 = &device_creator<vic1110_device>;
+
+
+
+//-------------------------------------------------
+// INPUT_PORTS( vic1110 )
+//-------------------------------------------------
+
+INPUT_PORTS_START( vic1110 )
+ PORT_START("SW")
+ PORT_DIPNAME( 0x0f, BLK1, "Memory Location" ) PORT_DIPLOCATION("SW:1,2,3,4")
+ PORT_DIPSETTING( BLK1, "$2000-$3FFF" )
+ PORT_DIPSETTING( BLK2, "$4000-$5FFF" )
+ PORT_DIPSETTING( BLK3, "$6000-$7FFF" )
+ PORT_DIPSETTING( BLK5, "$A000-B3FFF" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor vic1110_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( vic1110 );
+}
+
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic1110_device - constructor
+//-------------------------------------------------
+
+vic1110_device::vic1110_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC1110, "VIC1110", tag, owner, clock, "vic1110", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this),
+ m_sw(*this, "SW")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic1110_device::device_start()
+{
+ // allocate memory
+ vic20_ram_pointer(machine(), 0x2000);
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic1110_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ UINT8 sw = m_sw->read();
+
+ if ((!blk1 && (sw == BLK1)) || (!blk2 && (sw == BLK2)) || (!blk3 && (sw == BLK3)) || (!blk5 && (sw == BLK5)))
+ {
+ data = m_ram[offset & 0x1fff];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic1110_device::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ UINT8 sw = m_sw->read();
+
+ if ((!blk1 && (sw == BLK1)) || (!blk2 && (sw == BLK2)) || (!blk3 && (sw == BLK3)) || (!blk5 && (sw == BLK5)))
+ {
+ m_ram[offset & 0x1fff] = data;
+ }
+}
diff --git a/src/emu/bus/vic20/vic1110.h b/src/emu/bus/vic20/vic1110.h
new file mode 100644
index 00000000000..9758115283a
--- /dev/null
+++ b/src/emu/bus/vic20/vic1110.h
@@ -0,0 +1,56 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1110 8K RAM Expansion Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC1110__
+#define __VIC1110__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic1110_device
+
+class vic1110_device : public device_t,
+ public device_vic20_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic1110_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const;
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+
+private:
+ required_ioport m_sw;
+};
+
+
+// device type definition
+extern const device_type VIC1110;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/vic1111.c b/src/emu/bus/vic20/vic1111.c
new file mode 100644
index 00000000000..29e4ff6f16c
--- /dev/null
+++ b/src/emu/bus/vic20/vic1111.c
@@ -0,0 +1,83 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1111 16K RAM Expansion Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "vic1111.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC1111 = &device_creator<vic1111_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic1111_device - constructor
+//-------------------------------------------------
+
+vic1111_device::vic1111_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC1111, "VIC1111", tag, owner, clock, "vic1111", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic1111_device::device_start()
+{
+ // allocate memory
+ m_ram = auto_alloc_array(machine(), UINT8, 0x4000);
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic1111_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!blk1)
+ {
+ data = m_ram[offset];
+ }
+ else if (!blk2)
+ {
+ data = m_ram[0x2000 + offset];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic1111_device::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!blk1)
+ {
+ m_ram[offset] = data;
+ }
+ else if (!blk2)
+ {
+ m_ram[0x2000 + offset] = data;
+ }
+}
diff --git a/src/emu/bus/vic20/vic1111.h b/src/emu/bus/vic20/vic1111.h
new file mode 100644
index 00000000000..4ed922e254d
--- /dev/null
+++ b/src/emu/bus/vic20/vic1111.h
@@ -0,0 +1,50 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1111 16K RAM Expansion Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC1111__
+#define __VIC1111__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic1111_device
+
+class vic1111_device : public device_t,
+ public device_vic20_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic1111_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+};
+
+
+// device type definition
+extern const device_type VIC1111;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/vic1112.c b/src/emu/bus/vic20/vic1112.c
new file mode 100644
index 00000000000..b75d561f2fd
--- /dev/null
+++ b/src/emu/bus/vic20/vic1112.c
@@ -0,0 +1,256 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1112 IEEE-488 Interface Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "vic1112.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define M6522_0_TAG "u4"
+#define M6522_1_TAG "u5"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC1112 = &device_creator<vic1112_device>;
+
+
+//-------------------------------------------------
+// via6522_interface via0_intf
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( vic1112_device::via0_irq_w )
+{
+ m_via0_irq = state;
+
+ m_slot->irq_w(m_via0_irq | m_via1_irq);
+}
+
+READ8_MEMBER( vic1112_device::via0_pb_r )
+{
+ /*
+
+ bit description
+
+ PB0
+ PB1
+ PB2
+ PB3 _EOI
+ PB4 _DAV IN
+ PB5 _NRFD IN
+ PB6 _NDAC IN
+ PB7 _ATN IN
+
+ */
+
+ UINT8 data = 0;
+
+ data |= m_bus->eoi_r() << 3;
+ data |= m_bus->dav_r() << 4;
+ data |= m_bus->nrfd_r() << 5;
+ data |= m_bus->ndac_r() << 6;
+ data |= m_bus->atn_r() << 7;
+
+ return data;
+}
+
+WRITE8_MEMBER( vic1112_device::via0_pb_w )
+{
+ /*
+
+ bit description
+
+ PB0 _DAV OUT
+ PB1 _NRFD OUT
+ PB2 _NDAC OUT
+ PB3
+ PB4
+ PB5
+ PB6
+ PB7
+
+ */
+
+ m_bus->dav_w(BIT(data, 0));
+ m_bus->nrfd_w(BIT(data, 1));
+ m_bus->ndac_w(BIT(data, 2));
+}
+
+static const via6522_interface via0_intf =
+{
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, vic1112_device, via0_pb_r),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, vic1112_device, via0_pb_w),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, vic1112_device, via0_irq_w)
+};
+
+
+//-------------------------------------------------
+// via6522_interface via1_intf
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( vic1112_device::via1_irq_w )
+{
+ m_via1_irq = state;
+
+ m_slot->irq_w(m_via0_irq | m_via1_irq);
+}
+
+static const via6522_interface via1_intf =
+{
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(IEEE488_TAG, ieee488_device, dio_r),
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(IEEE488_TAG, ieee488_device, srq_r),
+ DEVCB_NULL,
+ DEVCB_NULL,
+
+ DEVCB_DEVICE_MEMBER(IEEE488_TAG, ieee488_device, dio_w),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(IEEE488_TAG, ieee488_device, atn_w),
+ DEVCB_DEVICE_LINE_MEMBER(IEEE488_TAG, ieee488_device, eoi_w),
+
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, vic1112_device, via1_irq_w)
+};
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( vic1112 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( vic1112 )
+ MCFG_VIA6522_ADD(M6522_0_TAG, 0, via0_intf)
+ MCFG_VIA6522_ADD(M6522_1_TAG, 0, via1_intf)
+
+ MCFG_CBM_IEEE488_ADD(NULL)
+ MCFG_IEEE488_SRQ_CALLBACK(DEVWRITELINE(M6522_1_TAG, via6522_device, write_cb1))
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor vic1112_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( vic1112 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic1112_device - constructor
+//-------------------------------------------------
+
+vic1112_device::vic1112_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC1112, "VIC1112", tag, owner, clock, "vic1112", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this),
+ m_via0(*this, M6522_0_TAG),
+ m_via1(*this, M6522_1_TAG),
+ m_bus(*this, IEEE488_TAG)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic1112_device::device_start()
+{
+ // state saving
+ save_item(NAME(m_via0_irq));
+ save_item(NAME(m_via1_irq));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void vic1112_device::device_reset()
+{
+ m_bus->ifc_w(0);
+ m_bus->ifc_w(1);
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic1112_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!io2)
+ {
+ if (offset & 0x10)
+ {
+ data = m_via1->read(space, offset & 0x0f);
+ }
+ else
+ {
+ data = m_via0->read(space, offset & 0x0f);
+ }
+ }
+ else if (!blk5)
+ {
+ if (offset & 0x1000)
+ {
+ data = m_blk5[offset & 0x17ff];
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic1112_device::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!io2)
+ {
+ if (offset & 0x10)
+ {
+ m_via1->write(space, offset & 0x0f, data);
+ }
+ else
+ {
+ m_via0->write(space, offset & 0x0f, data);
+ }
+ }
+}
diff --git a/src/emu/bus/vic20/vic1112.h b/src/emu/bus/vic20/vic1112.h
new file mode 100644
index 00000000000..60544edee1e
--- /dev/null
+++ b/src/emu/bus/vic20/vic1112.h
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1112 IEEE-488 Interface Cartridge emulation
+
+ SYS 45065 to start
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC1112__
+#define __VIC1112__
+
+#include "emu.h"
+#include "exp.h"
+#include "bus/ieee488/ieee488.h"
+#include "cpu/m6502/m6502.h"
+#include "machine/6522via.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic1112_device
+
+class vic1112_device : public device_t,
+ public device_vic20_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic1112_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ // not really public
+ DECLARE_WRITE_LINE_MEMBER( via0_irq_w );
+ DECLARE_READ8_MEMBER( via0_pb_r );
+ DECLARE_WRITE8_MEMBER( via0_pb_w );
+ DECLARE_WRITE_LINE_MEMBER( via1_irq_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+
+private:
+ required_device<via6522_device> m_via0;
+ required_device<via6522_device> m_via1;
+ required_device<ieee488_device> m_bus;
+
+ //UINT8 *m_rom;
+
+ int m_via0_irq;
+ int m_via1_irq;
+};
+
+
+// device type definition
+extern const device_type VIC1112;
+
+
+
+#endif
diff --git a/src/emu/bus/vic20/vic1210.c b/src/emu/bus/vic20/vic1210.c
new file mode 100644
index 00000000000..c843bb75e90
--- /dev/null
+++ b/src/emu/bus/vic20/vic1210.c
@@ -0,0 +1,80 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1210 3K RAM Expansion Cartridge emulation
+ Commodore VIC-1211A Super Expander with 3K RAM Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "vic1210.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIC1210 = &device_creator<vic1210_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vic1210_device - constructor
+//-------------------------------------------------
+
+vic1210_device::vic1210_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VIC1210, "VIC1210", tag, owner, clock, "vic1210", __FILE__),
+ device_vic20_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vic1210_device::device_start()
+{
+ // allocate memory
+ m_ram = auto_alloc_array(machine(), UINT8, 0xc00);
+}
+
+
+//-------------------------------------------------
+// vic20_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 vic1210_device::vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!ram1 || !ram2 || !ram3)
+ {
+ data = m_ram[offset & 0xbff];
+ }
+ else if (!blk5 && m_blk5)
+ {
+ data = m_blk5[offset & 0xfff];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic20_cd_w - cartridge data write
+//-------------------------------------------------
+
+void vic1210_device::vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3)
+{
+ if (!ram1 || !ram2 || !ram3)
+ {
+ m_ram[offset & 0xbff] = data;
+ }
+}
diff --git a/src/emu/bus/vic20/vic1210.h b/src/emu/bus/vic20/vic1210.h
new file mode 100644
index 00000000000..6a38852b3d6
--- /dev/null
+++ b/src/emu/bus/vic20/vic1210.h
@@ -0,0 +1,51 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore VIC-1210 3K RAM Expansion Cartridge emulation
+ Commodore VIC-1211A Super Expander with 3K RAM Cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIC1210__
+#define __VIC1210__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> vic1210_device
+
+class vic1210_device : public device_t,
+ public device_vic20_expansion_card_interface
+{
+public:
+ // construction/destruction
+ vic1210_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_vic20_expansion_card_interface overrides
+ virtual UINT8 vic20_cd_r(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+ virtual void vic20_cd_w(address_space &space, offs_t offset, UINT8 data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3);
+};
+
+
+// device type definition
+extern const device_type VIC1210;
+
+
+
+#endif
diff --git a/src/emu/bus/vidbrain/exp.c b/src/emu/bus/vidbrain/exp.c
new file mode 100644
index 00000000000..e1259ba52d2
--- /dev/null
+++ b/src/emu/bus/vidbrain/exp.c
@@ -0,0 +1,260 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// MACROS/CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VIDEOBRAIN_EXPANSION_SLOT = &device_creator<videobrain_expansion_slot_device>;
+
+
+
+//**************************************************************************
+// DEVICE VIDEOBRAIN_EXPANSION CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_videobrain_expansion_card_interface - constructor
+//-------------------------------------------------
+
+device_videobrain_expansion_card_interface::device_videobrain_expansion_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_rom(NULL),
+ m_ram(NULL),
+ m_rom_mask(0),
+ m_ram_mask(0)
+{
+ m_slot = dynamic_cast<videobrain_expansion_slot_device *>(device.owner());
+}
+
+
+//-------------------------------------------------
+// ~device_videobrain_expansion_card_interface - destructor
+//-------------------------------------------------
+
+device_videobrain_expansion_card_interface::~device_videobrain_expansion_card_interface()
+{
+}
+
+
+//-------------------------------------------------
+// videobrain_roml_pointer - get low ROM pointer
+//-------------------------------------------------
+
+UINT8* device_videobrain_expansion_card_interface::videobrain_rom_pointer(running_machine &machine, size_t size)
+{
+ if (m_rom == NULL)
+ {
+ m_rom = auto_alloc_array(machine, UINT8, size);
+
+ m_rom_mask = size - 1;
+ }
+
+ return m_rom;
+}
+
+
+//-------------------------------------------------
+// videobrain_ram_pointer - get RAM pointer
+//-------------------------------------------------
+
+UINT8* device_videobrain_expansion_card_interface::videobrain_ram_pointer(running_machine &machine, size_t size)
+{
+ if (m_ram == NULL)
+ {
+ m_ram = auto_alloc_array(machine, UINT8, size);
+
+ m_ram_mask = size - 1;
+ }
+
+ return m_ram;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// videobrain_expansion_slot_device - constructor
+//-------------------------------------------------
+
+videobrain_expansion_slot_device::videobrain_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VIDEOBRAIN_EXPANSION_SLOT, "VideoBrain expansion port", tag, owner, clock, "videobrain_expansion_slot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ device_image_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// videobrain_expansion_slot_device - destructor
+//-------------------------------------------------
+
+videobrain_expansion_slot_device::~videobrain_expansion_slot_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void videobrain_expansion_slot_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const videobrain_expansion_slot_interface *intf = reinterpret_cast<const videobrain_expansion_slot_interface *>(static_config());
+ if (intf != NULL)
+ {
+ *static_cast<videobrain_expansion_slot_interface *>(this) = *intf;
+ }
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_extres_cb, 0, sizeof(m_out_extres_cb));
+ }
+
+ // set brief and instance name
+ update_names();
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void videobrain_expansion_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_videobrain_expansion_card_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_out_extres_func.resolve(m_out_extres_cb, *this);
+}
+
+
+//-------------------------------------------------
+// call_load -
+//-------------------------------------------------
+
+bool videobrain_expansion_slot_device::call_load()
+{
+ if (m_cart)
+ {
+ size_t size = 0;
+
+ if (software_entry() == NULL)
+ {
+ size = length();
+
+ fread(m_cart->videobrain_rom_pointer(machine(), size), size);
+ }
+ else
+ {
+ size = get_software_region_length("rom");
+ if (size) memcpy(m_cart->videobrain_rom_pointer(machine(), size), get_software_region("rom"), size);
+
+ size = get_software_region_length("ram");
+ if (size) memset(m_cart->videobrain_ram_pointer(machine(), size), 0, size);
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+//-------------------------------------------------
+// call_softlist_load -
+//-------------------------------------------------
+
+bool videobrain_expansion_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
+{
+ load_software_part_region(this, swlist, swname, start_entry);
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// get_default_card_software -
+//-------------------------------------------------
+
+const char * videobrain_expansion_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
+{
+ return software_get_default_slot(config, options, this, "standard");
+}
+
+
+//-------------------------------------------------
+// bo_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 videobrain_expansion_slot_device::bo_r(address_space &space, offs_t offset, int cs1, int cs2)
+{
+ UINT8 data = 0;
+
+ if (m_cart != NULL)
+ {
+ data = m_cart->videobrain_bo_r(space, offset, cs1, cs2);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// bo_w - cartridge data write
+//-------------------------------------------------
+
+void videobrain_expansion_slot_device::bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2)
+{
+ if (m_cart != NULL)
+ {
+ m_cart->videobrain_bo_w(space, offset, data, cs1, cs2);
+ }
+}
+
+
+READ8_MEMBER( videobrain_expansion_slot_device::cs1_r ) { return bo_r(space, offset + 0x1000, 0, 1); }
+WRITE8_MEMBER( videobrain_expansion_slot_device::cs1_w ) { bo_w(space, offset + 0x1000, data, 0, 1); }
+READ8_MEMBER( videobrain_expansion_slot_device::cs2_r ) { return bo_r(space, offset + 0x1800, 1, 0); }
+WRITE8_MEMBER( videobrain_expansion_slot_device::cs2_w ) { bo_w(space, offset + 0x1800, data, 1, 0); }
+READ8_MEMBER( videobrain_expansion_slot_device::unmap_r ) { return bo_r(space, offset + 0x3000, 1, 0); }
+WRITE8_MEMBER( videobrain_expansion_slot_device::unmap_w ) { bo_w(space, offset + 0x3000, data, 1, 0); }
+
+
+WRITE_LINE_MEMBER( videobrain_expansion_slot_device::extres_w ) { m_out_extres_func(state); }
+
+
+//-------------------------------------------------
+// SLOT_INTERFACE_START( vidbrain_expansion_cards )
+//-------------------------------------------------
+
+SLOT_INTERFACE_START( vidbrain_expansion_cards )
+ SLOT_INTERFACE_INTERNAL("standard", VB_STD)
+ SLOT_INTERFACE_INTERNAL("moneyminder", VB_MONEY_MINDER)
+ SLOT_INTERFACE_INTERNAL("timeshare", VB_TIMESHARE)
+SLOT_INTERFACE_END
diff --git a/src/emu/bus/vidbrain/exp.h b/src/emu/bus/vidbrain/exp.h
new file mode 100644
index 00000000000..db856a5ad56
--- /dev/null
+++ b/src/emu/bus/vidbrain/exp.h
@@ -0,0 +1,185 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Expansion Port emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+
+ GND 1 2 BO2
+ BO1 3 4 BO0
+ BA0 5 6 BA1
+ BA2 7 8 BA3
+ BA4 9 10 BA5
+ BA6 11 12 BA7
+ +5V 13 14 BA8
+ BA9 15 16 _CS1
+ BA10 17 18 BO7
+ BO6 19 20 BO5
+ BO4 21 22 BO3
+ BA11 23 24 BA12
+ BRC 25 26 ?
+ EXTRES 27 28 _CS2
+ ? 29 30 UV202/35
+ HBLANK 31 32 UV201/5
+ UV201/2 33 34 UV201/4
+ UV201/3 35 36 BISTROBE
+ UV202/1 37 38 BA13
+ UV202/18 39 40 ?
+ R/W 41 42 +5V
+ GND 43 44 GND
+ GND 45 46 N/C
+ ? 47 48 N/C
+ N/C 49 50 N/C
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIDEOBRAIN_EXPANSION_SLOT__
+#define __VIDEOBRAIN_EXPANSION_SLOT__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+#define VIDEOBRAIN_EXPANSION_SLOT_TAG "exp"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define VIDEOBRAIN_EXPANSION_INTERFACE(_name) \
+ const videobrain_expansion_slot_interface (_name) =
+
+
+#define MCFG_VIDEOBRAIN_EXPANSION_SLOT_ADD(_tag, _config, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, VIDEOBRAIN_EXPANSION_SLOT, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> videobrain_expansion_slot_interface
+
+struct videobrain_expansion_slot_interface
+{
+ devcb_write_line m_out_extres_cb;
+};
+
+
+// ======================> videobrain_expansion_slot_device
+
+class device_videobrain_expansion_card_interface;
+
+class videobrain_expansion_slot_device : public device_t,
+ public videobrain_expansion_slot_interface,
+ public device_slot_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ videobrain_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~videobrain_expansion_slot_device();
+
+ // computer interface
+ UINT8 bo_r(address_space &space, offs_t offset, int cs1, int cs2);
+ void bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2);
+
+ DECLARE_READ8_MEMBER( cs1_r );
+ DECLARE_WRITE8_MEMBER( cs1_w );
+ DECLARE_READ8_MEMBER( cs2_r );
+ DECLARE_WRITE8_MEMBER( cs2_w );
+ DECLARE_READ8_MEMBER( unmap_r );
+ DECLARE_WRITE8_MEMBER( unmap_w );
+
+ // cartridge interface
+ DECLARE_WRITE_LINE_MEMBER( extres_w );
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
+
+ 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 char *image_interface() const { return "vidbrain_cart"; }
+ virtual const char *file_extensions() const { return "bin"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // slot interface overrides
+ virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
+
+ devcb_resolved_write_line m_out_extres_func;
+
+ device_videobrain_expansion_card_interface *m_cart;
+};
+
+
+// ======================> device_videobrain_expansion_card_interface
+
+class device_videobrain_expansion_card_interface : public device_slot_card_interface
+{
+ friend class videobrain_expansion_slot_device;
+
+public:
+ // construction/destruction
+ device_videobrain_expansion_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_videobrain_expansion_card_interface();
+
+protected:
+ // initialization
+ virtual UINT8* videobrain_rom_pointer(running_machine &machine, size_t size);
+ virtual UINT8* videobrain_ram_pointer(running_machine &machine, size_t size);
+
+ // runtime
+ virtual UINT8 videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2) { return 0; };
+ virtual void videobrain_bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2) { };
+ virtual void videobrain_extres_w() { };
+
+ videobrain_expansion_slot_device *m_slot;
+
+ UINT8 *m_rom;
+ UINT8 *m_ram;
+
+ size_t m_rom_mask;
+ size_t m_ram_mask;
+};
+
+
+// device type definition
+extern const device_type VIDEOBRAIN_EXPANSION_SLOT;
+
+
+// slot devices
+#include "std.h"
+#include "money_minder.h"
+#include "timeshare.h"
+
+SLOT_INTERFACE_EXTERN( vidbrain_expansion_cards );
+
+
+
+#endif
diff --git a/src/emu/bus/vidbrain/money_minder.c b/src/emu/bus/vidbrain/money_minder.c
new file mode 100644
index 00000000000..98df3830963
--- /dev/null
+++ b/src/emu/bus/vidbrain/money_minder.c
@@ -0,0 +1,79 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Money Minder cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "money_minder.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VB_MONEY_MINDER = &device_creator<videobrain_money_minder_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// videobrain_money_minder_cartridge_device - constructor
+//-------------------------------------------------
+
+videobrain_money_minder_cartridge_device::videobrain_money_minder_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VB_MONEY_MINDER, "VideoBrain Money Minder cartridge", tag, owner, clock, "vb_money_minder", __FILE__),
+ device_videobrain_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void videobrain_money_minder_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// videobrain_cd_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 videobrain_money_minder_cartridge_device::videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2)
+{
+ UINT8 data = 0;
+
+ if (!cs1 || !cs2)
+ {
+ data = m_rom[offset & m_rom_mask];
+ }
+ else if (offset >= 0x3800)
+ {
+ data = m_ram[offset & m_ram_mask];
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// videobrain_bo_w - cartridge data write
+//-------------------------------------------------
+
+void videobrain_money_minder_cartridge_device::videobrain_bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2)
+{
+ if (offset >= 0x3800)
+ {
+ m_ram[offset & m_ram_mask] = data;
+ }
+}
diff --git a/src/emu/bus/vidbrain/money_minder.h b/src/emu/bus/vidbrain/money_minder.h
new file mode 100644
index 00000000000..20bdaf1f1e5
--- /dev/null
+++ b/src/emu/bus/vidbrain/money_minder.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Money Minder cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIDEOBRAIN_MONEY_MINDER_CARTRIDGE__
+#define __VIDEOBRAIN_MONEY_MINDER_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> videobrain_money_minder_cartridge_device
+
+class videobrain_money_minder_cartridge_device : public device_t,
+ public device_videobrain_expansion_card_interface
+{
+public:
+ // construction/destruction
+ videobrain_money_minder_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_videobrain_expansion_card_interface overrides
+ virtual UINT8 videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2);
+ virtual void videobrain_bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2);
+};
+
+
+// device type definition
+extern const device_type VB_MONEY_MINDER;
+
+
+#endif
diff --git a/src/emu/bus/vidbrain/std.c b/src/emu/bus/vidbrain/std.c
new file mode 100644
index 00000000000..cbfbf6e20d3
--- /dev/null
+++ b/src/emu/bus/vidbrain/std.c
@@ -0,0 +1,65 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Standard 2K/4K cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "std.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VB_STD = &device_creator<videobrain_standard_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// videobrain_standard_cartridge_device - constructor
+//-------------------------------------------------
+
+videobrain_standard_cartridge_device::videobrain_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VB_STD, "VideoBrain standard cartridge", tag, owner, clock, "vb_std", __FILE__),
+ device_videobrain_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void videobrain_standard_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// videobrain_bo_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 videobrain_standard_cartridge_device::videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2)
+{
+ UINT8 data = 0;
+
+ if (!cs1)
+ {
+ data = m_rom[offset & m_rom_mask];
+ }
+ else if (!cs2)
+ {
+ data = m_rom[offset & m_rom_mask];
+ }
+ return data;
+}
diff --git a/src/emu/bus/vidbrain/std.h b/src/emu/bus/vidbrain/std.h
new file mode 100644
index 00000000000..a0baea9e3a7
--- /dev/null
+++ b/src/emu/bus/vidbrain/std.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Standard 2K/4K cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIDEOBRAIN_STANDARD_CARTRIDGE__
+#define __VIDEOBRAIN_STANDARD_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> videobrain_standard_cartridge_device
+
+class videobrain_standard_cartridge_device : public device_t,
+ public device_videobrain_expansion_card_interface
+{
+public:
+ // construction/destruction
+ videobrain_standard_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_videobrain_expansion_card_interface overrides
+ virtual UINT8 videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2);
+};
+
+
+// device type definition
+extern const device_type VB_STD;
+
+
+#endif
diff --git a/src/emu/bus/vidbrain/timeshare.c b/src/emu/bus/vidbrain/timeshare.c
new file mode 100644
index 00000000000..ccb3f8781ad
--- /dev/null
+++ b/src/emu/bus/vidbrain/timeshare.c
@@ -0,0 +1,78 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Timeshare cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "timeshare.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type VB_TIMESHARE = &device_creator<videobrain_timeshare_cartridge_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// videobrain_timeshare_cartridge_device - constructor
+//-------------------------------------------------
+
+videobrain_timeshare_cartridge_device::videobrain_timeshare_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VB_TIMESHARE, "VideoBrain Timeshare cartridge", tag, owner, clock, "vb_timeshare", __FILE__),
+ device_videobrain_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void videobrain_timeshare_cartridge_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// videobrain_bo_r - cartridge data read
+//-------------------------------------------------
+
+UINT8 videobrain_timeshare_cartridge_device::videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2)
+{
+ UINT8 data = 0;
+
+ if (!cs1)
+ {
+ data = m_rom[offset & m_rom_mask];
+ }
+ else if (!cs2)
+ {
+ data = m_ram[offset & m_ram_mask];
+ }
+ return data;
+}
+
+
+//-------------------------------------------------
+// videobrain_bo_w - cartridge data write
+//-------------------------------------------------
+
+void videobrain_timeshare_cartridge_device::videobrain_bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2)
+{
+ if (!cs2)
+ {
+ m_ram[offset & m_ram_mask] = data;
+ }
+}
diff --git a/src/emu/bus/vidbrain/timeshare.h b/src/emu/bus/vidbrain/timeshare.h
new file mode 100644
index 00000000000..d4c10b4821e
--- /dev/null
+++ b/src/emu/bus/vidbrain/timeshare.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ VideoBrain Timeshare cartridge emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __VIDEOBRAIN_TIMESHARE_CARTRIDGE__
+#define __VIDEOBRAIN_TIMESHARE_CARTRIDGE__
+
+#include "emu.h"
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> videobrain_timeshare_cartridge_device
+
+class videobrain_timeshare_cartridge_device : public device_t,
+ public device_videobrain_expansion_card_interface
+{
+public:
+ // construction/destruction
+ videobrain_timeshare_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+
+ // device_videobrain_expansion_card_interface overrides
+ virtual UINT8 videobrain_bo_r(address_space &space, offs_t offset, int cs1, int cs2);
+ virtual void videobrain_bo_w(address_space &space, offs_t offset, UINT8 data, int cs1, int cs2);
+};
+
+
+// device type definition
+extern const device_type VB_TIMESHARE;
+
+
+#endif
diff --git a/src/emu/emu.mak b/src/emu/emu.mak
index e935833c8d6..095ef08a981 100644
--- a/src/emu/emu.mak
+++ b/src/emu/emu.mak
@@ -28,14 +28,27 @@ OBJDIRS += \
$(EMUOBJ)/debugint \
$(EMUOBJ)/audio \
$(EMUOBJ)/bus \
+ $(EMUOBJ)/bus/abc1600 \
$(EMUOBJ)/bus/abcbus \
+ $(EMUOBJ)/bus/adam \
$(EMUOBJ)/bus/adamnet \
+ $(EMUOBJ)/bus/bw2 \
$(EMUOBJ)/bus/c64 \
+ $(EMUOBJ)/bus/cbm2 \
$(EMUOBJ)/bus/cbmiec \
$(EMUOBJ)/bus/comx35 \
+ $(EMUOBJ)/bus/ecbbus \
+ $(EMUOBJ)/bus/econet \
+ $(EMUOBJ)/bus/ep64 \
$(EMUOBJ)/bus/ieee488 \
$(EMUOBJ)/bus/isbx \
+ $(EMUOBJ)/bus/pet \
+ $(EMUOBJ)/bus/plus4 \
$(EMUOBJ)/bus/s100 \
+ $(EMUOBJ)/bus/vcs \
+ $(EMUOBJ)/bus/vic10 \
+ $(EMUOBJ)/bus/vic20 \
+ $(EMUOBJ)/bus/vidbrain \
$(EMUOBJ)/bus/vip \
$(EMUOBJ)/bus/wangpc \
$(EMUOBJ)/drivers \
diff --git a/src/emu/machine/64h156.c b/src/emu/machine/64h156.c
new file mode 100644
index 00000000000..8a32a9cca29
--- /dev/null
+++ b/src/emu/machine/64h156.c
@@ -0,0 +1,778 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore 64H156 Gate Array emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+/*
+
+ TODO:
+
+ http://staff.washington.edu/rrcc/uwweb/1541early/1540-2.GIF
+
+ - model disk rotation for proper track alignment
+ - write circuitry
+ - cycle exact M6502
+ - cycle exact VIA
+ - refactor to use modern floppy system
+
+ - get these running and we're golden
+ - Quiwi (speed change within track)
+ - Defender of the Crown (V-MAX! v2, density checks)
+ - Test Drive / Cabal (HLS, sub-cycle jitter)
+ - Galaxian (?, needs 100% accurate VIA)
+
+*/
+
+#include "emu.h"
+#include "64h156.h"
+#include "formats/g64_dsk.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+#define ATN (m_atni ^ m_atna)
+
+#define CYCLES_UNTIL_ANALOG_DESYNC 288 // 18 us
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type C64H156 = &device_creator<c64h156_device>;
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void c64h156_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const c64h156_interface *intf = reinterpret_cast<const c64h156_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<c64h156_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_atn_cb, 0, sizeof(m_out_atn_cb));
+ memset(&m_out_sync_cb, 0, sizeof(m_out_sync_cb));
+ memset(&m_out_byte_cb, 0, sizeof(m_out_byte_cb));
+ }
+}
+
+
+
+//**************************************************************************
+// INLINE HELPERS
+//**************************************************************************
+
+//-------------------------------------------------
+// set_atn_line -
+//-------------------------------------------------
+
+inline void c64h156_device::set_atn_line()
+{
+ m_out_atn_func(ATN);
+}
+
+
+//-------------------------------------------------
+// read_current_track -
+//-------------------------------------------------
+
+inline void c64h156_device::read_current_track()
+{
+ int track_length = G64_BUFFER_SIZE;
+
+ // read track data
+ floppy_drive_read_track_data_info_buffer(m_floppy, m_side, m_track_buffer, &track_length);
+
+ // extract track length
+ m_track_len = floppy_drive_get_current_track_size(m_floppy, m_side);
+
+ // set bit pointer to track start
+ m_buffer_pos = 0;
+ m_bit_pos = 7;
+ m_bit_count = 0;
+ m_zero_count = 0;
+
+ if (m_track_len)
+ {
+ memcpy(m_speed_buffer, m_track_buffer + m_track_len, G64_SPEED_BLOCK_SIZE);
+
+ update_cycles_until_next_bit();
+ }
+}
+
+
+//-------------------------------------------------
+// update_cycles_until_next_bit -
+//-------------------------------------------------
+
+inline void c64h156_device::update_cycles_until_next_bit()
+{
+ int speed_offset = m_buffer_pos / 4;
+ int speed_shift = (3 - (m_buffer_pos % 4)) * 2;
+
+ UINT8 speed = m_speed_buffer[speed_offset];
+
+ int ds = (speed >> speed_shift) & 0x03;
+
+ m_cycles_until_next_bit = (16 - ds) * 4;
+
+ if (LOG) logerror("buff %04x:%u speed %04x shift %u ds %u cycles %u\n", m_buffer_pos, m_bit_pos, speed_offset, speed_shift, ds, m_cycles_until_next_bit);
+}
+
+
+//-------------------------------------------------
+// receive_bit - receive bit
+//-------------------------------------------------
+
+inline void c64h156_device::receive_bit()
+{
+ if (!m_track_len)
+ {
+ m_bit_sync = 0;
+ }
+ else
+ {
+ if (m_cycles_until_next_bit == 0)
+ {
+ m_bit_sync = BIT(m_track_buffer[m_buffer_pos], m_bit_pos);
+
+ if (m_bit_sync)
+ {
+ m_zero_count = 0;
+ m_cycles_until_random_flux = (rand() % 31) + 289;
+ }
+ else
+ {
+ m_zero_count++;
+ }
+
+ if (m_zero_count >= m_cycles_until_random_flux)
+ {
+ // receive phantom bit
+ if (LOG) logerror("PHANTOM BIT SYNC 1 after %u cycles\n", m_zero_count);
+
+ m_bit_sync = 1;
+
+ m_zero_count = 0;
+ m_cycles_until_random_flux = (rand() % 367) + 33;
+ }
+ else
+ {
+ if (LOG) logerror("BIT SYNC %u\n", m_bit_sync);
+ }
+
+ m_shift <<= 1;
+ m_shift |= m_bit_sync;
+
+ m_bit_pos--;
+ m_bit_count++;
+
+ if (m_bit_pos < 0)
+ {
+ m_bit_pos = 7;
+ m_buffer_pos++;
+
+ if (m_buffer_pos >= m_track_len)
+ {
+ // loop to the start of the track
+ m_buffer_pos = 0;
+ }
+ }
+
+ update_cycles_until_next_bit();
+ }
+
+ m_cycles_until_next_bit--;
+ }
+}
+
+
+//-------------------------------------------------
+// decode_bit -
+//-------------------------------------------------
+
+inline void c64h156_device::decode_bit()
+{
+ // UE7
+
+ bool ue7_tc = false;
+
+ if (!m_last_bit_sync && m_bit_sync)
+ {
+ m_ue7 = m_ds;
+ }
+ else
+ {
+ m_ue7++;
+
+ if (m_ue7 == 16)
+ {
+ m_ue7 = m_ds;
+ ue7_tc = true;
+ }
+ }
+
+ if (LOG) logerror("UE7 CTR %01x TC %u, ", m_ue7, ue7_tc);
+
+ // UF4
+
+ if (!m_last_bit_sync && m_bit_sync)
+ {
+ m_uf4 = 0;
+
+ if (LOG) logerror("--");
+ }
+ else
+ {
+ if (!m_ue7_tc && ue7_tc)
+ {
+ m_uf4++;
+ m_uf4 &= 0x0f;
+
+ if (LOG) logerror("++");
+ }
+ else
+ {
+ if (LOG) logerror(" ");
+ }
+ }
+
+ m_last_bit_sync = m_bit_sync;
+ m_ue7_tc = ue7_tc;
+
+ int uf4_qa = BIT(m_uf4, 0);
+ int uf4_qb = BIT(m_uf4, 1);
+ int uf4_qc = BIT(m_uf4, 2);
+ int uf4_qd = BIT(m_uf4, 3);
+
+ int ue5a = !(uf4_qc || uf4_qd);
+
+ if (LOG) logerror("UF4 CTR %01x %u%u%u%u UE5A %u, ", m_uf4, uf4_qd, uf4_qc, uf4_qb, uf4_qa, ue5a);
+
+ if (!m_uf4_qb && uf4_qb)
+ {
+ // shift bits thru flip-flops
+ m_u4b = m_u4a;
+ m_u4a = BIT(m_ud2, 7);
+
+ // shift in data bit
+ m_ud2 <<= 1;
+ m_ud2 |= ue5a;
+
+ if (LOG) logerror("<<");
+ }
+ else
+ {
+ if (LOG) logerror(" ");
+ }
+
+ if (LOG) logerror("UD2 %u%u%u%u%u%u%u%u%u%u : %02x (%02x), ", m_u4b, m_u4a, BIT(m_ud2, 7), BIT(m_ud2, 6), BIT(m_ud2, 5), BIT(m_ud2, 4), BIT(m_ud2, 3), BIT(m_ud2, 2), BIT(m_ud2, 1), BIT(m_ud2, 0), m_ud2, m_shift & 0xff);
+
+ // UE3
+
+ int block_sync = !(m_oe && (m_ud2 == 0xff) && m_u4a && m_u4b);
+
+ if (LOG) logerror("SYNC %u, ", block_sync);
+
+ if (!block_sync)
+ {
+ // load UE3
+ m_ue3 = 8; // pin D is floating and TTL inputs float high
+
+ if (LOG) logerror("--");
+ }
+ else
+ {
+ if (m_block_sync && !m_uf4_qb && uf4_qb)
+ {
+ // clock UE3
+ m_ue3++;
+
+ if (m_ue3 == 16)
+ {
+ m_ue3 = 0;
+ }
+
+ if (LOG) logerror("++");
+ }
+ else
+ {
+ if (LOG) logerror(" ");
+ }
+ }
+
+ int ue3_qa = BIT(m_ue3, 0);
+ int ue3_qb = BIT(m_ue3, 1);
+ int ue3_qc = BIT(m_ue3, 2);
+
+ int uf3a = !(ue3_qa && ue3_qb && ue3_qc);
+ int uc1b = !uf3a; // schmitt trigger
+
+ if (LOG) logerror("UE3 CTR %01x UF3A %u UC1B %u, ", m_ue3, uf3a, uc1b);
+
+ int byte_sync = !(uc1b && m_soe && !uf4_qb);
+
+ if (LOG) logerror("BYTE %u SOE %u\n", byte_sync, m_soe);
+
+ // UD3
+
+ int uf3b = !(uc1b && uf4_qa && uf4_qb);
+
+ if (!uf3b)
+ {
+ m_ud3 = m_via_pa;
+ }
+ else if (!m_uf4_qb && uf4_qb)
+ {
+ // shift out bits
+ int ud3_qh = BIT(m_ud3, 0);
+ m_ud3 >>= 1;
+
+ int uf5b = !(!uf4_qb && ud3_qh);
+
+ if (!m_oe && m_wp)
+ {
+ // TODO write bit to disk
+ if (LOG) logerror("WRITE BIT %u\n", uf5b);
+ }
+ }
+
+ // prepare for next cycle
+
+ if (m_block_sync != block_sync)
+ {
+ m_block_sync = block_sync;
+ m_out_sync_func(m_block_sync);
+ }
+
+ if (m_byte_sync != byte_sync)
+ {
+ m_byte_sync = byte_sync;
+
+ if (m_accl)
+ {
+ if (!byte_sync)
+ {
+ m_accl_yb = m_ud2;
+ m_accl_byte_sync = byte_sync;
+ m_out_byte_func(m_accl_byte_sync);
+ }
+ }
+ else
+ {
+ m_out_byte_func(m_byte_sync);
+ }
+ }
+
+ m_uf4_qb = uf4_qb;
+
+ m_bit_sync = 0;
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// c64h156_device - constructor
+//-------------------------------------------------
+
+c64h156_device::c64h156_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, C64H156, "64H156", tag, owner, clock, "c64h156", __FILE__),
+ device_execute_interface(mconfig, *this),
+ m_icount(0),
+ m_floppy(NULL),
+ m_track_buffer(*this, "track_buffer"),
+ m_speed_buffer(*this, "speed_buffer"),
+ m_side(0),
+ m_track_len(0),
+ m_buffer_pos(0),
+ m_bit_pos(0),
+ m_bit_count(0),
+ m_mtr(0),
+ m_accl(0),
+ m_ds(0),
+ m_soe(0),
+ m_oe(0),
+ m_atni(1),
+ m_atna(1),
+ m_last_bit_sync(0),
+ m_bit_sync(0),
+ m_byte_sync(1),
+ m_accl_byte_sync(1),
+ m_block_sync(1),
+ m_ue7(0),
+ m_ue7_tc(0),
+ m_uf4(0),
+ m_uf4_qb(0),
+ m_ud2(0),
+ m_accl_yb(0),
+ m_u4a(0),
+ m_u4b(0),
+ m_ue3(0),
+ m_uc1b(0),
+ m_wp(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void c64h156_device::device_start()
+{
+ // set our instruction counter
+ m_icountptr = &m_icount;
+
+ // allocate track buffer
+ m_track_buffer.allocate(G64_BUFFER_SIZE);
+ m_speed_buffer.allocate(G64_SPEED_BLOCK_SIZE);
+
+ // resolve callbacks
+ m_out_atn_func.resolve(m_out_atn_cb, *this);
+ m_out_sync_func.resolve(m_out_sync_cb, *this);
+ m_out_byte_func.resolve(m_out_byte_cb, *this);
+
+ // register for state saving
+ save_item(NAME(m_shift));
+ save_item(NAME(m_side));
+ save_item(NAME(m_track_len));
+ save_item(NAME(m_buffer_pos));
+ save_item(NAME(m_bit_pos));
+ save_item(NAME(m_bit_count));
+ save_item(NAME(m_cycles_until_next_bit));
+ save_item(NAME(m_zero_count));
+ save_item(NAME(m_cycles_until_random_flux));
+ save_item(NAME(m_mtr));
+ save_item(NAME(m_accl));
+ save_item(NAME(m_ds));
+ save_item(NAME(m_soe));
+ save_item(NAME(m_oe));
+ save_item(NAME(m_atni));
+ save_item(NAME(m_atna));
+ save_item(NAME(m_last_bit_sync));
+ save_item(NAME(m_bit_sync));
+ save_item(NAME(m_byte_sync));
+ save_item(NAME(m_accl_byte_sync));
+ save_item(NAME(m_block_sync));
+ save_item(NAME(m_ue7));
+ save_item(NAME(m_ue7_tc));
+ save_item(NAME(m_uf4));
+ save_item(NAME(m_uf4_qb));
+ save_item(NAME(m_ud2));
+ save_item(NAME(m_accl_yb));
+ save_item(NAME(m_u4a));
+ save_item(NAME(m_u4b));
+ save_item(NAME(m_ue3));
+ save_item(NAME(m_uc1b));
+ save_item(NAME(m_via_pa));
+ save_item(NAME(m_ud3));
+ save_item(NAME(m_wp));
+}
+
+
+//-------------------------------------------------
+// execute_run -
+//-------------------------------------------------
+
+void c64h156_device::execute_run()
+{
+ do
+ {
+ if (m_mtr)
+ {
+ receive_bit();
+ }
+
+ decode_bit();
+
+ m_icount--;
+ } while (m_icount > 0);
+}
+
+
+//-------------------------------------------------
+// yb_r -
+//-------------------------------------------------
+
+READ8_MEMBER( c64h156_device::yb_r )
+{
+ UINT8 data = 0;
+
+ if (m_soe)
+ {
+ if (m_accl)
+ {
+ data = m_accl_yb;
+ }
+ else
+ {
+ data = m_ud2;
+ }
+ }
+
+ if (LOG) logerror("%s YB read %02x:%02x\n", machine().describe_context(), m_ud2, data);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// yb_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( c64h156_device::yb_w )
+{
+ m_via_pa = data;
+}
+
+
+//-------------------------------------------------
+// test_w - test write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::test_w )
+{
+}
+
+
+//-------------------------------------------------
+// accl_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::accl_w )
+{
+ m_accl = state;
+}
+
+
+//-------------------------------------------------
+// sync_r - sync read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( c64h156_device::sync_r )
+{
+ return m_block_sync;
+}
+
+
+//-------------------------------------------------
+// byte_r - byte ready read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( c64h156_device::byte_r )
+{
+ int state = 1;
+
+ if (m_accl)
+ {
+ state = m_accl_byte_sync;
+ }
+ else
+ {
+ state = m_byte_sync;
+ }
+
+ return state;
+}
+
+
+//-------------------------------------------------
+// ted_w -
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::ted_w )
+{
+ if (m_accl && !m_accl_byte_sync && !state)
+ {
+ m_accl_byte_sync = 1;
+ m_out_byte_func(m_accl_byte_sync);
+ }
+}
+
+
+//-------------------------------------------------
+// mtr_w - motor write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::mtr_w )
+{
+ if (m_mtr != state)
+ {
+ if (LOG) logerror("MTR %u\n", state);
+
+ if (state)
+ {
+ // read track data
+ read_current_track();
+ }
+
+ floppy_mon_w(m_floppy, !state);
+
+ m_mtr = state;
+ }
+}
+
+
+//-------------------------------------------------
+// oe_w - output enable write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::oe_w )
+{
+ if (LOG) logerror("OE %u\n", state);
+
+ m_oe = state;
+}
+
+
+//-------------------------------------------------
+// soe_w - SO enable write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::soe_w )
+{
+ if (LOG) logerror("SOE %u\n", state);
+
+ m_soe = state;
+}
+
+
+//-------------------------------------------------
+// atn_r - serial attention read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( c64h156_device::atn_r )
+{
+ return ATN;
+}
+
+
+//-------------------------------------------------
+// atni_w - serial attention input write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::atni_w )
+{
+ if (LOG) logerror("ATNI %u\n", state);
+
+ m_atni = state;
+
+ set_atn_line();
+}
+
+
+//-------------------------------------------------
+// atna_w - serial attention acknowledge write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( c64h156_device::atna_w )
+{
+ if (LOG) logerror("ATNA %u\n", state);
+
+ m_atna = state;
+
+ set_atn_line();
+}
+
+
+//-------------------------------------------------
+// set_floppy -
+//-------------------------------------------------
+
+void c64h156_device::set_floppy(legacy_floppy_image_device *floppy)
+{
+ m_floppy = floppy;
+
+ // install image callbacks
+ floppy_install_unload_proc(m_floppy, c64h156_device::on_disk_change);
+ floppy_install_load_proc(m_floppy, c64h156_device::on_disk_change);
+}
+
+
+//-------------------------------------------------
+// stp_w -
+//-------------------------------------------------
+
+void c64h156_device::stp_w(int data)
+{
+ if (m_mtr)
+ {
+ int track = floppy_drive_get_current_track(m_floppy);
+ int tracks = (data - track) & 0x03;
+
+ if (tracks == 3)
+ {
+ tracks = -1;
+ }
+
+ if (tracks == -1 || tracks == 1)
+ {
+ // step read/write head
+ floppy_drive_seek(m_floppy, tracks);
+
+ // read new track data
+ read_current_track();
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// ds_w - density select
+//-------------------------------------------------
+
+void c64h156_device::ds_w(int data)
+{
+ m_ds = data;
+}
+
+
+//-------------------------------------------------
+// set_side -
+//-------------------------------------------------
+
+void c64h156_device::set_side(int side)
+{
+ if (m_side != side)
+ {
+ m_side = side;
+
+ // read new track data
+ read_current_track();
+ }
+}
+
+
+//-------------------------------------------------
+// on_disk_change -
+//-------------------------------------------------
+
+void c64h156_device::on_disk_change(device_image_interface &image)
+{
+ //m_wp = !floppy_wpt_r(image);
+
+ //read_current_track();
+}
diff --git a/src/emu/machine/64h156.h b/src/emu/machine/64h156.h
new file mode 100644
index 00000000000..bd1bd327c0c
--- /dev/null
+++ b/src/emu/machine/64h156.h
@@ -0,0 +1,210 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Commodore 64H156 Gate Array emulation
+
+ Used in 1541B/1541C/1541-II/1551/1571
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ TEST 1 |* \_/ | 40 _BYTE
+ YB0 2 | | 39 SOE
+ YB1 3 | | 38 B
+ YB2 4 | | 37 CK
+ YB3 5 | | 36 _QX
+ YB4 6 | | 35 Q
+ YB5 7 | | 34 R/_W
+ YB6 8 | | 33 LOCK
+ YB7 9 | | 32 PLL
+ Vss 10 | 64H156-01 | 31 CLR
+ STP1 11 | 251828-01 | 30 Vcc
+ STP0 12 | | 29 _XRW
+ MTR 13 | | 28 Y3
+ _A 14 | | 27 Y2
+ DS0 15 | | 26 Y1
+ DS1 16 | | 25 Y0
+ _SYNC 17 | | 24 ATN
+ TED 18 | | 23 ATNI
+ OE 19 | | 22 ATNA
+ _ACCL 20 |_____________| 21 OSC
+
+ _____ _____
+ TEST 1 |* \_/ | 42 _BYTE
+ YB0 2 | | 41 SOE
+ YB1 3 | | 40 B
+ YB2 4 | | 39 CK
+ YB3 5 | | 38 _QX
+ YB4 6 | | 37 Q
+ YB5 7 | | 36 R/_W
+ YB6 8 | | 35 LOCK
+ YB7 9 | | 34 PLL
+ Vss 10 | 64H156-02 | 33 CLR
+ STP1 11 | 251828-02 | 32 Vcc
+ STP0 12 | | 31 _XRW
+ MTR 13 | | 30 Y3
+ _A 14 | | 29 Y2
+ DS0 15 | | 28 Y1
+ DS1 16 | | 27 Y0
+ _SYNC 17 | | 26 ATN
+ TED 18 | | 25 ATNI
+ OE 19 | | 24 ATNA
+ _ACCL 20 | | 23 OSC
+ Vcc 21 |_____________| 22 Vss
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __C64H156__
+#define __C64H156__
+
+
+#include "emu.h"
+#include "imagedev/flopdrv.h"
+#include "formats/d64_dsk.h"
+#include "formats/g64_dsk.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_64H156_ADD(_tag, _clock, _config) \
+ MCFG_DEVICE_ADD(_tag, C64H156, _clock) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define C64H156_INTERFACE(_name) \
+ const c64h156_interface (_name) =
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> c64h156_interface
+
+struct c64h156_interface
+{
+ devcb_write_line m_out_atn_cb;
+ devcb_write_line m_out_sync_cb;
+ devcb_write_line m_out_byte_cb;
+};
+
+// ======================> c64h156_device
+
+class c64h156_device : public device_t,
+ public device_execute_interface,
+ public c64h156_interface
+{
+public:
+ // construction/destruction
+ c64h156_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ8_MEMBER( yb_r );
+ DECLARE_WRITE8_MEMBER( yb_w );
+ DECLARE_WRITE_LINE_MEMBER( test_w );
+ DECLARE_WRITE_LINE_MEMBER( accl_w );
+ DECLARE_READ_LINE_MEMBER( sync_r );
+ DECLARE_READ_LINE_MEMBER( byte_r );
+ DECLARE_WRITE_LINE_MEMBER( ted_w );
+ DECLARE_WRITE_LINE_MEMBER( mtr_w );
+ DECLARE_WRITE_LINE_MEMBER( oe_w );
+ DECLARE_WRITE_LINE_MEMBER( soe_w );
+ DECLARE_READ_LINE_MEMBER( atn_r );
+ DECLARE_WRITE_LINE_MEMBER( atni_w );
+ DECLARE_WRITE_LINE_MEMBER( atna_w );
+
+ void set_floppy(legacy_floppy_image_device *floppy);
+
+ void stp_w(int data);
+ void ds_w(int data);
+ void set_side(int side);
+
+ static void on_disk_change(device_image_interface &image);
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+
+ // device_execute_interface overrides
+ virtual void execute_run();
+
+ int m_icount;
+
+ inline void set_atn_line();
+ inline void read_current_track();
+ inline void update_cycles_until_next_bit();
+ inline void receive_bit();
+ inline void decode_bit();
+
+private:
+ devcb_resolved_write_line m_out_atn_func;
+ devcb_resolved_write_line m_out_sync_func;
+ devcb_resolved_write_line m_out_byte_func;
+
+ legacy_floppy_image_device *m_floppy;
+ optional_shared_ptr<UINT8> m_track_buffer; // track data buffer
+ optional_shared_ptr<UINT8> m_speed_buffer; // speed block buffer
+
+ // track
+ UINT16 m_shift;
+ int m_side; // disk side
+ int m_track_len; // track length
+ offs_t m_buffer_pos; // current byte position within track buffer
+ int m_bit_pos; // current bit position within track buffer byte
+ int m_bit_count; // current data byte bit counter
+ int m_cycles_until_next_bit;
+ int m_zero_count;
+ int m_cycles_until_random_flux;
+
+ // motors
+ int m_mtr; // spindle motor on
+
+ // signals
+ int m_accl; // 1/2 MHz select
+ int m_ds; // density select
+ int m_soe; // serial output enable
+ int m_oe; // output enable (0 = write, 1 = read)
+
+ // IEC
+ int m_atni; // attention input
+ int m_atna; // attention acknowledge
+
+ // read logic
+ int m_last_bit_sync;
+ int m_bit_sync;
+ int m_byte_sync;
+ int m_accl_byte_sync;
+ int m_block_sync;
+ int m_ue7;
+ int m_ue7_tc;
+ int m_uf4;
+ int m_uf4_qb;
+ UINT8 m_ud2;
+ UINT8 m_accl_yb;
+ int m_u4a;
+ int m_u4b;
+ int m_ue3;
+ int m_uc1b;
+
+ // write logic
+ UINT8 m_via_pa;
+ UINT8 m_ud3;
+ int m_wp;
+};
+
+
+
+// device type definition
+extern const device_type C64H156;
+
+
+
+#endif
diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak
index 94e1ffb9fab..00ddeace905 100644
--- a/src/emu/machine/machine.mak
+++ b/src/emu/machine/machine.mak
@@ -921,6 +921,33 @@ endif
#-------------------------------------------------
#
+#@src/emu/machine/mos6702.h,MACHINES += MOS6702
+#-------------------------------------------------
+
+ifneq ($(filter MOS6702,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/mos6702.o
+endif
+
+#-------------------------------------------------
+#
+#@src/emu/machine/mos8706.h,MACHINES += MOS8706
+#-------------------------------------------------
+
+ifneq ($(filter MOS8706,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/mos8706.o
+endif
+
+#-------------------------------------------------
+#
+#@src/emu/machine/mos8722.h,MACHINES += MOS8722
+#-------------------------------------------------
+
+ifneq ($(filter MOS8722,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/mos8722.o
+endif
+
+#-------------------------------------------------
+#
#@src/emu/machine/mos8726.h,MACHINES += MOS8726
#-------------------------------------------------
@@ -1116,6 +1143,15 @@ endif
#-------------------------------------------------
#
+#@src/emu/machine/64h156.h,MACHINES += RP5C15
+#-------------------------------------------------
+
+ifneq ($(filter R64H156,$(MACHINES)),)
+MACHINEOBJS += $(MACHINEOBJ)/64h156.o
+endif
+
+#-------------------------------------------------
+#
#@src/emu/machine/rtc4543.h,MACHINES += RTC4543
#-------------------------------------------------
diff --git a/src/emu/machine/mos6702.c b/src/emu/machine/mos6702.c
new file mode 100644
index 00000000000..b6e1aeb1f20
--- /dev/null
+++ b/src/emu/machine/mos6702.c
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 6702 Mystery Device emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "mos6702.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type MOS6702 = &device_creator<mos6702_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mos6702_device - constructor
+//-------------------------------------------------
+
+mos6702_device::mos6702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MOS6702, "MOS6702", tag, owner, clock, "mos6702", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mos6702_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( mos6702_device::read )
+{
+ return 0;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( mos6702_device::write )
+{
+}
diff --git a/src/emu/machine/mos6702.h b/src/emu/machine/mos6702.h
new file mode 100644
index 00000000000..879f90df2bf
--- /dev/null
+++ b/src/emu/machine/mos6702.h
@@ -0,0 +1,69 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 6702 Mystery Device emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ R/_W 1 |* \_/ | 20 Vcc
+ D7 2 | | 19 CS0
+ D6 3 | | 18 CS1
+ D5 4 | | 17 CS2
+ D4 5 | MOS6702 | 16 CS3
+ D3 6 | | 15 _CS4
+ D2 7 | | 14 _CS5
+ D1 8 | | 13 _CS5
+ D0 9 | | 12 _RTS
+ Vss 10 |_____________| 11 phi2
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __MOS6702__
+#define __MOS6702__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS6702_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD(_tag, MOS6702, _clock)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mos6702_device
+
+class mos6702_device : public device_t
+{
+public:
+ // construction/destruction
+ mos6702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+};
+
+
+// device type definition
+extern const device_type MOS6702;
+
+
+
+#endif
diff --git a/src/emu/machine/mos8706.c b/src/emu/machine/mos8706.c
new file mode 100644
index 00000000000..699aa6e7bc7
--- /dev/null
+++ b/src/emu/machine/mos8706.c
@@ -0,0 +1,81 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS 8706 Speech Glue Logic ASIC emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "mos8706.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+// device type definition
+const device_type MOS8706 = &device_creator<mos8706_device>;
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mos8706_device - constructor
+//-------------------------------------------------
+
+mos8706_device::mos8706_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MOS8706, "MOS8706", tag, owner, clock, "mos8706", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mos8706_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mos8706_device::device_reset()
+{
+}
+
+
+//-------------------------------------------------
+// read -
+//-------------------------------------------------
+
+READ8_MEMBER( mos8706_device::read )
+{
+ return 0;
+}
+
+
+//-------------------------------------------------
+// write -
+//-------------------------------------------------
+
+WRITE8_MEMBER( mos8706_device::write )
+{
+}
diff --git a/src/emu/machine/mos8706.h b/src/emu/machine/mos8706.h
new file mode 100644
index 00000000000..1138dab0f8b
--- /dev/null
+++ b/src/emu/machine/mos8706.h
@@ -0,0 +1,73 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS 8706 Speech Glue Logic ASIC emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ _RES 1 |* \_/ | 28 Vdd
+ _IRQ 2 | | 27 D0
+ R/_W 3 | | 26 T6721A D0
+ phi0 4 | | 25 D1
+ _CS 5 | | 24 T6721A D1
+ A0 6 | | 23 D2
+ A1 7 | MOS8706 | 22 T6721A D2
+ 8 | | 21 D3
+ _EOS 9 | | 20 T6721A D3
+ APD 10 | | 19 D4
+ phi2 11 | | 18 D5
+ DI 12 | | 17 D6
+ DTRD 13 | | 16 D7
+ GND 14 |_____________| 15 _WR
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __MOS8706__
+#define __MOS8706__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS8706_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD((_tag), MOS8706, _clock)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mos8706_device
+
+class mos8706_device : public device_t
+{
+public:
+ mos8706_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER( write );
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+};
+
+
+// device type definition
+extern const device_type MOS8706;
+
+
+
+#endif
diff --git a/src/emu/machine/mos8722.c b/src/emu/machine/mos8722.c
new file mode 100644
index 00000000000..b74f0e0815c
--- /dev/null
+++ b/src/emu/machine/mos8722.c
@@ -0,0 +1,429 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 8722 Memory Management Unit emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************/
+
+#include "mos8722.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define LOG 0
+
+
+// registers
+enum
+{
+ CR = 0,
+ PCRA, LCRA = PCRA,
+ PCRB, LCRB = PCRB,
+ PCRC, LCRC = PCRC,
+ PCRD, LCRD = PCRD,
+ MCR,
+ RCR,
+ P0L,
+ P0H,
+ P1L,
+ P1H,
+ VR
+};
+
+
+// configuration register
+enum
+{
+ CR_IO_SYSTEM_IO = 0,
+ CR_IO_HI_ROM
+};
+
+enum
+{
+ CR_ROM_SYSTEM_ROM = 0,
+ CR_ROM_INT_FUNC_ROM,
+ CR_ROM_EXT_FUNC_ROM,
+ CR_ROM_RAM
+};
+
+#define CR_IO BIT(m_reg[CR], 0)
+#define CR_ROM_LO BIT(m_reg[CR], 1)
+#define CR_ROM_MID ((m_reg[CR] >> 2) & 0x03)
+#define CR_ROM_HI ((m_reg[CR] >> 4) & 0x03)
+#define CR_A16 BIT(m_reg[CR], 6)
+
+
+// mode configuration register
+#define MCR_8500 BIT(m_reg[MCR], 0)
+#define MCR_FSDIR BIT(m_reg[MCR], 3)
+#define MCR_GAME BIT(m_reg[MCR], 4)
+#define MCR_EXROM BIT(m_reg[MCR], 5)
+#define MCR_C64 BIT(m_reg[MCR], 6)
+#define MCR_40_80 BIT(m_reg[MCR], 7)
+
+
+// RAM configuration register
+static const offs_t RCR_BOTTOM_ADDRESS[4] = { 0x0400, 0x1000, 0x0400, 0x1000 };
+static const offs_t RCR_TOP_ADDRESS[4] = { 0xf000, 0xf000, 0xe000, 0xc000 };
+
+enum
+{
+ RCR_SHARE_1K = 0,
+ RCR_SHARE_4K,
+ RCR_SHARE_8K,
+ RCR_SHARE_16K
+};
+
+#define RCR_SHARE (m_reg[RCR] & 0x03)
+#define RCR_BOTTOM BIT(m_reg[RCR], 2)
+#define RCR_TOP BIT(m_reg[RCR], 3)
+#define RCR_VA16 BIT(m_reg[RCR], 6)
+
+
+// page 0 pointer register
+#define P0H_A16 BIT(m_reg[P0H], 0)
+
+
+// page 1 pointer register
+#define P1H_A16 BIT(m_reg[P1H], 0)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type MOS8722 = &device_creator<mos8722_device>;
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// mos8722_device - constructor
+//-------------------------------------------------
+
+mos8722_device::mos8722_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MOS8722, "MOS8722", tag, owner, clock, "mos8722", __FILE__)
+{
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void mos8722_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const mos8722_interface *intf = reinterpret_cast<const mos8722_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<mos8722_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_z80en_cb, 0, sizeof(m_out_z80en_cb));
+ memset(&m_out_fsdir_cb, 0, sizeof(m_out_fsdir_cb));
+ memset(&m_in_game_cb, 0, sizeof(m_in_game_cb));
+ memset(&m_in_exrom_cb, 0, sizeof(m_in_exrom_cb));
+ memset(&m_in_sense40_cb, 0, sizeof(m_in_sense40_cb));
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void mos8722_device::device_start()
+{
+ // resolve callbacks
+ m_out_z80en_func.resolve(m_out_z80en_cb, *this);
+ m_out_fsdir_func.resolve(m_out_fsdir_cb, *this);
+ m_in_game_func.resolve(m_in_game_cb, *this);
+ m_in_exrom_func.resolve(m_in_exrom_cb, *this);
+ m_in_sense40_func.resolve(m_in_sense40_cb, *this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void mos8722_device::device_reset()
+{
+ for (int i = 0; i < 16; i++)
+ {
+ m_reg[i] = 0;
+ }
+
+ m_reg[P1L] = 0x01;
+
+ m_p0h_latch = 0;
+ m_p1h_latch = 0;
+
+ m_out_z80en_func(MCR_8500);
+ m_out_fsdir_func(MCR_FSDIR);
+}
+
+
+//-------------------------------------------------
+// read - register read
+//-------------------------------------------------
+
+UINT8 mos8722_device::read(offs_t offset, UINT8 data)
+{
+ if (MCR_C64) return data;
+
+ if (!CR_IO && offset >= 0xd500 && offset < 0xd50c)
+ {
+ switch (offset & 0x0f)
+ {
+ case CR:
+ data = m_reg[CR] | 0x80;
+ break;
+
+ case MCR:
+ data = m_reg[MCR] | 0x06;
+
+ data &= ((m_in_game_func() << 4) | ~0x10);
+ data &= ((m_in_exrom_func() << 5) | ~0x20);
+ data &= ((m_in_sense40_func() << 7) | ~0x80);
+ break;
+
+ case VR:
+ data = 0x20;
+ break;
+
+ default:
+ data = m_reg[offset & 0x0f];
+ break;
+ }
+ }
+ else if (offset >= 0xff00 && offset < 0xff05)
+ {
+ switch (offset & 0x0f)
+ {
+ case CR:
+ data = m_reg[CR] | 0x80;
+ break;
+
+ default:
+ data = m_reg[offset & 0x0f];
+ break;
+ }
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write - register write
+//-------------------------------------------------
+
+WRITE8_MEMBER( mos8722_device::write )
+{
+ if (MCR_C64) return;
+
+ if (!CR_IO && offset >= 0xd500 && offset < 0xd50c)
+ {
+ if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data);
+
+ switch (offset & 0x0f)
+ {
+ case CR:
+ m_reg[CR] = data & 0x7f;
+ break;
+
+ case PCRA:
+ case PCRB:
+ case PCRC:
+ case PCRD:
+ m_reg[offset & 0x0f] = data & 0x7f;
+ break;
+
+ case MCR:
+ {
+ int _8500 = MCR_8500;
+ int fsdir = MCR_FSDIR;
+
+ m_reg[MCR] = data;
+
+ if (_8500 != MCR_8500) m_out_z80en_func(MCR_8500);
+ if (fsdir != MCR_FSDIR) m_out_fsdir_func(MCR_FSDIR);
+ break;
+ }
+
+ case RCR:
+ m_reg[RCR] = data & 0x4f;
+ break;
+
+ case P0L:
+ m_reg[P0L] = data;
+ m_reg[P0H] = m_p0h_latch;
+ break;
+
+ case P0H:
+ m_p0h_latch = data & 0x01;
+ break;
+
+ case P1L:
+ m_reg[P1L] = data;
+ m_reg[P1H] = m_p1h_latch;
+ break;
+
+ case P1H:
+ m_p1h_latch = data & 0x01;
+ break;
+
+ default:
+ m_reg[offset & 0x0f] = data;
+ }
+ }
+ else if (offset >= 0xff00 && offset < 0xff05)
+ {
+ if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data);
+
+ switch (offset & 0x0f)
+ {
+ case CR:
+ m_reg[CR] = data & 0x7f;
+ break;
+
+ default:
+ m_reg[CR] = m_reg[offset & 0x0f];
+ break;
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// fsdir_r - fast serial direction read
+//-------------------------------------------------
+
+READ_LINE_MEMBER( mos8722_device::fsdir_r )
+{
+ return MCR_FSDIR;
+}
+
+
+//-------------------------------------------------
+// ta_r - translated address read
+//-------------------------------------------------
+
+offs_t mos8722_device::ta_r(offs_t offset, int aec, int *ms0, int *ms1, int *ms2, int *ms3, int *cas0, int *cas1)
+{
+ offs_t ta;
+
+ *ms0 = 1;
+ *ms1 = 1;
+ *ms2 = CR_IO;
+ *ms3 = !MCR_C64;
+
+ if (aec)
+ {
+ // CPU access
+ ta = offset & 0xff00;
+
+ *cas0 = CR_A16;
+ *cas1 = !*cas0;
+
+ if (!MCR_C64)
+ {
+ if (offset >= 0xff00 && offset < 0xff05)
+ {
+ // MMU registers
+ *cas0 = 1;
+ *cas1 = 1;
+ }
+ else if (!MCR_8500 && !CR_A16 && offset < 0x1000)
+ {
+ // Z80 ROM
+ ta = 0xd000 | (offset & 0xf00);
+
+ *ms0 = 0;
+ *ms1 = 0;
+ }
+ else
+ {
+ if (offset < 0x0100)
+ {
+ // page 0 pointer
+ ta = m_reg[P0L] << 8;
+
+ *cas0 = P0H_A16;
+ *cas1 = !*cas0;
+ }
+ else if (offset < 0x0200)
+ {
+ // page 1 pointer
+ ta = m_reg[P1L] << 8;
+
+ *cas0 = P1H_A16;
+ *cas1 = !*cas0;
+ }
+ else if (offset >= 0x4000 && offset < 0x8000)
+ {
+ // low ROM
+ *ms0 = CR_ROM_LO;
+ *ms1 = CR_ROM_LO;
+ }
+ else if (offset >= 0x8000 && offset < 0xc000)
+ {
+ // middle ROM
+ *ms0 = BIT(CR_ROM_MID, 1);
+ *ms1 = BIT(CR_ROM_MID, 0);
+ }
+ else if (offset >= 0xc000)
+ {
+ // high ROM
+ *ms0 = BIT(CR_ROM_HI, 1);
+ *ms1 = BIT(CR_ROM_HI, 0);
+ }
+
+ if (*ms0 && *ms1)
+ {
+ if ((offset >> 8) == m_reg[P0L])
+ {
+ ta = 0x0000;
+ }
+ else if ((offset >> 8) == m_reg[P1L])
+ {
+ ta = 0x0100;
+ }
+ }
+
+ if ((RCR_BOTTOM && offset < RCR_BOTTOM_ADDRESS[RCR_SHARE]) ||
+ (RCR_TOP && offset >= RCR_TOP_ADDRESS[RCR_SHARE]))
+ {
+ // RAM sharing
+ *cas0 = 0;
+ *cas1 = !*cas0;
+ }
+ }
+ }
+ }
+ else
+ {
+ // VIC access
+ ta = 0xf000 | (offset & 0xf00);
+
+ *cas0 = RCR_VA16;
+ *cas1 = !*cas0;
+ }
+
+ return ta;
+}
diff --git a/src/emu/machine/mos8722.h b/src/emu/machine/mos8722.h
new file mode 100644
index 00000000000..b4dc13c8c9b
--- /dev/null
+++ b/src/emu/machine/mos8722.h
@@ -0,0 +1,119 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MOS Technology 8722 Memory Management Unit emulation
+
+ Copyright MESS Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+**********************************************************************
+ _____ _____
+ Vdd 1 |* \_/ | 48 SENSE40
+ _RESET 2 | | 47 (MS3) 128/64
+ TA15 3 | | 46 _EXROM
+ TA14 4 | | 45 _GAME
+ TA13 5 | | 44 FSDIR
+ TA12 6 | | 43 _Z80EN
+ TA11 7 | | 42 D7
+ TA10 8 | | 41 D6
+ TA9 9 | | 40 D5
+ TA8 10 | | 39 D4
+ _CAS1 11 | | 38 D3
+ _CAS0 12 | MOS8722 | 37 D2
+ I/O SEL (MS2) 13 | | 36 D1
+ ROMBANK1 (MS1) 14 | | 35 D0
+ ROMBANK0 (MS0) 15 | | 34 Vss
+ AEC 16 | | 33 phi0
+ MUX 17 | | 32 R/_W
+ A0 18 | | 31 A15
+ A1 19 | | 30 A14
+ A2 20 | | 29 A13
+ A3 21 | | 28 A12
+ A4/A5 22 | | 27 A11
+ A6/A7 23 | | 26 A10
+ A8 24 |_____________| 25 A9
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef __MOS8722__
+#define __MOS8722__
+
+#include "emu.h"
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_MOS8722_ADD(_tag, _config) \
+ MCFG_DEVICE_ADD(_tag, MOS8722, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+
+#define MOS8722_INTERFACE(name) \
+ const mos8722_interface (name) =
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> mos8722_interface
+
+struct mos8722_interface
+{
+ devcb_write_line m_out_z80en_cb;
+ devcb_write_line m_out_fsdir_cb;
+ devcb_read_line m_in_game_cb;
+ devcb_read_line m_in_exrom_cb;
+ devcb_read_line m_in_sense40_cb;
+};
+
+
+// ======================> mos8722_device
+
+class mos8722_device : public device_t,
+ public mos8722_interface
+{
+public:
+ // construction/destruction
+ mos8722_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ UINT8 read(offs_t offset, UINT8 data);
+ DECLARE_WRITE8_MEMBER( write );
+
+ DECLARE_READ_LINE_MEMBER( fsdir_r );
+
+ offs_t ta_r(offs_t offset, int aec, int *ms0, int *ms1, int *ms2, int *ms3, int *cas0, int *cas1);
+
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_reset();
+
+private:
+ devcb_resolved_write_line m_out_z80en_func;
+ devcb_resolved_write_line m_out_fsdir_func;
+ devcb_resolved_read_line m_in_game_func;
+ devcb_resolved_read_line m_in_exrom_func;
+ devcb_resolved_read_line m_in_sense40_func;
+
+ UINT8 m_reg[16];
+
+ UINT8 m_p0h_latch;
+ UINT8 m_p1h_latch;
+};
+
+
+// device type definition
+extern const device_type MOS8722;
+
+
+
+#endif