mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +03:00
mc68681: Preliminary support for SC28C94 QUART. [R. Belmont]
This commit is contained in:
parent
67bded8842
commit
a9f9729c07
@ -1,7 +1,9 @@
|
|||||||
// license:BSD-3-Clause
|
// license:BSD-3-Clause
|
||||||
// copyright-holders:Mariusz Wojcieszek, R. Belmont
|
// copyright-holders:Mariusz Wojcieszek, R. Belmont
|
||||||
/*
|
/*
|
||||||
|
2681 DUART
|
||||||
68681 DUART
|
68681 DUART
|
||||||
|
28C94 QUART
|
||||||
|
|
||||||
Written by Mariusz Wojcieszek
|
Written by Mariusz Wojcieszek
|
||||||
Updated by Jonathan Gevaryahu AKA Lord Nightmare
|
Updated by Jonathan Gevaryahu AKA Lord Nightmare
|
||||||
@ -50,9 +52,12 @@ static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000,
|
|||||||
|
|
||||||
#define CHANA_TAG "cha"
|
#define CHANA_TAG "cha"
|
||||||
#define CHANB_TAG "chb"
|
#define CHANB_TAG "chb"
|
||||||
|
#define CHANC_TAG "chc"
|
||||||
|
#define CHAND_TAG "chd"
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
const device_type MC68681 = &device_creator<mc68681_device>;
|
const device_type MC68681 = &device_creator<mc68681_device>;
|
||||||
|
const device_type SC28C94 = &device_creator<sc28c94_device>;
|
||||||
const device_type MC68681_CHANNEL = &device_creator<mc68681_channel>;
|
const device_type MC68681_CHANNEL = &device_creator<mc68681_channel>;
|
||||||
|
|
||||||
MACHINE_CONFIG_FRAGMENT( duart68681 )
|
MACHINE_CONFIG_FRAGMENT( duart68681 )
|
||||||
@ -60,17 +65,28 @@ MACHINE_CONFIG_FRAGMENT( duart68681 )
|
|||||||
MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0)
|
MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
MACHINE_CONFIG_FRAGMENT( quart28c94 )
|
||||||
|
MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0)
|
||||||
|
MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0)
|
||||||
|
MCFG_DEVICE_ADD(CHANC_TAG, MC68681_CHANNEL, 0)
|
||||||
|
MCFG_DEVICE_ADD(CHAND_TAG, MC68681_CHANNEL, 0)
|
||||||
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// LIVE DEVICE
|
// LIVE DEVICE
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
mc68681_base_device::mc68681_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source)
|
||||||
: device_t(mconfig, MC68681, "MC68681 DUART", tag, owner, clock, "mc68681", __FILE__),
|
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||||
m_chanA(*this, CHANA_TAG),
|
m_chanA(*this, CHANA_TAG),
|
||||||
m_chanB(*this, CHANB_TAG),
|
m_chanB(*this, CHANB_TAG),
|
||||||
|
m_chanC(*this, CHANC_TAG),
|
||||||
|
m_chanD(*this, CHAND_TAG),
|
||||||
write_irq(*this),
|
write_irq(*this),
|
||||||
write_a_tx(*this),
|
write_a_tx(*this),
|
||||||
write_b_tx(*this),
|
write_b_tx(*this),
|
||||||
|
write_c_tx(*this),
|
||||||
|
write_d_tx(*this),
|
||||||
read_inport(*this),
|
read_inport(*this),
|
||||||
write_outport(*this),
|
write_outport(*this),
|
||||||
ip3clk(0),
|
ip3clk(0),
|
||||||
@ -83,14 +99,24 @@ mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, d
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
|
: mc68681_base_device(mconfig, MC68681, "MC68681 DUART", tag, owner, clock, "mc68681", __FILE__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
|
: mc68681_base_device(mconfig, SC28C94, "SC28C94 QUART", tag, owner, clock, "sc28c94", __FILE__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// static_set_clocks - configuration helper to set
|
// static_set_clocks - configuration helper to set
|
||||||
// the external clocks
|
// the external clocks
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void mc68681_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6)
|
void mc68681_base_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6)
|
||||||
{
|
{
|
||||||
mc68681_device &duart = downcast<mc68681_device &>(device);
|
mc68681_base_device &duart = downcast<mc68681_base_device &>(device);
|
||||||
duart.ip3clk = clk3;
|
duart.ip3clk = clk3;
|
||||||
duart.ip4clk = clk4;
|
duart.ip4clk = clk4;
|
||||||
duart.ip5clk = clk5;
|
duart.ip5clk = clk5;
|
||||||
@ -101,7 +127,7 @@ void mc68681_device::static_set_clocks(device_t &device, int clk3, int clk4, int
|
|||||||
device start callback
|
device start callback
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
void mc68681_device::device_start()
|
void mc68681_base_device::device_start()
|
||||||
{
|
{
|
||||||
write_irq.resolve_safe();
|
write_irq.resolve_safe();
|
||||||
write_a_tx.resolve_safe();
|
write_a_tx.resolve_safe();
|
||||||
@ -109,7 +135,7 @@ void mc68681_device::device_start()
|
|||||||
read_inport.resolve();
|
read_inport.resolve();
|
||||||
write_outport.resolve_safe();
|
write_outport.resolve_safe();
|
||||||
|
|
||||||
duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68681_device::duart_timer_callback),this), nullptr);
|
duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68681_base_device::duart_timer_callback),this), nullptr);
|
||||||
|
|
||||||
save_item(NAME(ACR));
|
save_item(NAME(ACR));
|
||||||
save_item(NAME(IMR));
|
save_item(NAME(IMR));
|
||||||
@ -125,7 +151,7 @@ void mc68681_device::device_start()
|
|||||||
device reset callback
|
device reset callback
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
void mc68681_device::device_reset()
|
void mc68681_base_device::device_reset()
|
||||||
{
|
{
|
||||||
ACR = 0; /* Interrupt Vector Register */
|
ACR = 0; /* Interrupt Vector Register */
|
||||||
IVR = 0x0f; /* Interrupt Vector Register */
|
IVR = 0x0f; /* Interrupt Vector Register */
|
||||||
@ -141,12 +167,17 @@ void mc68681_device::device_reset()
|
|||||||
write_outport(OPR ^ 0xff);
|
write_outport(OPR ^ 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_config_constructor mc68681_device::device_mconfig_additions() const
|
machine_config_constructor mc68681_base_device::device_mconfig_additions() const
|
||||||
{
|
{
|
||||||
return MACHINE_CONFIG_NAME( duart68681 );
|
return MACHINE_CONFIG_NAME( duart68681 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void mc68681_device::update_interrupts()
|
machine_config_constructor sc28c94_device::device_mconfig_additions() const
|
||||||
|
{
|
||||||
|
return MACHINE_CONFIG_NAME( quart28c94 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void mc68681_base_device::update_interrupts()
|
||||||
{
|
{
|
||||||
/* update SR state and update interrupt ISR state for the following bits:
|
/* update SR state and update interrupt ISR state for the following bits:
|
||||||
SRn: bits 7-4: handled elsewhere.
|
SRn: bits 7-4: handled elsewhere.
|
||||||
@ -208,7 +239,7 @@ void mc68681_device::update_interrupts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double mc68681_device::duart68681_get_ct_rate()
|
double mc68681_base_device::duart68681_get_ct_rate()
|
||||||
{
|
{
|
||||||
double rate = 0.0f;
|
double rate = 0.0f;
|
||||||
|
|
||||||
@ -250,19 +281,19 @@ double mc68681_device::duart68681_get_ct_rate()
|
|||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mc68681_device::duart68681_get_ct_count()
|
uint16_t mc68681_base_device::duart68681_get_ct_count()
|
||||||
{
|
{
|
||||||
double clock = duart68681_get_ct_rate();
|
double clock = duart68681_get_ct_rate();
|
||||||
return (duart_timer->remaining() * clock).as_double();
|
return (duart_timer->remaining() * clock).as_double();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mc68681_device::duart68681_start_ct(int count)
|
void mc68681_base_device::duart68681_start_ct(int count)
|
||||||
{
|
{
|
||||||
double clock = duart68681_get_ct_rate();
|
double clock = duart68681_get_ct_rate();
|
||||||
duart_timer->adjust(attotime::from_hz(clock) * count, 0);
|
duart_timer->adjust(attotime::from_hz(clock) * count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_CALLBACK_MEMBER( mc68681_device::duart_timer_callback )
|
TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback )
|
||||||
{
|
{
|
||||||
if (ACR & 0x40)
|
if (ACR & 0x40)
|
||||||
{
|
{
|
||||||
@ -320,13 +351,13 @@ TIMER_CALLBACK_MEMBER( mc68681_device::duart_timer_callback )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
READ8_MEMBER( mc68681_device::read )
|
READ8_MEMBER( mc68681_base_device::read )
|
||||||
{
|
{
|
||||||
uint8_t r = 0xff;
|
uint8_t r = 0xff;
|
||||||
|
|
||||||
offset &= 0xf;
|
offset &= 0xf;
|
||||||
|
|
||||||
LOG(( "Reading 68681 (%s) reg %x (%s) ", tag(), offset, duart68681_reg_read_names[offset] ));
|
LOG(( "Reading 68681 (%s) reg %x (%s)\n", tag(), offset, duart68681_reg_read_names[offset] ));
|
||||||
|
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
@ -424,7 +455,7 @@ READ8_MEMBER( mc68681_device::read )
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE8_MEMBER( mc68681_device::write )
|
WRITE8_MEMBER( mc68681_base_device::write )
|
||||||
{
|
{
|
||||||
offset &= 0x0f;
|
offset &= 0x0f;
|
||||||
LOG(( "Writing 68681 (%s) reg %x (%s) with %04x\n", tag(), offset, duart68681_reg_write_names[offset], data ));
|
LOG(( "Writing 68681 (%s) reg %x (%s) with %04x\n", tag(), offset, duart68681_reg_write_names[offset], data ));
|
||||||
@ -516,7 +547,7 @@ WRITE8_MEMBER( mc68681_device::write )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( mc68681_device::ip0_w )
|
WRITE_LINE_MEMBER( mc68681_base_device::ip0_w )
|
||||||
{
|
{
|
||||||
uint8_t newIP = (IP_last_state & ~0x01) | ((state == ASSERT_LINE) ? 1 : 0);
|
uint8_t newIP = (IP_last_state & ~0x01) | ((state == ASSERT_LINE) ? 1 : 0);
|
||||||
|
|
||||||
@ -536,7 +567,7 @@ WRITE_LINE_MEMBER( mc68681_device::ip0_w )
|
|||||||
IP_last_state = newIP;
|
IP_last_state = newIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( mc68681_device::ip1_w )
|
WRITE_LINE_MEMBER( mc68681_base_device::ip1_w )
|
||||||
{
|
{
|
||||||
uint8_t newIP = (IP_last_state & ~0x02) | ((state == ASSERT_LINE) ? 2 : 0);
|
uint8_t newIP = (IP_last_state & ~0x02) | ((state == ASSERT_LINE) ? 2 : 0);
|
||||||
|
|
||||||
@ -556,7 +587,7 @@ WRITE_LINE_MEMBER( mc68681_device::ip1_w )
|
|||||||
IP_last_state = newIP;
|
IP_last_state = newIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( mc68681_device::ip2_w )
|
WRITE_LINE_MEMBER( mc68681_base_device::ip2_w )
|
||||||
{
|
{
|
||||||
uint8_t newIP = (IP_last_state & ~0x04) | ((state == ASSERT_LINE) ? 4 : 0);
|
uint8_t newIP = (IP_last_state & ~0x04) | ((state == ASSERT_LINE) ? 4 : 0);
|
||||||
|
|
||||||
@ -576,7 +607,7 @@ WRITE_LINE_MEMBER( mc68681_device::ip2_w )
|
|||||||
IP_last_state = newIP;
|
IP_last_state = newIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( mc68681_device::ip3_w )
|
WRITE_LINE_MEMBER( mc68681_base_device::ip3_w )
|
||||||
{
|
{
|
||||||
uint8_t newIP = (IP_last_state & ~0x08) | ((state == ASSERT_LINE) ? 8 : 0);
|
uint8_t newIP = (IP_last_state & ~0x08) | ((state == ASSERT_LINE) ? 8 : 0);
|
||||||
|
|
||||||
@ -596,21 +627,21 @@ WRITE_LINE_MEMBER( mc68681_device::ip3_w )
|
|||||||
IP_last_state = newIP;
|
IP_last_state = newIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( mc68681_device::ip4_w )
|
WRITE_LINE_MEMBER( mc68681_base_device::ip4_w )
|
||||||
{
|
{
|
||||||
uint8_t newIP = (IP_last_state & ~0x10) | ((state == ASSERT_LINE) ? 0x10 : 0);
|
uint8_t newIP = (IP_last_state & ~0x10) | ((state == ASSERT_LINE) ? 0x10 : 0);
|
||||||
// TODO: special mode for ip4 (Ch. A Rx clock)
|
// TODO: special mode for ip4 (Ch. A Rx clock)
|
||||||
IP_last_state = newIP;
|
IP_last_state = newIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( mc68681_device::ip5_w )
|
WRITE_LINE_MEMBER( mc68681_base_device::ip5_w )
|
||||||
{
|
{
|
||||||
uint8_t newIP = (IP_last_state & ~0x20) | ((state == ASSERT_LINE) ? 0x20 : 0);
|
uint8_t newIP = (IP_last_state & ~0x20) | ((state == ASSERT_LINE) ? 0x20 : 0);
|
||||||
// TODO: special mode for ip5 (Ch. B Tx clock)
|
// TODO: special mode for ip5 (Ch. B Tx clock)
|
||||||
IP_last_state = newIP;
|
IP_last_state = newIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
mc68681_channel *mc68681_device::get_channel(int chan)
|
mc68681_channel *mc68681_base_device::get_channel(int chan)
|
||||||
{
|
{
|
||||||
if (chan == 0)
|
if (chan == 0)
|
||||||
{
|
{
|
||||||
@ -620,7 +651,7 @@ mc68681_channel *mc68681_device::get_channel(int chan)
|
|||||||
return m_chanB;
|
return m_chanB;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mc68681_device::calc_baud(int ch, uint8_t data)
|
int mc68681_base_device::calc_baud(int ch, uint8_t data)
|
||||||
{
|
{
|
||||||
int baud_rate;
|
int baud_rate;
|
||||||
|
|
||||||
@ -661,15 +692,16 @@ int mc68681_device::calc_baud(int ch, uint8_t data)
|
|||||||
LOG(( "Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data ));
|
LOG(( "Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printf("%s ch %d setting baud to %d\n", tag(), ch, baud_rate);
|
||||||
return baud_rate;
|
return baud_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mc68681_device::clear_ISR_bits(int mask)
|
void mc68681_base_device::clear_ISR_bits(int mask)
|
||||||
{
|
{
|
||||||
ISR &= ~mask;
|
ISR &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mc68681_device::set_ISR_bits(int mask)
|
void mc68681_base_device::set_ISR_bits(int mask)
|
||||||
{
|
{
|
||||||
ISR |= mask;
|
ISR |= mask;
|
||||||
}
|
}
|
||||||
@ -690,7 +722,7 @@ mc68681_channel::mc68681_channel(const machine_config &mconfig, const char *tag,
|
|||||||
|
|
||||||
void mc68681_channel::device_start()
|
void mc68681_channel::device_start()
|
||||||
{
|
{
|
||||||
m_uart = downcast<mc68681_device *>(owner());
|
m_uart = downcast<mc68681_base_device *>(owner());
|
||||||
m_ch = m_uart->get_ch(this); // get our channel number
|
m_ch = m_uart->get_ch(this); // get our channel number
|
||||||
|
|
||||||
save_item(NAME(CR));
|
save_item(NAME(CR));
|
||||||
@ -793,7 +825,7 @@ void mc68681_channel::tra_callback()
|
|||||||
if ((MR2&0xC0) != 0x80)
|
if ((MR2&0xC0) != 0x80)
|
||||||
{
|
{
|
||||||
int bit = transmit_register_get_data_bit();
|
int bit = transmit_register_get_data_bit();
|
||||||
// printf("%s ch %d transmit %d\n", tag(), m_ch, bit);
|
//printf("%s ch %d transmit %d\n", tag(), m_ch, bit);
|
||||||
if (m_ch == 0)
|
if (m_ch == 0)
|
||||||
{
|
{
|
||||||
m_uart->write_a_tx(bit);
|
m_uart->write_a_tx(bit);
|
||||||
@ -1157,7 +1189,7 @@ void mc68681_channel::write_TX(uint8_t data)
|
|||||||
printf("Write %02x to TX when TX not ready!\n", data);
|
printf("Write %02x to TX when TX not ready!\n", data);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// printf("%s ch %d Tx %02x\n", tag(), m_ch, data);
|
//printf("%s ch %d Tx %02x\n", tag(), m_ch, data);
|
||||||
|
|
||||||
tx_ready = 0;
|
tx_ready = 0;
|
||||||
SR &= ~STATUS_TRANSMITTER_READY;
|
SR &= ~STATUS_TRANSMITTER_READY;
|
||||||
|
@ -11,28 +11,38 @@
|
|||||||
MCFG_DEVICE_REPLACE(_tag, MC68681, _clock)
|
MCFG_DEVICE_REPLACE(_tag, MC68681, _clock)
|
||||||
|
|
||||||
#define MCFG_MC68681_IRQ_CALLBACK(_cb) \
|
#define MCFG_MC68681_IRQ_CALLBACK(_cb) \
|
||||||
devcb = &mc68681_device::set_irq_cb(*device, DEVCB_##_cb);
|
devcb = &mc68681_base_device::set_irq_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
#define MCFG_MC68681_A_TX_CALLBACK(_cb) \
|
#define MCFG_MC68681_A_TX_CALLBACK(_cb) \
|
||||||
devcb = &mc68681_device::set_a_tx_cb(*device, DEVCB_##_cb);
|
devcb = &mc68681_base_device::set_a_tx_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
#define MCFG_MC68681_B_TX_CALLBACK(_cb) \
|
#define MCFG_MC68681_B_TX_CALLBACK(_cb) \
|
||||||
devcb = &mc68681_device::set_b_tx_cb(*device, DEVCB_##_cb);
|
devcb = &mc68681_base_device::set_b_tx_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
// deprecated: use ipX_w() instead
|
// deprecated: use ipX_w() instead
|
||||||
#define MCFG_MC68681_INPORT_CALLBACK(_cb) \
|
#define MCFG_MC68681_INPORT_CALLBACK(_cb) \
|
||||||
devcb = &mc68681_device::set_inport_cb(*device, DEVCB_##_cb);
|
devcb = &mc68681_base_device::set_inport_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
#define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \
|
#define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \
|
||||||
devcb = &mc68681_device::set_outport_cb(*device, DEVCB_##_cb);
|
devcb = &mc68681_base_device::set_outport_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
#define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \
|
#define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \
|
||||||
mc68681_device::static_set_clocks(*device, _a, _b, _c, _d);
|
mc68681_base_device::static_set_clocks(*device, _a, _b, _c, _d);
|
||||||
|
|
||||||
|
// SC28C94 specific callbacks
|
||||||
|
#define MCFG_SC28C94_ADD(_tag, _clock) \
|
||||||
|
MCFG_DEVICE_ADD(_tag, SC28C94, _clock)
|
||||||
|
|
||||||
|
#define MCFG_SC28C94_C_TX_CALLBACK(_cb) \
|
||||||
|
devcb = &sc28c94_device::set_c_tx_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
|
#define MCFG_SC28C94_D_TX_CALLBACK(_cb) \
|
||||||
|
devcb = &sc28c94_device::set_d_tx_cb(*device, DEVCB_##_cb);
|
||||||
|
|
||||||
#define MC68681_RX_FIFO_SIZE 3
|
#define MC68681_RX_FIFO_SIZE 3
|
||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
class mc68681_device;
|
class mc68681_base_device;
|
||||||
|
|
||||||
// mc68681_channel class
|
// mc68681_channel class
|
||||||
class mc68681_channel : public device_t, public device_serial_interface
|
class mc68681_channel : public device_t, public device_serial_interface
|
||||||
@ -86,7 +96,7 @@ private:
|
|||||||
uint8_t tx_data;
|
uint8_t tx_data;
|
||||||
uint8_t tx_ready;
|
uint8_t tx_ready;
|
||||||
|
|
||||||
mc68681_device *m_uart;
|
mc68681_base_device *m_uart;
|
||||||
|
|
||||||
void write_MR(uint8_t data);
|
void write_MR(uint8_t data);
|
||||||
void write_CR(uint8_t data);
|
void write_CR(uint8_t data);
|
||||||
@ -94,15 +104,17 @@ private:
|
|||||||
void recalc_framing();
|
void recalc_framing();
|
||||||
};
|
};
|
||||||
|
|
||||||
class mc68681_device : public device_t
|
class mc68681_base_device : public device_t
|
||||||
{
|
{
|
||||||
friend class mc68681_channel;
|
friend class mc68681_channel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
mc68681_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
|
||||||
|
|
||||||
required_device<mc68681_channel> m_chanA;
|
required_device<mc68681_channel> m_chanA;
|
||||||
required_device<mc68681_channel> m_chanB;
|
required_device<mc68681_channel> m_chanB;
|
||||||
|
optional_device<mc68681_channel> m_chanC;
|
||||||
|
optional_device<mc68681_channel> m_chanD;
|
||||||
|
|
||||||
// inline configuration helpers
|
// inline configuration helpers
|
||||||
static void static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6);
|
static void static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6);
|
||||||
@ -115,13 +127,13 @@ public:
|
|||||||
DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((uint8_t)state); }
|
DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((uint8_t)state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((uint8_t)state); }
|
DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((uint8_t)state); }
|
||||||
|
|
||||||
template<class _Object> static devcb_base &set_irq_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_irq.set_callback(object); }
|
template<class _Object> static devcb_base &set_irq_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_irq.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_a_tx_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_a_tx.set_callback(object); }
|
template<class _Object> static devcb_base &set_a_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_a_tx.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_b_tx_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_b_tx.set_callback(object); }
|
template<class _Object> static devcb_base &set_b_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_b_tx.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_inport_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).read_inport.set_callback(object); }
|
template<class _Object> static devcb_base &set_inport_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).read_inport.set_callback(object); }
|
||||||
template<class _Object> static devcb_base &set_outport_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_outport.set_callback(object); }
|
template<class _Object> static devcb_base &set_outport_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_outport.set_callback(object); }
|
||||||
|
|
||||||
devcb_write_line write_irq, write_a_tx, write_b_tx;
|
devcb_write_line write_irq, write_a_tx, write_b_tx, write_c_tx, write_d_tx;
|
||||||
devcb_read8 read_inport;
|
devcb_read8 read_inport;
|
||||||
devcb_write8 write_outport;
|
devcb_write8 write_outport;
|
||||||
int32_t ip3clk, ip4clk, ip5clk, ip6clk;
|
int32_t ip3clk, ip4clk, ip5clk, ip6clk;
|
||||||
@ -166,15 +178,56 @@ private:
|
|||||||
uint16_t duart68681_get_ct_count();
|
uint16_t duart68681_get_ct_count();
|
||||||
void duart68681_start_ct(int count);
|
void duart68681_start_ct(int count);
|
||||||
int calc_baud(int ch, uint8_t data);
|
int calc_baud(int ch, uint8_t data);
|
||||||
int get_ch(mc68681_channel *ch) { return (ch == m_chanA) ? 0 : 1; }
|
|
||||||
void clear_ISR_bits(int mask);
|
void clear_ISR_bits(int mask);
|
||||||
void set_ISR_bits(int mask);
|
void set_ISR_bits(int mask);
|
||||||
void update_interrupts();
|
void update_interrupts();
|
||||||
|
|
||||||
|
int get_ch(mc68681_channel *ch)
|
||||||
|
{
|
||||||
|
if (ch == m_chanA)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (ch == m_chanB)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (ch == m_chanC)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
mc68681_channel *get_channel(int chan);
|
mc68681_channel *get_channel(int chan);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class mc68681_device : public mc68681_base_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
class sc28c94_device : public mc68681_base_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
template<class _Object> static devcb_base &set_c_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_c_tx.set_callback(object); }
|
||||||
|
template<class _Object> static devcb_base &set_d_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_d_tx.set_callback(object); }
|
||||||
|
|
||||||
|
DECLARE_WRITE_LINE_MEMBER( rx_c_w ) { m_chanC->device_serial_interface::rx_w((uint8_t)state); }
|
||||||
|
DECLARE_WRITE_LINE_MEMBER( rx_d_w ) { m_chanD->device_serial_interface::rx_w((uint8_t)state); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual machine_config_constructor device_mconfig_additions() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
extern const device_type MC68681;
|
extern const device_type MC68681;
|
||||||
|
extern const device_type SC28C94;
|
||||||
extern const device_type MC68681_CHANNEL;
|
extern const device_type MC68681_CHANNEL;
|
||||||
|
|
||||||
#endif //_N68681_H
|
#endif //_N68681_H
|
||||||
|
Loading…
Reference in New Issue
Block a user