mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
- Add preliminary Yamaha YM3802 MIDI controller
- Add X68000 expansion device using the YM3802
This commit is contained in:
parent
e6f86fa673
commit
03f21234b8
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
66
src/devices/bus/x68k/x68k_midi.cpp
Normal file
66
src/devices/bus/x68k/x68k_midi.cpp
Normal file
@ -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
|
||||
}
|
48
src/devices/bus/x68k/x68k_midi.h
Normal file
48
src/devices/bus/x68k/x68k_midi.h
Normal file
@ -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
|
@ -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;
|
||||
|
286
src/devices/machine/ym3802.cpp
Normal file
286
src/devices/machine/ym3802.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
164
src/devices/machine/ym3802.h
Normal file
164
src/devices/machine/ym3802.h
Normal file
@ -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
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user