summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mahlemiut <bsr@xnet.co.nz>2017-06-21 18:34:36 +1200
committer mahlemiut <bsr@xnet.co.nz>2017-06-21 18:37:23 +1200
commit03f21234b8e8cfbffa8f0199696307246122de31 (patch)
tree67d0a775958c287c8debc37c944b5e4984b35c45
parente6f86fa6738ae3d108da1e0d28e3b09ceb9cc989 (diff)
- Add preliminary Yamaha YM3802 MIDI controller
- Add X68000 expansion device using the YM3802
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--src/devices/bus/x68k/x68k_midi.cpp66
-rw-r--r--src/devices/bus/x68k/x68k_midi.h48
-rw-r--r--src/devices/bus/x68k/x68kexp.h10
-rw-r--r--src/devices/machine/ym3802.cpp286
-rw-r--r--src/devices/machine/ym3802.h164
-rw-r--r--src/mame/drivers/x68k.cpp12
-rw-r--r--src/mame/includes/x68k.h4
9 files changed, 601 insertions, 3 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 7e420e913b8..7ae85734f1e 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2631,6 +2631,8 @@ if (BUSES["X68K"]~=null) then
MAME_DIR .. "src/devices/bus/x68k/x68k_neptunex.h",
MAME_DIR .. "src/devices/bus/x68k/x68k_scsiext.cpp",
MAME_DIR .. "src/devices/bus/x68k/x68k_scsiext.h",
+ MAME_DIR .. "src/devices/bus/x68k/x68k_midi.cpp",
+ MAME_DIR .. "src/devices/bus/x68k/x68k_midi.h",
}
end
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index b69727f1475..0b212b50d43 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -2683,6 +2683,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/ym3802.h,MACHINES["YM3802"] = true
+---------------------------------------------------
+
+if (MACHINES["YM3802"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/ym3802.cpp",
+ MAME_DIR .. "src/devices/machine/ym3802.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/z80ctc.h,MACHINES["Z80CTC"] = true
---------------------------------------------------
diff --git a/src/devices/bus/x68k/x68k_midi.cpp b/src/devices/bus/x68k/x68k_midi.cpp
new file mode 100644
index 00000000000..04b402f3843
--- /dev/null
+++ b/src/devices/bus/x68k/x68k_midi.cpp
@@ -0,0 +1,66 @@
+// license:BSD-3-Clause
+// copyright-holders:Barry Rodewald
+/*
+ * x68k_midi.c
+ *
+ * X68000 MIDI interface - YM3802
+ *
+ */
+
+#include "emu.h"
+#include "bus/midi/midi.h"
+#include "x68k_midi.h"
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(X68K_MIDI, x68k_midi_device, "x68k_midi", "X68000 MIDI Interface")
+
+MACHINE_CONFIG_MEMBER( x68k_midi_device::device_add_mconfig )
+ MCFG_DEVICE_ADD("midi", YM3802, XTAL_1MHz) // clock is unknown
+ MCFG_YM3802_TXD_HANDLER(DEVWRITELINE("mdout",midi_port_device,write_txd))
+ MCFG_YM3802_IRQ_HANDLER(WRITELINE(x68k_midi_device,irq_w))
+ MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin")
+ MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout")
+// MCFG_MIDI_PORT_ADD("mdthru", midiout_slot, "midiout")
+ // TODO: Add serial data handlers
+
+MACHINE_CONFIG_END
+
+
+x68k_midi_device::x68k_midi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, X68K_MIDI, tag, owner, clock)
+ , device_x68k_expansion_card_interface(mconfig, *this)
+ , m_slot(nullptr)
+ , m_midi(*this, "midi")
+{
+}
+
+void x68k_midi_device::device_start()
+{
+ device_t* cpu = machine().device("maincpu");
+ address_space& space = cpu->memory().space(AS_PROGRAM);
+ m_slot = dynamic_cast<x68k_expansion_slot_device *>(owner());
+ space.install_readwrite_handler(0xeafa00,0xeafa0f,read8_delegate(FUNC(x68k_midi_device::x68k_midi_reg_r),this),write8_delegate(FUNC(x68k_midi_device::x68k_midi_reg_w),this),0x00ff00ff);
+}
+
+void x68k_midi_device::device_reset()
+{
+}
+
+READ8_MEMBER(x68k_midi_device::x68k_midi_reg_r)
+{
+ return m_midi->read(space, offset);
+}
+
+WRITE8_MEMBER(x68k_midi_device::x68k_midi_reg_w)
+{
+ m_midi->write(space, offset, data);
+}
+
+void x68k_midi_device::irq_w(int state)
+{
+ set_vector(MIDI_IRQ_VECTOR | (m_midi->vector() & 0x1f));
+ m_slot->irq4_w(state); // selectable between IRQ2 and IRQ4
+}
diff --git a/src/devices/bus/x68k/x68k_midi.h b/src/devices/bus/x68k/x68k_midi.h
new file mode 100644
index 00000000000..e6c467620a8
--- /dev/null
+++ b/src/devices/bus/x68k/x68k_midi.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Barry Rodewald
+/*
+ * x68k_midi.h
+ *
+ * X68000 MIDI expansion card
+ *
+ */
+
+#ifndef MAME_BUS_X68K_X68K_MIDI_H
+#define MAME_BUS_X68K_X68K_MIDI_H
+
+#pragma once
+
+#include "machine/ym3802.h"
+#include "x68kexp.h"
+
+#define MIDI_IRQ_VECTOR 0x80 // does not seem to use the YM3802's vector registers
+
+class x68k_midi_device : public device_t,
+ public device_x68k_expansion_card_interface
+{
+public:
+ // construction/destruction
+ x68k_midi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ DECLARE_READ8_MEMBER(x68k_midi_reg_r);
+ DECLARE_WRITE8_MEMBER(x68k_midi_reg_w);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ x68k_expansion_slot_device *m_slot;
+ required_device<ym3802_device> m_midi;
+ void irq_w(int state);
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(X68K_MIDI, x68k_midi_device)
+
+#endif // MAME_BUS_X68K_X68K_MIDI_H
diff --git a/src/devices/bus/x68k/x68kexp.h b/src/devices/bus/x68k/x68kexp.h
index 5b66685fbed..165dda08a73 100644
--- a/src/devices/bus/x68k/x68kexp.h
+++ b/src/devices/bus/x68k/x68kexp.h
@@ -105,9 +105,15 @@ public:
// reset
virtual void x68k_reset_w() { }
-
+
+ void set_vector(uint8_t vector) { m_vector = vector; }
+ uint8_t vector() { return m_vector; }
+
protected:
device_x68k_expansion_card_interface(const machine_config &mconfig, device_t &device);
+
+private:
+ uint8_t m_vector;
};
@@ -131,6 +137,8 @@ public:
DECLARE_WRITE_LINE_MEMBER( nmi_w );
DECLARE_WRITE_LINE_MEMBER( reset_w );
+ uint8_t vector() { return m_card->vector(); }
+
protected:
// device-level overrides
virtual void device_start() override;
diff --git a/src/devices/machine/ym3802.cpp b/src/devices/machine/ym3802.cpp
new file mode 100644
index 00000000000..6afd4ea9a12
--- /dev/null
+++ b/src/devices/machine/ym3802.cpp
@@ -0,0 +1,286 @@
+// license:BSD-3-Clause
+// copyright-holders:Barry Rodewald
+/*
+ * ym3802.c - Yamaha MCS MIDI Communication and Service Controller
+ *
+ * TODO:
+ * - Receive serial data
+ * - Transmit Idle detection
+ * - IRx/ITx (used for MIDI system messages)
+ * - FSK modulation
+ * - Timers
+ * - Interrupts (except for Tx Buffer Empty)
+ */
+
+#include "emu.h"
+#include "ym3802.h"
+
+
+DEFINE_DEVICE_TYPE(YM3802, ym3802_device, "ym3802", "Yamaha YM3802 MCS MIDI Communication and Service Controller")
+
+ym3802_device::ym3802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, YM3802, tag, owner, clock)
+ , device_serial_interface(mconfig, *this)
+ , m_irq_handler(*this)
+ , m_txd_handler(*this)
+ , m_rxd_handler(*this)
+ , m_reg(REG_MAX)
+ , m_wdr(0)
+ , m_irq_status(0)
+ , m_vector(0)
+ , m_clkm_rate(500000) // TODO: make these configurable
+ , m_clkf_rate(614400)
+ {
+ }
+
+void ym3802_device::device_start()
+{
+ m_irq_handler.resolve_safe();
+ m_txd_handler.resolve_safe();
+ m_rxd_handler.resolve_safe(0xff);
+ m_clock_timer = timer_alloc(TIMER_SYSTEM_CLOCK);
+ m_midi_timer = timer_alloc(TIMER_MIDI_CLOCK);
+ save_item(NAME(m_reg));
+}
+
+void ym3802_device::device_reset()
+{
+ m_reg.clear();
+ reset_irq(0xff);
+ transmit_register_reset();
+ receive_register_reset();
+ reset_midi_timer();
+ set_comms_mode();
+}
+
+void ym3802_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ // TODO: support clock and timers
+ switch(id)
+ {
+ case TIMER_MIDI_CLOCK:
+ transmit_clk();
+ break;
+ }
+}
+
+void ym3802_device::set_irq(uint8_t irq)
+{
+ uint8_t x;
+
+ m_irq_status |= (irq & m_reg[REG_IER]);
+ for(x=0;x<8;x++)
+ {
+ if(m_irq_status & (1 << x))
+ break;
+ }
+ m_vector = (m_reg[REG_IOR] & 0xe0) | (x << 1);
+ if(m_irq_status != 0)
+ m_irq_handler(ASSERT_LINE);
+}
+
+void ym3802_device::reset_irq(uint8_t irq)
+{
+ m_irq_status &= ~irq;
+ if(m_irq_status == 0)
+ m_irq_handler(CLEAR_LINE);
+}
+
+void ym3802_device::transmit_clk()
+{
+ if(m_reg[REG_TCR] & 0x01) // Tx Enable
+ {
+ if(!m_tx_fifo.empty())
+ {
+ if (is_transmit_register_empty())
+ {
+ transmit_register_setup(m_tx_fifo.front()); // start to send first byte in FIFO
+ m_tx_fifo.pop(); // and remove it from the FIFO
+ if(m_tx_fifo.empty())
+ set_irq(IRQ_FIFOTX_EMPTY);
+ }
+ }
+ /* if diserial has bits to send, make them so */
+ if (!is_transmit_register_empty())
+ {
+ uint8_t data = transmit_register_get_data_bit();
+ m_tx_busy = true;
+ m_txd_handler(data);
+ }
+ if (m_tx_fifo.empty() && is_transmit_register_empty())
+ m_tx_busy = false;
+ }
+}
+
+void ym3802_device::reset_midi_timer()
+{
+ uint64_t rate;
+ uint8_t divisor = m_reg[REG_RRR] & 0x1f;
+
+ if(!(divisor & 0x10))
+ {
+ if(divisor & 0x08)
+ rate = m_clkm_rate / 32;
+ else
+ rate = m_clkm_rate / 16;
+ }
+ else
+ {
+ if(!(divisor & 0x08))
+ rate = m_clkf_rate / 32;
+ else
+ {
+ switch(divisor & 0x07)
+ {
+ case 0:
+ rate = m_clkf_rate / 64;
+ break;
+ case 1:
+ rate = m_clkf_rate / 128;
+ break;
+ case 2:
+ rate = m_clkf_rate / 256;
+ break;
+ case 3:
+ rate = m_clkf_rate / 512;
+ break;
+ case 4:
+ rate = m_clkf_rate / 1024;
+ break;
+ case 5:
+ rate = m_clkf_rate / 2048;
+ break;
+ case 6:
+ rate = m_clkf_rate / 4096;
+ break;
+ case 7:
+ rate = m_clkf_rate / 8192;
+ break;
+ }
+ }
+ }
+
+ if(rate != m_prev_rate)
+ m_midi_timer->adjust(attotime::from_hz(rate),0,attotime::from_hz(rate));
+ m_prev_rate = rate;
+ logerror("MIDI Timer rate set to %iHz\n",rate);
+}
+
+void ym3802_device::set_comms_mode()
+{
+ uint8_t data_bits = (m_reg[REG_TMR] & 0x20) ? 7 : 8;
+ parity_t parity;
+ stop_bits_t stop_bits = (m_reg[REG_TMR] & 0x02) ? STOP_BITS_2 : STOP_BITS_1;
+
+ if(!(m_reg[REG_TMR] & 0x10)) // parity enable
+ parity = PARITY_NONE;
+ else
+ {
+ if(m_reg[REG_TMR] & 0x04)
+ parity = PARITY_ODD;
+ else
+ parity = PARITY_EVEN;
+ // TODO: 4-bit parity
+ }
+
+ set_data_frame(1, data_bits, parity, stop_bits);
+ logerror("MIDI comms set to 1 start bit, %i data bits, %s, parity = %i\n",data_bits, (stop_bits == STOP_BITS_2) ? "2 stop bits" : "1 stop bit", parity);
+}
+
+READ8_MEMBER(ym3802_device::read)
+{
+ if(offset < 4)
+ {
+ if(offset == 3)
+ return m_wdr;
+ if(offset == 2)
+ return m_irq_status;
+ if(offset == 0)
+ return m_vector;
+ return m_reg[offset];
+ }
+ else
+ {
+ uint8_t bank = m_reg[REG_RGR] & 0x0f;
+ uint8_t ret = 0;
+
+ if(bank > 9)
+ return m_wdr;
+
+ switch(offset + (bank * 10))
+ {
+ case REG_TSR:
+ if(m_tx_fifo.empty())
+ ret |= 0x80;
+ if(m_tx_fifo.size() < 16)
+ ret |= 0x40;
+ if(m_tx_busy)
+ ret |= 0x01;
+ break;
+ default:
+ ret = m_reg[offset + (bank * 10)];
+ }
+ return ret;
+ }
+}
+
+WRITE8_MEMBER(ym3802_device::write)
+{
+ m_wdr = data;
+ if(offset == 1)
+ {
+ m_reg[REG_RGR] = data & 0x0f;
+ if(data & 0x80)
+ device_reset();
+ logerror("MIDI: writing %02x to reg %i\n",data,offset);
+ }
+ if(offset == 3)
+ reset_irq(data);
+ if(offset > 4)
+ {
+ uint8_t bank = m_reg[REG_RGR] & 0x0f;
+
+ if(bank > 9)
+ return;
+
+ m_reg[offset + (bank * 10)] = data;
+ logerror("MIDI: writing %02x to reg %i\n",data,offset + (bank * 10));
+
+ switch(offset + (bank * 10))
+ {
+ case REG_IOR:
+ popmessage("IOR vector write %02\n",data);
+ break;
+ case REG_IER:
+ logerror("IER set to %02x\n",data);
+ break;
+ case REG_TMR:
+ set_comms_mode();
+ break;
+ case REG_TCR:
+ if(data & 0x01)
+ reset_midi_timer();
+ break;
+ case REG_TDR:
+ m_tx_fifo.push(data);
+ reset_irq(IRQ_FIFOTX_EMPTY);
+ break;
+ case REG_GTR_LOW:
+ m_general_counter = (m_general_counter & 0xff00) | data;
+ //popmessage("General counter set to %i\n",m_general_counter);
+ break;
+ case REG_GTR_HIGH:
+ m_general_counter = (m_general_counter & 0x00ff) | ((data & 0x3f) << 8);
+ //popmessage("General counter set to %i\n",m_general_counter);
+ break;
+ case REG_MTR_LOW:
+ m_midi_counter = (m_midi_counter & 0xff00) | data;
+ //popmessage("MIDI counter set to %i\n",m_midi_counter);
+ break;
+ case REG_MTR_HIGH:
+ m_midi_counter = (m_midi_counter & 0x00ff) | ((data & 0x3f) << 8);
+ //popmessage("MIDI counter set to %i\n",m_midi_counter);
+ break;
+ }
+ }
+}
diff --git a/src/devices/machine/ym3802.h b/src/devices/machine/ym3802.h
new file mode 100644
index 00000000000..003c52a759f
--- /dev/null
+++ b/src/devices/machine/ym3802.h
@@ -0,0 +1,164 @@
+// license:BSD-3-Clause
+// copyright-holders:Barry Rodewald
+/*
+ * ym3802.h - Yamaha YM3802/YM3523 MCS MIDI Communication and Service Controller
+ *
+ * * Registers:
+ * reg0 : IVR (read-only)
+ * reg1 : RGR (bit 8 = reset, bits 0-3 = register bank select)
+ * reg2 : ISR (read-only)
+ * reg3 : ICR (write-only)
+ * reg4-reg7 banked registers
+ * reg4 : IOR DMR RRR RSR TRR TSR FSR SRR GTR(L) EDR
+ * reg5 : IMR DCR RMR RCR TMR TCR FCR SCR GTR(H) ---
+ * reg6 : IER DSR AMR RDR --- TDR CCR SPR(L) MTR(L) EOR/EIR
+ * reg7 : --- DNR ADR --- --- --- CDR SPR(H) MTR(H) ---
+ */
+
+#ifndef DEVICES_MACHINE_YM3802_H
+#define DEVICES_MACHINE_YM3802_H
+
+#pragma once
+
+#include <queue>
+
+#define MCFG_YM3802_IRQ_HANDLER(_devcb) \
+ devcb = &ym3802_device::set_irq_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_YM3802_TXD_HANDLER(_devcb) \
+ devcb = &ym3802_device::set_txd_handler(*device, DEVCB_##_devcb);
+
+class ym3802_device : public device_t, public device_serial_interface
+{
+public:
+ // construction/destruction
+ ym3802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // static configuration helpers
+ template <class Object> static devcb_base &set_irq_handler(device_t &device, Object &&cb) { return downcast<ym3802_device &>(device).m_irq_handler.set_callback(std::forward<Object>(cb)); }
+ template <class Object> static devcb_base &set_txd_handler(device_t &device, Object &&cb) { return downcast<ym3802_device &>(device).m_txd_handler.set_callback(std::forward<Object>(cb)); }
+
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+
+ uint8_t vector() { return m_vector; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ enum
+ {
+ REG_IVR = 0, // Interrupt Vector (read only)
+ REG_RGR, // Register Group / System Control
+ REG_ISR, // Interrupt Service (read only)
+ REG_ICR, // Interrupt Clear (write only)
+
+ REG_IOR, // Interrupt Vector Offset Request
+ REG_IMR, // Interrupt Mode Control
+ REG_IER, // Interrupt Enable Request
+ REG_UNUSED1,
+
+ REG_DMR = 14, // Real Time Message Control
+ REG_DCR, // Real Time Message Request
+ REG_DSR, // FIFO IRx Data
+ REG_DNR, // FIFO IRx Control
+
+ REG_RRR = 24, // Rx Rate
+ REG_RMR, // Rx Mode
+ REG_AMR, // Address Hunter Maker
+ REG_ADR, // Address Hunter Device
+
+ REG_RSR = 34, // FIFO Rx Buffer Status
+ REG_RCR, // FIFO Rx Buffer Control
+ REG_RDR, // FIFO Rx Data
+ REG_UNUSED2,
+
+ REG_TRR = 44, // Tx Rate
+ REG_TMR, // Tx Mode
+ REG_UNUSED3,
+ REG_UNUSED4,
+
+ REG_TSR = 54, // FIFO Tx Status
+ REG_TCR, // FIFO Tx Control
+ REG_TDR, // FIFO Tx Data
+ REG_UNUSED5,
+
+ REG_FSR = 64, // FSK status
+ REG_FCR, // FSK control
+ REG_CCR, // Click Counter Control
+ REG_CDR, // Click Counter Data (7-bit)
+
+ REG_SRR = 74, // Recording Counter current value
+ REG_SCR, // Sequencer Control
+ REG_SPR_LOW, // Playback Counter (low 8-bits)
+ REG_SPR_HIGH, // Playback Counter (high 7-bits)
+
+ REG_GTR_LOW = 84, // General Timer (low 8-bits)
+ REG_GTR_HIGH, // General Timer (high 6-bits)
+ REG_MTR_LOW, // MIDI Clock Timer (low 8-bits)
+ REG_MTR_HIGH, // MIDI Clock Timer (high 6-bits)
+
+ REG_EDR = 94, // External I/O Direction
+ REG_EOR, // External I/O Output Data
+ REG_EIR, // External I/O Input Data
+ REG_UNUSED7,
+
+ REG_MAX = 100
+ };
+
+ enum
+ {
+ IRQ_MIDI_MSG = 0x01,
+ IRQ_CLICK = 0x02,
+ IRQ_MIDI_CLK = 0x02,
+ IRQ_PLAYBACK_COUNT = 0x04,
+ IRQ_RECORDING_COUNT = 0x08,
+ IRQ_OFFLINE = 0x10,
+ IRQ_BREAK = 0x10,
+ IRQ_FIFORX_RDY = 0x20,
+ IRQ_FIFOTX_EMPTY = 0x40,
+ IRQ_GENERAL_TIMER = 0x80
+ };
+
+ enum
+ {
+ TIMER_SYSTEM_CLOCK = 0x200, // CLK input - anywhere from 1MHz up to 4MHz
+ TIMER_MIDI_CLOCK, // CLKM input - usually either 1MHz or 0.5MHz, or CLKF input - usually 614.4kHz
+ };
+
+ void transmit_clk();
+ void reset_midi_timer();
+ void set_comms_mode();
+ void set_irq(uint8_t irq);
+ void reset_irq(uint8_t irq);
+
+ devcb_write_line m_irq_handler;
+ devcb_write_line m_txd_handler;
+ devcb_read_line m_rxd_handler;
+ emu_timer* m_clock_timer;
+ emu_timer* m_midi_timer;
+
+ std::vector<uint8_t> m_reg;
+ uint8_t m_wdr;
+ uint64_t m_prev_rate;
+ uint8_t m_irq_status;
+ uint16_t m_general_counter;
+ uint16_t m_midi_counter;
+ uint8_t m_vector;
+
+ std::queue<uint8_t> m_tx_fifo;
+ std::queue<uint8_t> m_rx_fifo;
+ std::queue<uint8_t> m_itx_fifo;
+ std::queue<uint8_t> m_irx_fifo;
+ bool m_tx_busy;
+
+ uint64_t m_clkm_rate;
+ uint64_t m_clkf_rate;
+};
+
+DECLARE_DEVICE_TYPE(YM3802, ym3802_device)
+
+#endif // DEVICES_MACHINE_YM3802_H
diff --git a/src/mame/drivers/x68k.cpp b/src/mame/drivers/x68k.cpp
index 7b7735bebbe..0be83bea167 100644
--- a/src/mame/drivers/x68k.cpp
+++ b/src/mame/drivers/x68k.cpp
@@ -123,9 +123,9 @@
#include "machine/mb89352.h"
#include "machine/nvram.h"
-#include "bus/x68k/x68kexp.h"
#include "bus/x68k/x68k_neptunex.h"
#include "bus/x68k/x68k_scsiext.h"
+#include "bus/x68k/x68k_midi.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsihd.h"
#include "bus/scsi/scsicd.h"
@@ -1474,9 +1474,17 @@ WRITE_LINE_MEMBER(x68k_state::x68k_irq2_line)
}
+WRITE_LINE_MEMBER(x68k_state::x68k_irq4_line)
+{
+ m_current_vector[4] = m_expansion->vector();
+ m_maincpu->set_input_line_and_vector(4,state,m_current_vector[4]);
+ logerror("EXP: IRQ4 set to %i (vector %02x)\n",state,m_current_vector[4]);
+}
+
static SLOT_INTERFACE_START(x68000_exp_cards)
SLOT_INTERFACE("neptunex",X68K_NEPTUNEX) // Neptune-X ethernet adapter (ISA NE2000 bridge)
SLOT_INTERFACE("cz6bs1",X68K_SCSIEXT) // Sharp CZ-6BS1 SCSI-1 controller
+ SLOT_INTERFACE("x68k_midi",X68K_MIDI) // X68000 MIDI interface
SLOT_INTERFACE_END
MACHINE_RESET_MEMBER(x68k_state,x68000)
@@ -1726,7 +1734,7 @@ static MACHINE_CONFIG_START( x68000 )
MCFG_DEVICE_ADD("exp", X68K_EXPANSION_SLOT, 0)
MCFG_DEVICE_SLOT_INTERFACE(x68000_exp_cards, nullptr, false)
MCFG_X68K_EXPANSION_SLOT_OUT_IRQ2_CB(WRITELINE(x68k_state, x68k_irq2_line))
- MCFG_X68K_EXPANSION_SLOT_OUT_IRQ4_CB(INPUTLINE("maincpu", M68K_IRQ_4))
+ MCFG_X68K_EXPANSION_SLOT_OUT_IRQ4_CB(WRITELINE(x68k_state, x68k_irq4_line))
MCFG_X68K_EXPANSION_SLOT_OUT_NMI_CB(INPUTLINE("maincpu", INPUT_LINE_NMI))
/* internal ram */
diff --git a/src/mame/includes/x68k.h b/src/mame/includes/x68k.h
index 852ffcb26d7..f0a3e252bc3 100644
--- a/src/mame/includes/x68k.h
+++ b/src/mame/includes/x68k.h
@@ -21,6 +21,7 @@
#include "machine/upd765.h"
#include "sound/okim6258.h"
#include "sound/ym2151.h"
+#include "bus/x68k/x68kexp.h"
#include "screen.h"
@@ -67,6 +68,7 @@ public:
m_ppi(*this, "ppi8255"),
m_screen(*this, "screen"),
m_upd72065(*this, "upd72065"),
+ m_expansion(*this, "exp"),
m_options(*this, "options"),
m_mouse1(*this, "mouse1"),
m_mouse2(*this, "mouse2"),
@@ -98,6 +100,7 @@ public:
required_device<i8255_device> m_ppi;
required_device<screen_device> m_screen;
required_device<upd72065_device> m_upd72065;
+ required_device<x68k_expansion_slot_device> m_expansion;
required_ioport m_options;
required_ioport m_mouse1;
@@ -300,6 +303,7 @@ public:
DECLARE_WRITE_LINE_MEMBER(x68k_fm_irq);
DECLARE_WRITE_LINE_MEMBER(x68k_irq2_line);
+ DECLARE_WRITE_LINE_MEMBER(x68k_irq4_line);
DECLARE_WRITE16_MEMBER(x68k_scc_w);
DECLARE_WRITE16_MEMBER(x68k_fdc_w);