From 73b75f5c705e361170c6fba5af645ecab1998653 Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 22 Nov 2017 01:24:05 -0500 Subject: mc68681: Distinguish SCN2681 and MC68681 DUART types --- src/devices/machine/mc68681.cpp | 265 ++++++++++++++++++++++------------------ src/devices/machine/mc68681.h | 95 ++++++++------ src/mame/drivers/cit220.cpp | 4 +- src/mame/drivers/microterm.cpp | 14 +-- src/mame/includes/apollo.h | 2 +- src/mame/machine/apollo.cpp | 6 +- 6 files changed, 214 insertions(+), 172 deletions(-) diff --git a/src/devices/machine/mc68681.cpp b/src/devices/machine/mc68681.cpp index c8bb75f0b1c..c6717e2938b 100644 --- a/src/devices/machine/mc68681.cpp +++ b/src/devices/machine/mc68681.cpp @@ -16,7 +16,7 @@ #include "emu.h" #include "mc68681.h" -//#define VERBOSE 1 +#define VERBOSE 1 //#define LOG_OUTPUT_FUNC printf #include "logmacro.h" @@ -60,17 +60,18 @@ static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000, #define CHAND_TAG "chd" // device type definition +DEFINE_DEVICE_TYPE(SCN2681, scn2681_device, "scn2681", "SCN2681 DUART") DEFINE_DEVICE_TYPE(MC68681, mc68681_device, "mc68681", "MC68681 DUART") DEFINE_DEVICE_TYPE(SC28C94, sc28c94_device, "sc28c94", "SC28C94 QUART") DEFINE_DEVICE_TYPE(MC68340_DUART, mc68340_duart_device, "mc68340duart", "MC68340 DUART Device") -DEFINE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel, "mc68681_channel", "MC68681 DUART channel") +DEFINE_DEVICE_TYPE(DUART_CHANNEL, duart_channel, "duart_channel", "DUART channel") //************************************************************************** // LIVE DEVICE //************************************************************************** -mc68681_base_device::mc68681_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +duart_base_device::duart_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), m_chanA(*this, CHANA_TAG), m_chanB(*this, CHANB_TAG), @@ -88,18 +89,23 @@ mc68681_base_device::mc68681_base_device(const machine_config &mconfig, device_t ip5clk(0), ip6clk(0), ACR(0), - m_read_vector(false), IP_last_state(0) { } +scn2681_device::scn2681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, SCN2681, tag, owner, clock) +{ +} + mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mc68681_base_device(mconfig, MC68681, tag, owner, clock) + : duart_base_device(mconfig, MC68681, tag, owner, clock), + m_read_vector(false) { } sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mc68681_base_device(mconfig, SC28C94, tag, owner, clock) + : duart_base_device(mconfig, SC28C94, tag, owner, clock) { } @@ -111,7 +117,7 @@ sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, d // TODO: A lot of subtle differences and also detect misuse of unavailable registers as they should be ignored //-------------------------------------------------------------------------------------------------------------------- mc68340_duart_device::mc68340_duart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : mc68681_base_device(mconfig, type, tag, owner, clock) + : duart_base_device(mconfig, type, tag, owner, clock) { } @@ -125,9 +131,9 @@ mc68340_duart_device::mc68340_duart_device(const machine_config &mconfig, const // the external clocks //------------------------------------------------- -void mc68681_base_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6) +void duart_base_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6) { - mc68681_base_device &duart = downcast(device); + duart_base_device &duart = downcast(device); duart.ip3clk = clk3; duart.ip4clk = clk4; duart.ip5clk = clk5; @@ -138,7 +144,7 @@ void mc68681_base_device::static_set_clocks(device_t &device, int clk3, int clk4 device start callback -------------------------------------------------*/ -void mc68681_base_device::device_start() +void duart_base_device::device_start() { write_irq.resolve_safe(); write_a_tx.resolve_safe(); @@ -148,56 +154,70 @@ void mc68681_base_device::device_start() read_inport.resolve(); write_outport.resolve_safe(); - duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68681_base_device::duart_timer_callback),this), nullptr); + duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(duart_base_device::duart_timer_callback),this), nullptr); save_item(NAME(ACR)); save_item(NAME(IMR)); save_item(NAME(ISR)); - save_item(NAME(IVR)); save_item(NAME(OPCR)); save_item(NAME(CTR)); save_item(NAME(IP_last_state)); save_item(NAME(half_period)); } +void mc68681_device::device_start() +{ + duart_base_device::device_start(); + + save_item(NAME(m_read_vector)); + save_item(NAME(IVR)); +} + /*------------------------------------------------- device reset callback -------------------------------------------------*/ -void mc68681_base_device::device_reset() +void duart_base_device::device_reset() { ACR = 0; /* Interrupt Vector Register */ - IVR = 0x0f; /* Interrupt Vector Register */ IMR = 0; /* Interrupt Mask Register */ ISR = 0; /* Interrupt Status Register */ OPCR = 0; /* Output Port Conf. Register */ OPR = 0; /* Output Port Register */ CTR.d = 0; /* Counter/Timer Preset Value */ - m_read_vector = false; // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state" IPCR = 0; + write_irq(CLEAR_LINE); write_outport(OPR ^ 0xff); } -MACHINE_CONFIG_MEMBER( mc68681_base_device::device_add_mconfig ) - MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0) +void mc68681_device::device_reset() +{ + duart_base_device::device_reset(); + + IVR = 0x0f; /* Interrupt Vector Register */ + m_read_vector = false; +} + +MACHINE_CONFIG_MEMBER( duart_base_device::device_add_mconfig ) + MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER( sc28c94_device::device_add_mconfig ) - 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) + MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANC_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHAND_TAG, DUART_CHANNEL, 0) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER( mc68340_duart_device::device_add_mconfig ) - MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0) MACHINE_CONFIG_END -void mc68681_base_device::update_interrupts() +void duart_base_device::update_interrupts() { /* update SR state and update interrupt ISR state for the following bits: SRn: bits 7-4: handled elsewhere. @@ -223,7 +243,6 @@ void mc68681_base_device::update_interrupts() { LOG( "68681: Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR); write_irq(CLEAR_LINE); - m_read_vector = false; // clear IACK too } if(OPCR & 0xf0) { @@ -259,7 +278,13 @@ void mc68681_base_device::update_interrupts() } } -double mc68681_base_device::duart68681_get_ct_rate() +void mc68681_device::update_interrupts() +{ + if (!irq_pending()) + m_read_vector = false; // clear IACK too +} + +double duart_base_device::get_ct_rate() { double rate = 0.0f; @@ -301,19 +326,19 @@ double mc68681_base_device::duart68681_get_ct_rate() return rate; } -uint16_t mc68681_base_device::duart68681_get_ct_count() +uint16_t duart_base_device::get_ct_count() { - double clock = duart68681_get_ct_rate(); + double clock = get_ct_rate(); return (duart_timer->remaining() * clock).as_double(); } -void mc68681_base_device::duart68681_start_ct(int count) +void duart_base_device::start_ct(int count) { - double clock = duart68681_get_ct_rate(); + double clock = get_ct_rate(); duart_timer->adjust(attotime::from_hz(clock) * count, 0); } -TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback ) +TIMER_CALLBACK_MEMBER( duart_base_device::duart_timer_callback ) { if (ACR & 0x40) { @@ -353,22 +378,37 @@ TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback ) } if (!half_period) - { - ISR |= INT_COUNTER_READY; - update_interrupts(); - } + set_ISR_bits(INT_COUNTER_READY); int count = std::max(CTR.w.l, uint16_t(1)); - duart68681_start_ct(count); + start_ct(count); } else { // Counter mode - ISR |= INT_COUNTER_READY; - update_interrupts(); - duart68681_start_ct(0xffff); + set_ISR_bits(INT_COUNTER_READY); + start_ct(0xffff); + } + +} + +READ8_MEMBER( mc68681_device::read ) +{ + if (offset == 0x0c) + return IVR; + + uint8_t r = duart_base_device::read(space, offset, mem_mask); + + if (offset == 0x0d) + { + // bit 6 is /IACK (note the active-low) + if (m_read_vector) + r &= ~0x40; + else + r |= 0x40; } + return r; } READ8_MEMBER( mc68340_duart_device::read ) @@ -390,7 +430,7 @@ READ8_MEMBER( mc68340_duart_device::read ) r = m_chanB->read_MR2(); break; default: - r = mc68681_base_device::read(space, offset, mem_mask); + r = duart_base_device::read(space, offset, mem_mask); } return r; } @@ -402,7 +442,7 @@ READ8_MEMBER( sc28c94_device::read ) if (offset < 0x10) { - return mc68681_base_device::read(space, offset, mem_mask); + return duart_base_device::read(space, offset, mem_mask); } switch (offset) @@ -423,7 +463,7 @@ READ8_MEMBER( sc28c94_device::read ) return r; } -READ8_MEMBER( mc68681_base_device::read ) +READ8_MEMBER( duart_base_device::read ) { uint8_t r = 0xff; @@ -445,8 +485,7 @@ READ8_MEMBER( mc68681_base_device::read ) // reading this clears all the input change bits IPCR &= 0x0f; - ISR &= ~INT_INPUT_PORT_CHANGE; - update_interrupts(); + clear_ISR_bits(INT_INPUT_PORT_CHANGE); } break; @@ -455,11 +494,11 @@ READ8_MEMBER( mc68681_base_device::read ) break; case 0x06: /* CUR */ - r = duart68681_get_ct_count() >> 8; + r = get_ct_count() >> 8; break; case 0x07: /* CLR */ - r = duart68681_get_ct_count() & 0xff; + r = get_ct_count() & 0xff; break; case 0x08: /* MR1B/MR2B */ @@ -483,16 +522,6 @@ READ8_MEMBER( mc68681_base_device::read ) } r |= 0x80; // bit 7 is always set - - // bit 6 is /IACK (note the active-low) - if (m_read_vector) - { - r &= ~0x40; - } - else - { - r |= 0x40; - } break; case 0x0e: /* Start counter command */ @@ -504,18 +533,17 @@ READ8_MEMBER( mc68681_base_device::read ) } int count = std::max(CTR.w.l, uint16_t(1)); - duart68681_start_ct(count); + start_ct(count); break; } case 0x0f: /* Stop counter command */ - ISR &= ~INT_COUNTER_READY; + clear_ISR_bits(INT_COUNTER_READY); // Stop the counter only if (!(ACR & 0x40)) duart_timer->adjust(attotime::never); - update_interrupts(); break; default: @@ -527,6 +555,14 @@ READ8_MEMBER( mc68681_base_device::read ) return r; } +WRITE8_MEMBER( mc68681_device::write ) +{ + if (offset == 0x0c) + IVR = data; + else + duart_base_device::write(space, offset, data, mem_mask); +} + WRITE8_MEMBER( mc68340_duart_device::write ) { //printf("Duart write %02x -> %02x\n", data, offset); @@ -546,7 +582,7 @@ WRITE8_MEMBER( mc68340_duart_device::write ) m_chanB->write_MR2(data); break; default: - mc68681_base_device::write(space, offset, data, mem_mask); + duart_base_device::write(space, offset, data, mem_mask); } } @@ -556,7 +592,7 @@ WRITE8_MEMBER( sc28c94_device::write ) if (offset < 0x10) { - mc68681_base_device::write(space, offset, data, mem_mask); + duart_base_device::write(space, offset, data, mem_mask); } switch(offset) @@ -577,7 +613,7 @@ WRITE8_MEMBER( sc28c94_device::write ) } } -WRITE8_MEMBER( mc68681_base_device::write ) +WRITE8_MEMBER( duart_base_device::write ) { offset &= 0x0f; LOG( "Writing 68681 (%s) reg %x (%s) with %04x\n", tag(), offset, duart68681_reg_write_names[offset], data ); @@ -605,7 +641,7 @@ WRITE8_MEMBER( mc68681_base_device::write ) uint16_t count = std::max(CTR.w.l, uint16_t(1)); half_period = 0; - duart68681_start_ct(count); + start_ct(count); } else { @@ -616,15 +652,12 @@ WRITE8_MEMBER( mc68681_base_device::write ) // check for pending input port delta interrupts if ((((IPCR>>4) & data) & 0x0f) != 0) - { - ISR |= INT_INPUT_PORT_CHANGE; - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); m_chanA->ACR_updated(); m_chanB->ACR_updated(); m_chanA->update_interrupts(); m_chanB->update_interrupts(); - update_interrupts(); break; } case 0x05: /* IMR */ @@ -647,10 +680,6 @@ WRITE8_MEMBER( mc68681_base_device::write ) m_chanB->write_chan_reg(offset&3, data); break; - case 0x0c: /* IVR */ - IVR = data; - break; - case 0x0d: /* OPCR */ if (((data & 0xf) != 0x00) && ((data & 0xc) != 0x4)) logerror( "68681 (%s): Unhandled OPCR value: %02x\n", tag(), data); @@ -669,7 +698,7 @@ WRITE8_MEMBER( mc68681_base_device::write ) } } -WRITE_LINE_MEMBER( mc68681_base_device::ip0_w ) +WRITE_LINE_MEMBER( duart_base_device::ip0_w ) { uint8_t newIP = (IP_last_state & ~0x01) | ((state == ASSERT_LINE) ? 1 : 0); @@ -680,16 +709,13 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip0_w ) IPCR |= 0x10; if (ACR & 1) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip1_w ) +WRITE_LINE_MEMBER( duart_base_device::ip1_w ) { uint8_t newIP = (IP_last_state & ~0x02) | ((state == ASSERT_LINE) ? 2 : 0); @@ -700,16 +726,13 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip1_w ) IPCR |= 0x20; if (ACR & 2) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip2_w ) +WRITE_LINE_MEMBER( duart_base_device::ip2_w ) { uint8_t newIP = (IP_last_state & ~0x04) | ((state == ASSERT_LINE) ? 4 : 0); @@ -720,16 +743,13 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip2_w ) IPCR |= 0x40; if (ACR & 4) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip3_w ) +WRITE_LINE_MEMBER( duart_base_device::ip3_w ) { uint8_t newIP = (IP_last_state & ~0x08) | ((state == ASSERT_LINE) ? 8 : 0); @@ -740,37 +760,34 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip3_w ) IPCR |= 0x80; if (ACR & 8) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip4_w ) +WRITE_LINE_MEMBER( duart_base_device::ip4_w ) { uint8_t newIP = (IP_last_state & ~0x10) | ((state == ASSERT_LINE) ? 0x10 : 0); // TODO: special mode for ip4 (Ch. A Rx clock) IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip5_w ) +WRITE_LINE_MEMBER( duart_base_device::ip5_w ) { uint8_t newIP = (IP_last_state & ~0x20) | ((state == ASSERT_LINE) ? 0x20 : 0); // TODO: special mode for ip5 (Ch. B Tx clock) IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip6_w ) +WRITE_LINE_MEMBER( duart_base_device::ip6_w ) { uint8_t newIP = (IP_last_state & ~0x40) | ((state == ASSERT_LINE) ? 0x40 : 0); // TODO: special mode for ip6 (Ch. B Rx clock) IP_last_state = newIP; } -mc68681_channel *mc68681_base_device::get_channel(int chan) +duart_channel *duart_base_device::get_channel(int chan) { if (chan == 0) { @@ -780,7 +797,7 @@ mc68681_channel *mc68681_base_device::get_channel(int chan) return m_chanB; } -int mc68681_base_device::calc_baud(int ch, uint8_t data) +int duart_base_device::calc_baud(int ch, uint8_t data) { int baud_rate; @@ -825,20 +842,28 @@ int mc68681_base_device::calc_baud(int ch, uint8_t data) return baud_rate; } -void mc68681_base_device::clear_ISR_bits(int mask) +void duart_base_device::clear_ISR_bits(int mask) { - ISR &= ~mask; + if ((ISR & mask) != 0) + { + ISR &= ~mask; + update_interrupts(); + } } -void mc68681_base_device::set_ISR_bits(int mask) +void duart_base_device::set_ISR_bits(int mask) { - ISR |= mask; + if ((~ISR & mask) != 0) + { + ISR |= mask; + update_interrupts(); + } } // DUART channel class stuff -mc68681_channel::mc68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, MC68681_CHANNEL, tag, owner, clock), +duart_channel::duart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DUART_CHANNEL, tag, owner, clock), device_serial_interface(mconfig, *this), MR1(0), MR2(0), @@ -849,9 +874,9 @@ mc68681_channel::mc68681_channel(const machine_config &mconfig, const char *tag, { } -void mc68681_channel::device_start() +void duart_channel::device_start() { - m_uart = downcast(owner()); + m_uart = downcast(owner()); m_ch = m_uart->get_ch(this); // get our channel number save_item(NAME(CR)); @@ -872,7 +897,7 @@ void mc68681_channel::device_start() save_item(NAME(tx_ready)); } -void mc68681_channel::device_reset() +void duart_channel::device_reset() { write_CR(0x10); // reset MR write_CR(0x20); // reset Rx @@ -886,7 +911,7 @@ void mc68681_channel::device_reset() } // serial device virtual overrides -void mc68681_channel::rcv_complete() +void duart_channel::rcv_complete() { receive_register_extract(); @@ -910,7 +935,7 @@ void mc68681_channel::rcv_complete() } } -void mc68681_channel::tra_complete() +void duart_channel::tra_complete() { //printf("%s ch %d Tx complete\n", tag(), m_ch); tx_ready = 1; @@ -943,7 +968,7 @@ void mc68681_channel::tra_complete() update_interrupts(); } -void mc68681_channel::tra_callback() +void duart_channel::tra_callback() { // don't actually send in loopback mode if ((MR2&0xC0) != 0x80) @@ -973,7 +998,7 @@ void mc68681_channel::tra_callback() } } -void mc68681_channel::update_interrupts() +void duart_channel::update_interrupts() { if (rx_enabled) { @@ -1067,12 +1092,10 @@ void mc68681_channel::update_interrupts() } } - m_uart->update_interrupts(); - //logerror("DEBUG: 68681 int check: after receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR); } -uint8_t mc68681_channel::read_rx_fifo() +uint8_t duart_channel::read_rx_fifo() { uint8_t rv; @@ -1099,7 +1122,7 @@ uint8_t mc68681_channel::read_rx_fifo() return rv; } -uint8_t mc68681_channel::read_chan_reg(int reg) +uint8_t duart_channel::read_chan_reg(int reg) { uint8_t rv = 0xff; @@ -1132,7 +1155,7 @@ uint8_t mc68681_channel::read_chan_reg(int reg) return rv; } -void mc68681_channel::write_chan_reg(int reg, uint8_t data) +void duart_channel::write_chan_reg(int reg, uint8_t data) { switch (reg) { @@ -1159,7 +1182,7 @@ void mc68681_channel::write_chan_reg(int reg, uint8_t data) } } -void mc68681_channel::write_MR(uint8_t data) +void duart_channel::write_MR(uint8_t data) { if ( MR_ptr == 0 ) { @@ -1174,7 +1197,7 @@ void mc68681_channel::write_MR(uint8_t data) update_interrupts(); } -void mc68681_channel::recalc_framing() +void duart_channel::recalc_framing() { parity_t parity = PARITY_NONE; switch ((MR1>>3) & 3) @@ -1234,7 +1257,7 @@ void mc68681_channel::recalc_framing() set_data_frame(1, (MR1 & 3)+5, parity, stopbits); } -void mc68681_channel::write_CR(uint8_t data) +void duart_channel::write_CR(uint8_t data) { CR = data; @@ -1312,7 +1335,7 @@ void mc68681_channel::write_CR(uint8_t data) update_interrupts(); } -void mc68681_channel::write_TX(uint8_t data) +void duart_channel::write_TX(uint8_t data) { tx_data = data; @@ -1337,12 +1360,12 @@ void mc68681_channel::write_TX(uint8_t data) update_interrupts(); } -void mc68681_channel::ACR_updated() +void duart_channel::ACR_updated() { write_chan_reg(1, CSR); } -uint8_t mc68681_channel::get_chan_CSR() +uint8_t duart_channel::get_chan_CSR() { return CSR; } diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h index 694e6a45246..82a31f72b65 100644 --- a/src/devices/machine/mc68681.h +++ b/src/devices/machine/mc68681.h @@ -13,23 +13,23 @@ MCFG_DEVICE_REPLACE(_tag, MC68681, _clock) #define MCFG_MC68681_IRQ_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_irq_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_irq_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_A_TX_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_a_tx_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_a_tx_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_B_TX_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_b_tx_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_b_tx_cb(*device, DEVCB_##_cb); // deprecated: use ipX_w() instead #define MCFG_MC68681_INPORT_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_inport_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_inport_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_outport_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_outport_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \ - mc68681_base_device::static_set_clocks(*device, _a, _b, _c, _d); + duart_base_device::static_set_clocks(*device, _a, _b, _c, _d); // SC28C94 specific callbacks #define MCFG_SC28C94_ADD(_tag, _clock) \ @@ -48,13 +48,13 @@ #define MC68681_RX_FIFO_SIZE 3 // forward declaration -class mc68681_base_device; +class duart_base_device; -// mc68681_channel class -class mc68681_channel : public device_t, public device_serial_interface +// duart_channel class +class duart_channel : public device_t, public device_serial_interface { public: - mc68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + duart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; @@ -107,7 +107,7 @@ private: uint8_t tx_data; uint8_t tx_ready; - mc68681_base_device *m_uart; + duart_base_device *m_uart; void write_MR(uint8_t data); void write_CR(uint8_t data); @@ -115,15 +115,15 @@ private: void recalc_framing(); }; -class mc68681_base_device : public device_t +class duart_base_device : public device_t { - friend class mc68681_channel; + friend class duart_channel; public: - required_device m_chanA; - required_device m_chanB; - optional_device m_chanC; - optional_device m_chanD; + required_device m_chanA; + required_device m_chanB; + optional_device m_chanC; + optional_device m_chanD; // inline configuration helpers static void static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6); @@ -131,16 +131,15 @@ public: // API virtual DECLARE_READ8_MEMBER(read); virtual DECLARE_WRITE8_MEMBER(write); - uint8_t get_irq_vector() { m_read_vector = true; return IVR; } 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); } - template static devcb_base &set_irq_cb(device_t &device, Object &&cb) { return downcast(device).write_irq.set_callback(std::forward(cb)); } - template static devcb_base &set_a_tx_cb(device_t &device, Object &&cb) { return downcast(device).write_a_tx.set_callback(std::forward(cb)); } - template static devcb_base &set_b_tx_cb(device_t &device, Object &&cb) { return downcast(device).write_b_tx.set_callback(std::forward(cb)); } - template static devcb_base &set_inport_cb(device_t &device, Object &&cb) { return downcast(device).read_inport.set_callback(std::forward(cb)); } - template static devcb_base &set_outport_cb(device_t &device, Object &&cb) { return downcast(device).write_outport.set_callback(std::forward(cb)); } + template static devcb_base &set_irq_cb(device_t &device, Object &&cb) { return downcast(device).write_irq.set_callback(std::forward(cb)); } + template static devcb_base &set_a_tx_cb(device_t &device, Object &&cb) { return downcast(device).write_a_tx.set_callback(std::forward(cb)); } + template static devcb_base &set_b_tx_cb(device_t &device, Object &&cb) { return downcast(device).write_b_tx.set_callback(std::forward(cb)); } + template static devcb_base &set_inport_cb(device_t &device, Object &&cb) { return downcast(device).read_inport.set_callback(std::forward(cb)); } + template static devcb_base &set_outport_cb(device_t &device, Object &&cb) { return downcast(device).write_outport.set_callback(std::forward(cb)); } // new-style push handlers for input port bits DECLARE_WRITE_LINE_MEMBER( ip0_w ); @@ -151,8 +150,10 @@ public: DECLARE_WRITE_LINE_MEMBER( ip5_w ); DECLARE_WRITE_LINE_MEMBER( ip6_w ); + bool irq_pending() const { return (ISR & IMR) != 0; } + protected: - mc68681_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + duart_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; @@ -171,14 +172,11 @@ private: uint8_t ACR; /* Auxiliary Control Register */ uint8_t IMR; /* Interrupt Mask Register */ uint8_t ISR; /* Interrupt Status Register */ - uint8_t IVR; /* Interrupt Vector Register */ uint8_t OPCR; /* Output Port Conf. Register */ uint8_t OPR; /* Output Port Register */ PAIR CTR; /* Counter/Timer Preset Value */ uint8_t IPCR; /* Input Port Control Register */ - bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK - /* state */ uint8_t IP_last_state; /* last state of IP bits */ @@ -186,15 +184,15 @@ private: uint8_t half_period; emu_timer *duart_timer; - double duart68681_get_ct_rate(); - uint16_t duart68681_get_ct_count(); - void duart68681_start_ct(int count); + double get_ct_rate(); + uint16_t get_ct_count(); + void start_ct(int count); int calc_baud(int ch, uint8_t data); void clear_ISR_bits(int mask); void set_ISR_bits(int mask); - void update_interrupts(); + virtual void update_interrupts(); - int get_ch(mc68681_channel *ch) + int get_ch(duart_channel *ch) { if (ch == m_chanA) { @@ -212,16 +210,36 @@ private: return 3; } - mc68681_channel *get_channel(int chan); + duart_channel *get_channel(int chan); }; -class mc68681_device : public mc68681_base_device +class scn2681_device : public duart_base_device +{ +public: + scn2681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +class mc68681_device : public duart_base_device { public: mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; + uint8_t get_irq_vector() { m_read_vector = true; return IVR; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void update_interrupts() override; + +private: + bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK + + uint8_t IVR; /* Interrupt Vector Register */ }; -class sc28c94_device : public mc68681_base_device +class sc28c94_device : public duart_base_device { public: sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -241,10 +259,10 @@ protected: private: }; -class mc68340_duart_device : public mc68681_base_device +class mc68340_duart_device : public duart_base_device { public: - mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual DECLARE_READ8_MEMBER(read) override; virtual DECLARE_WRITE8_MEMBER(write) override; @@ -254,9 +272,10 @@ protected: mc68340_duart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); }; +DECLARE_DEVICE_TYPE(SCN2681, scn2681_device) DECLARE_DEVICE_TYPE(MC68681, mc68681_device) DECLARE_DEVICE_TYPE(SC28C94, sc28c94_device) DECLARE_DEVICE_TYPE(MC68340_DUART, mc68340_duart_device) -DECLARE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel) +DECLARE_DEVICE_TYPE(DUART_CHANNEL, duart_channel) #endif // MAME_MACHINE_MC68681_H diff --git a/src/mame/drivers/cit220.cpp b/src/mame/drivers/cit220.cpp index 0cb7d789172..4247d0fd99c 100644 --- a/src/mame/drivers/cit220.cpp +++ b/src/mame/drivers/cit220.cpp @@ -50,7 +50,7 @@ static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, cit220_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( io_map, AS_IO, 8, cit220_state ) - AM_RANGE(0x00, 0x0f) AM_DEVREADWRITE("duart", mc68681_device, read, write) + AM_RANGE(0x00, 0x0f) AM_DEVREADWRITE("duart", scn2681_device, read, write) AM_RANGE(0x10, 0x10) AM_DEVREADWRITE("usart", i8251_device, data_r, data_w) AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("usart", i8251_device, status_r, control_w) AM_RANGE(0x20, 0x27) AM_DEVREADWRITE("avdc", scn2674_device, read, write) @@ -92,7 +92,7 @@ static MACHINE_CONFIG_START( cit220p ) MCFG_DEVICE_ADDRESS_MAP(0, vram_map) MCFG_VIDEO_SET_SCREEN("screen") - MCFG_DEVICE_ADD("duart", MC68681, 3686400) + MCFG_DEVICE_ADD("duart", SCN2681, 3686400) MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", I8085_RST55_LINE)) MCFG_DEVICE_ADD("usart", I8251, 3000000) diff --git a/src/mame/drivers/microterm.cpp b/src/mame/drivers/microterm.cpp index f0e2f4532d7..12a3027600d 100644 --- a/src/mame/drivers/microterm.cpp +++ b/src/mame/drivers/microterm.cpp @@ -44,7 +44,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( mt420_io_map, AS_IO, 8, microterm_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0xe0, 0xef) AM_DEVREADWRITE("duart", mc68681_device, read, write) + AM_RANGE(0xe0, 0xef) AM_DEVREADWRITE("duart", scn2681_device, read, write) AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE("asci", mc2661_device, read, write) ADDRESS_MAP_END @@ -56,7 +56,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( mt5510_io_map, AS_IO, 8, microterm_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x60, 0x6f) AM_DEVREADWRITE("duart", mc68681_device, read, write) + AM_RANGE(0x60, 0x6f) AM_DEVREADWRITE("duart", scn2681_device, read, write) ADDRESS_MAP_END static INPUT_PORTS_START( microterm ) @@ -67,7 +67,7 @@ static MACHINE_CONFIG_START( mt420 ) MCFG_CPU_PROGRAM_MAP(mt420_mem_map) MCFG_CPU_IO_MAP(mt420_io_map) - MCFG_DEVICE_ADD("duart", MC68681, XTAL_3_6864MHz) // SCN2681 + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) // MC2681 MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", 0)) MCFG_MC68681_OUTPORT_CALLBACK(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(5) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, cs_write)) MCFG_DEVCB_BIT(4) @@ -76,7 +76,7 @@ static MACHINE_CONFIG_START( mt420 ) MCFG_DEVICE_ADD("asci", MC2661, XTAL_3_6864MHz) // SCN2641 MCFG_EEPROM_SERIAL_93C46_ADD("eeprom") - MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", mc68681_device, ip6_w)) + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", scn2681_device, ip6_w)) MACHINE_CONFIG_END static MACHINE_CONFIG_START( mt5510 ) @@ -84,7 +84,7 @@ static MACHINE_CONFIG_START( mt5510 ) MCFG_CPU_PROGRAM_MAP(mt5510_mem_map) MCFG_CPU_IO_MAP(mt5510_io_map) - MCFG_DEVICE_ADD("duart", MC68681, XTAL_3_6864MHz) // SCN2681 + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", 0)) MCFG_MC68681_OUTPORT_CALLBACK(DEVWRITELINE("eeprom1", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(6) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom2", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(5) @@ -94,10 +94,10 @@ static MACHINE_CONFIG_START( mt5510 ) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom2", eeprom_serial_93cxx_device, clk_write)) MCFG_DEVCB_BIT(3) MCFG_EEPROM_SERIAL_93C46_ADD("eeprom1") - MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", mc68681_device, ip6_w)) + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", scn2681_device, ip6_w)) MCFG_EEPROM_SERIAL_93C46_ADD("eeprom2") - MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", mc68681_device, ip5_w)) + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", scn2681_device, ip5_w)) MACHINE_CONFIG_END diff --git a/src/mame/includes/apollo.h b/src/mame/includes/apollo.h index e1006db7bee..b15bd7296b6 100644 --- a/src/mame/includes/apollo.h +++ b/src/mame/includes/apollo.h @@ -327,7 +327,7 @@ void apollo_csr_set_status_register(uint16_t mask, uint16_t data); #define MCFG_APOLLO_SIO_OUTPORT_CALLBACK(_cb) \ devcb = &apollo_sio::set_outport_cb(*device, DEVCB_##_cb); -class apollo_sio: public mc68681_base_device +class apollo_sio: public duart_base_device { public: apollo_sio(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); diff --git a/src/mame/machine/apollo.cpp b/src/mame/machine/apollo.cpp index 61a635e0f1e..5284d636c8f 100644 --- a/src/mame/machine/apollo.cpp +++ b/src/mame/machine/apollo.cpp @@ -713,7 +713,7 @@ TIMER_CALLBACK_MEMBER( apollo_state::apollo_rtc_timer ) #define VERBOSE 0 apollo_sio::apollo_sio(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - mc68681_base_device(mconfig, APOLLO_SIO, tag, owner, clock), + duart_base_device(mconfig, APOLLO_SIO, tag, owner, clock), m_csrb(0), m_ip6(0) { @@ -744,7 +744,7 @@ READ8_MEMBER( apollo_sio::read ) "1X/16X Test", "RHRB", "IVR", "Input Ports", "Start Counter", "Stop Counter" }; - int data = mc68681_base_device::read(space, offset/2, mem_mask); + int data = duart_base_device::read(space, offset/2, mem_mask); switch (offset / 2) { @@ -804,7 +804,7 @@ WRITE8_MEMBER( apollo_sio::write ) break; #endif } - mc68681_base_device::write(space, offset/2, data, mem_mask); + duart_base_device::write(space, offset/2, data, mem_mask); } // device type definition -- cgit v1.2.3