From 03f21234b8e8cfbffa8f0199696307246122de31 Mon Sep 17 00:00:00 2001 From: mahlemiut Date: Wed, 21 Jun 2017 18:34:36 +1200 Subject: [PATCH] - Add preliminary Yamaha YM3802 MIDI controller - Add X68000 expansion device using the YM3802 --- scripts/src/bus.lua | 2 + scripts/src/machine.lua | 12 ++ src/devices/bus/x68k/x68k_midi.cpp | 66 +++++++ src/devices/bus/x68k/x68k_midi.h | 48 +++++ src/devices/bus/x68k/x68kexp.h | 10 +- src/devices/machine/ym3802.cpp | 286 +++++++++++++++++++++++++++++ src/devices/machine/ym3802.h | 164 +++++++++++++++++ src/mame/drivers/x68k.cpp | 12 +- src/mame/includes/x68k.h | 4 + 9 files changed, 601 insertions(+), 3 deletions(-) create mode 100644 src/devices/bus/x68k/x68k_midi.cpp create mode 100644 src/devices/bus/x68k/x68k_midi.h create mode 100644 src/devices/machine/ym3802.cpp create mode 100644 src/devices/machine/ym3802.h 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 @@ -2681,6 +2681,18 @@ if (MACHINES["YM2148"]~=null) then } 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(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 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 + +#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 static devcb_base &set_irq_handler(device_t &device, Object &&cb) { return downcast(device).m_irq_handler.set_callback(std::forward(cb)); } + template static devcb_base &set_txd_handler(device_t &device, Object &&cb) { return downcast(device).m_txd_handler.set_callback(std::forward(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 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 m_tx_fifo; + std::queue m_rx_fifo; + std::queue m_itx_fifo; + std::queue 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 m_ppi; required_device m_screen; required_device m_upd72065; + required_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);