From dbcffd411f68c2879eda3ed949b34a3ed8348317 Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 2 Jan 2020 23:10:54 -0500 Subject: [PATCH] mc68901: Sweeping rewrite of USART emulation (no longer based on device_serial_interface), adding support for 16x clock prescaler and data transition synchronization, break generation and detection, internal loopback and synchronous mode. harriet, x68k_kbd: Adjust serial clocks to match MFP-generated baud rates. indiana: Replace serial ASCII keyboard with AT-style keyboard (which only mostly works). Document some clocks and interrupts. tti: Terminal actually works now. --- src/devices/machine/mc68901.cpp | 673 ++++++++++++++++++++++++-------- src/devices/machine/mc68901.h | 56 ++- src/mame/drivers/atarist.cpp | 19 +- src/mame/drivers/harriet.cpp | 20 +- src/mame/drivers/indiana.cpp | 61 +-- src/mame/drivers/micro3d.cpp | 6 +- src/mame/drivers/tti.cpp | 8 +- src/mame/drivers/x68k.cpp | 7 +- src/mame/includes/atarist.h | 3 - src/mame/machine/x68k_kbd.cpp | 2 +- 10 files changed, 611 insertions(+), 244 deletions(-) diff --git a/src/devices/machine/mc68901.cpp b/src/devices/machine/mc68901.cpp index fcb5f967dc4..3994a4863c6 100644 --- a/src/devices/machine/mc68901.cpp +++ b/src/devices/machine/mc68901.cpp @@ -1,9 +1,12 @@ // license:BSD-3-Clause -// copyright-holders:Curt Coder +// copyright-holders:Curt Coder, AJR /********************************************************************** Motorola MC68901 Multi Function Peripheral emulation + This chip was originally designed by Mostek (MK68901) as a 68000- + oriented evolution of the Z80 STI. + **********************************************************************/ /* @@ -34,12 +37,7 @@ the GLUE is essentially invisible w.r.t IPL. The CPU and the MFP manage to add the delays all by themselves. - - divide serial clock by 16 - - synchronous mode - - 1.5/2 stop bits - - interrupt on receiver break end - - interrupt on character boundaries during break transmission - - loopback mode + - RR & TR outputs */ @@ -47,7 +45,11 @@ #include "mc68901.h" #include "cpu/m68000/m68000.h" -//#define VERBOSE 1 +#define LOG_GENERAL (1 << 0U) +#define LOG_RCV (1 << 1U) +#define LOG_XMIT (1 << 2U) + +//#define VERBOSE (LOG_GENERAL | LOG_RCV | LOG_XMIT) #include "logmacro.h" @@ -196,6 +198,22 @@ inline void mc68901_device::take_interrupt(u16 mask) check_interrupts(); } +inline void mc68901_device::tx_buffer_empty() +{ + if (m_ier & IR_XMIT_BUFFER_EMPTY) + { + take_interrupt(IR_XMIT_BUFFER_EMPTY); + } +} + +inline void mc68901_device::tx_error() +{ + if (m_ier & IR_XMIT_ERROR) + { + take_interrupt(IR_XMIT_ERROR); + } +} + inline void mc68901_device::rx_buffer_full() { if (m_ier & IR_RCV_BUFFER_FULL) @@ -330,10 +348,7 @@ void mc68901_device::gpio_output() mc68901_device::mc68901_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MC68901, tag, owner, clock), - device_serial_interface(mconfig, *this), m_timer_clock(0), - m_rx_clock(0), - m_tx_clock(0), m_out_irq_cb(*this), m_out_gpio_cb(*this), m_out_tao_cb(*this), @@ -346,8 +361,28 @@ mc68901_device::mc68901_device(const machine_config &mconfig, const char *tag, d m_iack_chain_cb(*this), m_aer(0), m_ier(0), + m_scr(0), + m_scr_parity(false), + m_transmit_buffer(0), + m_receive_buffer(0), m_gpio_input(0), - m_gpio_output(0xff) + m_gpio_output(0xff), + m_rframe(0), + m_rclk(0), + m_rbits(0), + m_si_scan(0xff), + m_next_rsr(0), + m_rc(true), + m_si(true), + m_last_si(true), + m_rparity(false), + m_osr(0), + m_tclk(0), + m_tbits(0), + m_tc(true), + m_so(false), + m_tparity(false), + m_underrun(false) { } @@ -358,8 +393,6 @@ mc68901_device::mc68901_device(const machine_config &mconfig, const char *tag, d void mc68901_device::device_start() { - m_start_bit_hack_for_external_clocks = true; - /* resolve callbacks */ m_out_irq_cb.resolve_safe(); m_out_gpio_cb.resolve_safe(); @@ -378,16 +411,6 @@ void mc68901_device::device_start() m_timer[TIMER_C] = timer_alloc(TIMER_C); m_timer[TIMER_D] = timer_alloc(TIMER_D); - if (m_rx_clock > 0) - { - set_rcv_rate(m_rx_clock); - } - - if (m_tx_clock > 0) - { - set_tra_rate(m_tx_clock); - } - /* register for state saving */ save_item(NAME(m_gpip)); save_item(NAME(m_aer)); @@ -405,17 +428,30 @@ void mc68901_device::device_start() save_item(NAME(m_to)); save_item(NAME(m_ti)); save_item(NAME(m_scr)); + save_item(NAME(m_scr_parity)); save_item(NAME(m_ucr)); save_item(NAME(m_rsr)); save_item(NAME(m_tsr)); save_item(NAME(m_transmit_buffer)); - save_item(NAME(m_transmit_pending)); save_item(NAME(m_receive_buffer)); - save_item(NAME(m_overrun_pending)); save_item(NAME(m_gpio_input)); save_item(NAME(m_gpio_output)); - save_item(NAME(m_rsr_read)); + save_item(NAME(m_rframe)); + save_item(NAME(m_rclk)); + save_item(NAME(m_rbits)); + save_item(NAME(m_si_scan)); save_item(NAME(m_next_rsr)); + save_item(NAME(m_rc)); + save_item(NAME(m_si)); + save_item(NAME(m_last_si)); + save_item(NAME(m_rparity)); + save_item(NAME(m_osr)); + save_item(NAME(m_tclk)); + save_item(NAME(m_tbits)); + save_item(NAME(m_tc)); + save_item(NAME(m_so)); + save_item(NAME(m_tparity)); + save_item(NAME(m_underrun)); } @@ -425,13 +461,16 @@ void mc68901_device::device_start() void mc68901_device::device_reset() { - m_tsr = 0; - m_transmit_pending = false; - m_overrun_pending = false; + m_rsr = 0; + m_tsr = TSR_BUFFER_EMPTY; + m_underrun = false; + m_rclk = 0; + m_tclk = 0; // Avoid read-before-write m_ipr = m_imr = 0; + m_rframe = 0x100; m_next_rsr = 0; memset(m_tmc, 0, sizeof(m_tmc)); @@ -455,10 +494,8 @@ void mc68901_device::device_reset() write(REGISTER_TCDCR, 0); write(REGISTER_SCR, 0); write(REGISTER_UCR, 0); - write(REGISTER_RSR, 0); - transmit_register_reset(); - receive_register_reset(); + set_so(true); } @@ -474,84 +511,7 @@ void mc68901_device::device_timer(emu_timer &timer, device_timer_id id, int para //------------------------------------------------- -// tra_callback - -//------------------------------------------------- - -void mc68901_device::tra_callback() -{ - m_out_so_cb(transmit_register_get_data_bit()); -} - - -//------------------------------------------------- -// tra_complete - -//------------------------------------------------- - -void mc68901_device::tra_complete() -{ - if (m_tsr & TSR_XMIT_ENABLE) - { - if (m_transmit_pending) - { - transmit_register_setup(m_transmit_buffer); - m_transmit_pending = false; - m_tsr |= TSR_BUFFER_EMPTY; - - if (m_ier & IR_XMIT_BUFFER_EMPTY) - { - take_interrupt(IR_XMIT_BUFFER_EMPTY); - } - } - else - { - m_tsr |= TSR_UNDERRUN_ERROR; - // TODO: transmit error? - } - } - else - { - m_tsr |= TSR_END_OF_XMIT; - } -} - - -//------------------------------------------------- -// rcv_complete - -//------------------------------------------------- - -void mc68901_device::rcv_complete() -{ - receive_register_extract(); - if (m_rsr & RSR_BUFFER_FULL) - { - m_overrun_pending = true; - } - else - { - m_receive_buffer = get_received_char(); - m_rsr |= RSR_BUFFER_FULL; - LOG("Received Character: %02x\n", m_receive_buffer); - - if (is_receive_framing_error()) - m_rsr |= RSR_FRAME_ERROR; - else - m_rsr &= ~RSR_FRAME_ERROR; - - if (is_receive_parity_error()) - m_rsr |= RSR_PARITY_ERROR; - else - m_rsr &= ~RSR_PARITY_ERROR; - - if ((m_rsr & (RSR_FRAME_ERROR | RSR_PARITY_ERROR)) && (m_ier & IR_RCV_ERROR)) - rx_error(); - else - rx_buffer_full(); - } -} - - -//------------------------------------------------- -// read - +// read - read from one MFP register //------------------------------------------------- u8 mc68901_device::read(offs_t offset) @@ -595,7 +555,7 @@ u8 mc68901_device::read(offs_t offset) { /* clear UE bit (in reality, this won't be cleared until one full clock cycle of the transmitter has passed since the bit was set) */ u8 tsr = m_tsr; - if (!machine().side_effects_disabled()) + if (!machine().side_effects_disabled() && !m_underrun) m_tsr &= ~TSR_UNDERRUN_ERROR; return tsr; } @@ -604,10 +564,15 @@ u8 mc68901_device::read(offs_t offset) if (!machine().side_effects_disabled()) { m_rsr &= ~RSR_BUFFER_FULL; - if (m_overrun_pending) + if (m_next_rsr != 0) { - m_overrun_pending = false; - m_rsr |= RSR_OVERRUN_ERROR; + m_rsr |= m_next_rsr; + m_next_rsr = 0; + rx_error(); + } + if ((m_rsr & RSR_BREAK) && BIT(m_rframe, 9)) + { + m_rsr &= ~RSR_BREAK; rx_error(); } } @@ -620,7 +585,7 @@ u8 mc68901_device::read(offs_t offset) //------------------------------------------------- -// write - +// write - write to one MFP register //------------------------------------------------- void mc68901_device::write(offs_t offset, u8 data) @@ -917,6 +882,7 @@ void mc68901_device::write(offs_t offset, u8 data) LOG("MC68901 Sync Character : %x\n", data); m_scr = data; + m_scr_parity = BIT(population_count_32(data), 0); break; case REGISTER_UCR: @@ -931,60 +897,41 @@ void mc68901_device::write(offs_t offset, u8 data) case UCR_WORD_LENGTH_5: data_bit_count = 5; break; } - parity_t parity; - if (data & UCR_PARITY_ENABLED) { if (data & UCR_PARITY_EVEN) { LOG("MC68901 Parity : Even\n"); - - parity = PARITY_EVEN; } else { LOG("MC68901 Parity : Odd\n"); - - parity = PARITY_ODD; } } else { LOG("MC68901 Parity : Disabled\n"); - - parity = PARITY_NONE; } LOG("MC68901 Word Length : %u bits\n", data_bit_count); - int start_bits; - stop_bits_t stop_bits; - switch (data & 0x18) { case UCR_START_STOP_0_0: default: - start_bits = 0; - stop_bits = STOP_BITS_0; LOG("MC68901 Start Bits : 0, Stop Bits : 0, Format : synchronous\n"); break; case UCR_START_STOP_1_1: - start_bits = 1; - stop_bits = STOP_BITS_1; LOG("MC68901 Start Bits : 1, Stop Bits : 1, Format : asynchronous\n"); break; case UCR_START_STOP_1_15: - start_bits = 1; - stop_bits = STOP_BITS_1_5; LOG("MC68901 Start Bits : 1, Stop Bits : 1.5, Format : asynchronous\n"); break; case UCR_START_STOP_1_2: - start_bits = 1; - stop_bits = STOP_BITS_2; LOG("MC68901 Start Bits : 1, Stop Bits : 2, Format : asynchronous\n"); break; } @@ -998,9 +945,6 @@ void mc68901_device::write(offs_t offset, u8 data) LOG("MC68901 Rx/Tx Clock Divisor : 1\n"); } - set_data_frame(start_bits, data_bit_count, parity, stop_bits); - receive_register_reset(); - m_ucr = data; } break; @@ -1014,20 +958,32 @@ void mc68901_device::write(offs_t offset, u8 data) else { LOG("MC68901 Receiver Enabled\n"); + m_rsr |= RSR_RCV_ENABLE; if (data & RSR_SYNC_STRIP_ENABLE) { LOG("MC68901 Sync Strip Enabled\n"); + m_rsr |= RSR_SYNC_STRIP_ENABLE; } else { LOG("MC68901 Sync Strip Disabled\n"); + m_rsr &= ~RSR_SYNC_STRIP_ENABLE; } - if (data & RSR_FOUND_SEARCH) - LOG("MC68901 Receiver Search Mode Enabled\n"); - - m_rsr = data & 0x0b; + if ((m_ucr & UCR_START_STOP_1_2) == UCR_START_STOP_0_0) + { + if (data & RSR_FOUND_SEARCH) + { + LOG("MC68901 Receiver Search Mode Disabled\n"); + m_rsr |= RSR_FOUND_SEARCH; + } + else + { + LOG("MC68901 Receiver Search Mode Disabled\n"); + m_rsr &= ~RSR_FOUND_SEARCH; + } + } } break; @@ -1036,12 +992,11 @@ void mc68901_device::write(offs_t offset, u8 data) if ((data & TSR_XMIT_ENABLE) == 0) { - LOG("MC68901 Transmitter Disabled\n"); - m_tsr &= ~TSR_UNDERRUN_ERROR; + m_underrun = false; - if (is_transmit_register_empty()) - m_tsr |= TSR_END_OF_XMIT; + if (m_tbits == 0) + set_so((m_tsr & TSR_OUTPUT_MASK) != TSR_OUTPUT_LOW); } else { @@ -1082,29 +1037,13 @@ void mc68901_device::write(offs_t offset, u8 data) } m_tsr &= ~TSR_END_OF_XMIT; - - if (m_transmit_pending && is_transmit_register_empty()) - { - transmit_register_setup(m_transmit_buffer); - m_transmit_pending = false; - } - if (!m_transmit_pending) - m_tsr |= TSR_BUFFER_EMPTY; } break; case REGISTER_UDR: LOG("MC68901 UDR %x\n", data); m_transmit_buffer = data; - m_transmit_pending = true; m_tsr &= ~TSR_BUFFER_EMPTY; - - if ((m_tsr & TSR_XMIT_ENABLE) && is_transmit_register_empty()) - { - transmit_register_setup(m_transmit_buffer); - m_transmit_pending = false; - m_tsr |= TSR_BUFFER_EMPTY; - } break; } } @@ -1161,7 +1100,413 @@ WRITE_LINE_MEMBER( mc68901_device::tbi_w ) timer_input(TIMER_B, state); } -WRITE_LINE_MEMBER(mc68901_device::write_rx) +//************************************************************************** +// USART +//************************************************************************** + +//------------------------------------------------- +// si_w - serial data input for receiver +//------------------------------------------------- + +WRITE_LINE_MEMBER(mc68901_device::si_w) { - device_serial_interface::rx_w(state); + m_si = state; +} + +//------------------------------------------------- +// rc_w - receiver clock input +//------------------------------------------------- + +WRITE_LINE_MEMBER(mc68901_device::rc_w) +{ + if (state != m_rc) + { + // receiver active on rising edge + m_rc = state; + if (state && (m_rsr & RSR_RCV_ENABLE) && (m_tsr & TSR_OUTPUT_MASK) != TSR_OUTPUT_LOOP) + rx_clock(m_si); + } +} + +//------------------------------------------------- +// tc_w - transmitter clock input +//------------------------------------------------- + +WRITE_LINE_MEMBER(mc68901_device::tc_w) +{ + if (state != m_tc) + { + // transmitter active on falling edge + m_tc = state; + if (!state && ((m_tsr & TSR_XMIT_ENABLE) || !(m_tsr & TSR_END_OF_XMIT))) + tx_clock(); + else if (state && (m_rsr & RSR_RCV_ENABLE) && (m_tsr & TSR_OUTPUT_MASK) == TSR_OUTPUT_LOOP) + rx_clock(m_so); + } +} + +//------------------------------------------------- +// set_so - set serial output +//------------------------------------------------- + +void mc68901_device::set_so(bool state) +{ + if (m_so != state) + { + m_so = state; + m_out_so_cb(state); + } +} + +//------------------------------------------------- +// rx_frame_start - begin a new frame of received +// data (following start bit for async mode) +//------------------------------------------------- + +void mc68901_device::rx_frame_start() +{ + m_rframe = 0; + m_rbits = (m_ucr & UCR_WORD_LENGTH_MASK) >> 5; + m_rparity = (m_ucr & UCR_PARITY_EVEN) == UCR_PARITY_ODD; +} + +//------------------------------------------------- +// rx_sync_found - notify that a sync character +// was found +//------------------------------------------------- + +void mc68901_device::rx_sync_found() +{ + m_rsr |= RSR_FOUND_SEARCH; + LOGMASKED(LOG_RCV, "USART sync character found (%02X)\n", m_scr); + + // causes error interrupt, but does not fill receiver buffer + rx_error(); +} + +//------------------------------------------------- +// rx_async_frame_complete - finish receiving one +// character in asynchronous mode +//------------------------------------------------- + +void mc68901_device::rx_async_frame_complete() +{ + if (m_rsr & RSR_BUFFER_FULL) + { + LOGMASKED(LOG_RCV, "USART discarding received character %02X (%s)\n", m_rframe & 0xff, (m_rframe == 0 && !m_last_si) ? "break" : "overrun"); + m_next_rsr |= (m_rframe == 0 && !m_last_si) ? RSR_BREAK : RSR_OVERRUN_ERROR; + } + else if (m_rsr & RSR_OVERRUN_ERROR) + { + if (m_rframe == 0 && !m_last_si) + m_rsr |= RSR_BREAK; + } + else + { + // load the receiver buffer + m_receive_buffer = m_rframe & 0xff; + m_rsr |= RSR_BUFFER_FULL; + + // set error flags + m_rsr &= ~(RSR_PARITY_ERROR | RSR_FRAME_ERROR | RSR_BREAK); + if (m_rparity) + m_rsr |= RSR_PARITY_ERROR; + if (!m_last_si) + m_rsr |= m_rframe == 0 ? RSR_BREAK : RSR_FRAME_ERROR; + LOGMASKED(LOG_RCV, "USART received character: %02X (PE = %d, FE = %d, B = %d)\n", m_receive_buffer, + m_rparity, + !m_last_si && m_rframe != 0, + !m_last_si && m_rframe == 0); + + // set normal or error interrupt (if the latter is disabled, always use the former) + if ((m_rparity || !m_last_si) && (m_ier & IR_RCV_ERROR)) + rx_error(); + else + rx_buffer_full(); + } +} + +//------------------------------------------------- +// rx_sync_frame_complete - finish receiving one +// character in synchronous mode (error flags are +// different from asynchronous mode) +//------------------------------------------------- + +void mc68901_device::rx_sync_frame_complete() +{ + // check if sync character matches + bool match = (m_rframe & 0xff) == (m_scr & (0xff >> ((m_ucr & UCR_WORD_LENGTH_MASK) >> 5))) && !m_rparity; + + // suppress sync characters if strip option set + if (!match || !(m_rsr & RSR_SYNC_STRIP_ENABLE)) + { + if (m_rsr & RSR_BUFFER_FULL) + m_next_rsr |= RSR_OVERRUN_ERROR; + else if (!(m_rsr & RSR_OVERRUN_ERROR)) + { + // load the receiver buffer + m_receive_buffer = m_rframe & 0xff; + m_rsr |= RSR_BUFFER_FULL; + + // set error flags + m_rsr &= ~(RSR_FRAME_ERROR | RSR_PARITY_ERROR | RSR_MATCH); + if (m_rparity) + m_rsr |= RSR_PARITY_ERROR; + if (match) + m_rsr |= RSR_MATCH; + LOGMASKED(LOG_RCV, "USART received character: %02X (PE = %d, sync %smatched)\n", m_receive_buffer, + m_rparity, + match ? "not " : ""); + + // set normal or error interrupt (if the latter is disabled, always use the former) + if ((m_rparity || match) && (m_ier & IR_RCV_ERROR)) + rx_error(); + else + rx_buffer_full(); + } + } + else + LOGMASKED(LOG_RCV, "USART sync character stripped (%02X)\n", m_rframe & 0xff); +} + +//------------------------------------------------- +// rx_clock - process one active transition on +// the receiver clock +//------------------------------------------------- + +void mc68901_device::rx_clock(bool si) +{ + m_rclk++; + if (m_rclk >= 244) + m_rclk &= 15; + m_si_scan = (m_si_scan >> 1) | (si ? 0x80 : 0); + bool rclk_sync = (m_ucr & UCR_CLOCK_DIVIDE_16) == UCR_CLOCK_DIVIDE_1 || (m_rclk >= 4 && (m_si_scan & 0xe0) == (m_last_si ? 0 : 0xe0)); + bool sync_mode = (m_ucr & UCR_START_STOP_1_2) == UCR_START_STOP_0_0; + if (rclk_sync) + { + LOGMASKED(LOG_RCV, "SI = %d (synchronized); RSR = %02X; rframe = %X; %d rbits, %d rclks\n", si, m_rsr, m_rframe, m_rbits, m_rclk); + m_last_si = si; + if (si && !sync_mode && !(m_rsr & RSR_CHAR_IN_PROGRESS)) + { + m_rframe = 0x100; + if (!(m_rsr & RSR_BUFFER_FULL) && (m_rsr & RSR_BREAK)) + { + // valid 0 to 1 transition ends break condition + m_rsr &= ~RSR_BREAK; + rx_error(); + } + } + m_rclk = 0; + } + + if ((m_ucr & UCR_CLOCK_DIVIDE_16) == UCR_CLOCK_DIVIDE_1 || (m_rclk & 15) == 8) + { + if (sync_mode && !(m_rsr & RSR_FOUND_SEARCH)) + { + // search mode: continuous comparison + m_rframe = (m_rframe >> 1) | (m_last_si ? 0x100 : 0); + if ((m_ucr & UCR_PARITY_ENABLED) && (m_ucr & UCR_WORD_LENGTH_MASK) == UCR_WORD_LENGTH_8) + { + // check calculated parity of 8-bit sync character + if ((m_rframe & 0xff) == m_scr && m_last_si == ((m_ucr & UCR_PARITY_EVEN) ? m_scr_parity : !m_scr_parity)) + { + rx_sync_found(); + rx_frame_start(); + } + } + else + { + // parity, if any, must be included in SCR when words are less than 8 bits + int frame_bits = ((m_ucr & UCR_PARITY_ENABLED) ? 9 : 8) - ((m_ucr & UCR_WORD_LENGTH_MASK) >> 5); + if ((m_rframe >> (9 - frame_bits)) == (m_scr & ((1 << frame_bits) - 1))) + { + rx_sync_found(); + rx_frame_start(); + } + } + } + else if (sync_mode || (m_rsr & RSR_CHAR_IN_PROGRESS)) + { + if (m_rbits > 8) + { + rx_async_frame_complete(); + m_rframe = m_last_si ? 0x100 : 0; + m_rsr &= ~RSR_CHAR_IN_PROGRESS; + } + else + { + LOGMASKED(LOG_RCV, "USART shifting in %d %s bit\n", m_last_si, m_rbits < 8 ? "data" : "parity"); + m_rframe = (m_rframe >> 1) | (m_last_si ? 0x100 : 0); + if (m_last_si) + m_rparity = !m_rparity; + m_rbits++; + + if (m_rbits == 8) + { + // adjust for fewer than 8 data bits + m_rframe >>= (m_ucr & UCR_WORD_LENGTH_MASK) >> 5; + + // adjust for no parity + if (!(m_ucr & UCR_PARITY_ENABLED)) + { + m_rframe >>= 1; + m_rparity = false; + m_rbits++; + } + } + + if (m_rbits > 8 && sync_mode) + { + rx_sync_frame_complete(); + + // one character follows another in sync mode + rx_frame_start(); + } + } + } + else if (!m_last_si && BIT(m_rframe, 8)) + { + // start bit valid + LOGMASKED(LOG_RCV, "USART received start bit\n"); + m_rsr |= RSR_CHAR_IN_PROGRESS; + rx_frame_start(); + } + } +} + +//------------------------------------------------- +// tx_frame_load - load one character into the +// shift register for transmission +//------------------------------------------------- + +void mc68901_device::tx_frame_load(u8 data) +{ + // set up output shift register + m_osr = data; + m_tbits = 9 - ((m_ucr & UCR_WORD_LENGTH_MASK) >> 5); + m_tparity = (m_ucr & UCR_PARITY_EVEN) == UCR_PARITY_ODD; + + // add start and stop bits for asynchronous mode + if ((m_ucr & UCR_START_STOP_1_2) != UCR_START_STOP_0_0) + { + m_osr = (m_osr << 1) | (1 << m_tbits); + m_tbits += 2; + } +} + +//------------------------------------------------- +// tx_clock - process one active edge on the +// transmitter clock +//------------------------------------------------- + +void mc68901_device::tx_clock() +{ + if (m_tclk != 0) + { + m_tclk--; + return; + } + + m_underrun = false; + + bool sync_mode = (m_ucr & UCR_START_STOP_1_2) == UCR_START_STOP_0_0; + if (m_tbits == (sync_mode ? 2 : 3)) + { + // inject the calculated parity or skip that bit + if (m_ucr & UCR_PARITY_ENABLED) + m_osr = (m_osr << 1) | m_tparity; + else + m_tbits--; + } + + bool send_break = !sync_mode && (m_tsr & TSR_BREAK); + bool tbusy = false; + if (m_tbits != 0) + { + m_tbits--; + if (m_tbits != 0) + tbusy = true; + else if (!(m_tsr & TSR_XMIT_ENABLE)) + { + LOGMASKED(LOG_XMIT, "USART transmitter disabled\n"); + + // transmitter is now effectively disabled + m_tsr |= TSR_END_OF_XMIT; + tx_error(); + + // automatic turnaround enables the receiver + if (m_tsr & TSR_AUTO_TURNAROUND) + m_rsr |= RSR_RCV_ENABLE; + } + else if ((m_tsr & TSR_BUFFER_EMPTY) && !(m_tsr & TSR_UNDERRUN_ERROR) && !send_break) + { + LOGMASKED(LOG_XMIT, "USART transmitter underrun\n"); + + // underrun error condition + m_tsr |= TSR_UNDERRUN_ERROR; + m_underrun = true; + tx_error(); + } + } + + if (!tbusy && (m_tsr & TSR_XMIT_ENABLE)) + { + // break inhibits reload + if (!(m_tsr & TSR_BUFFER_EMPTY) && !send_break) + { + LOGMASKED(LOG_XMIT, "USART loading character (%02X)\n", m_transmit_buffer); + + // empty buffer into shift register + m_tsr |= TSR_BUFFER_EMPTY; + tx_buffer_empty(); + tx_frame_load(m_transmit_buffer); + tbusy = true; + } + else if (sync_mode) + { + LOGMASKED(LOG_XMIT, "USART loading sync character (%02X)\n", m_scr); + + // transmit sync characters if nothing else is loaded + tx_frame_load(m_scr); + tbusy = true; + } + } + + if (tbusy) + { + LOGMASKED(LOG_XMIT, "USART shifting out %d %s bit\n", BIT(m_osr, 0), + m_tbits == 1 && !sync_mode ? "stop" : m_tbits == (sync_mode ? 1 : 2) ? "parity" : "data or start"); + + // shift out one bit + set_so(BIT(m_osr, 0)); + if (BIT(m_osr, 0)) + m_tparity = !m_tparity; + m_osr >>= 1; + + if (m_tbits == 1 && (m_ucr & UCR_START_STOP_1_2) >= UCR_START_STOP_1_15) + { + // 1½ or 2 stop bits selected + if (m_ucr & UCR_CLOCK_DIVIDE_16) + m_tclk = (m_ucr & UCR_START_STOP_1_2) == UCR_START_STOP_1_2 ? 31 : 23; + else + m_tclk = (m_ucr & UCR_START_STOP_1_2) == UCR_START_STOP_1_2 ? 1 : 0; + } + else if (m_ucr & UCR_CLOCK_DIVIDE_16) + m_tclk = 15; + } + else if (!(m_tsr & TSR_XMIT_ENABLE)) + { + // high/low output on SO (Hi-Z not supported) + set_so((m_tsr & TSR_OUTPUT_MASK) != TSR_OUTPUT_LOW); + } + else if (send_break) + { + set_so(false); + m_tbits = 1; + } + else + { + // asynchronous marking condition + set_so(true); + } } diff --git a/src/devices/machine/mc68901.h b/src/devices/machine/mc68901.h index 2199cb434e9..cc792b34900 100644 --- a/src/devices/machine/mc68901.h +++ b/src/devices/machine/mc68901.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Curt Coder +// copyright-holders:Curt Coder, AJR /********************************************************************** Motorola MC68901 Multi Function Peripheral emulation @@ -38,8 +38,6 @@ #pragma once -#include "diserial.h" - //************************************************************************** // TYPE DEFINITIONS @@ -48,19 +46,14 @@ // ======================> mc68901_device -class mc68901_device : public device_t, - public device_serial_interface +class mc68901_device : public device_t { public: // construction/destruction mc68901_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); void set_timer_clock(int timer_clock) { m_timer_clock = timer_clock; } - void set_rx_clock(int rx_clock) { m_rx_clock = rx_clock; } - void set_tx_clock(int tx_clock) { m_tx_clock = tx_clock; } void set_timer_clock(const XTAL &xtal) { set_timer_clock(xtal.value()); } - void set_rx_clock(const XTAL &xtal) { set_rx_clock(xtal.value()); } - void set_tx_clock(const XTAL &xtal) { set_tx_clock(xtal.value()); } auto out_irq_cb() { return m_out_irq_cb.bind(); } auto out_gpio_cb() { return m_out_gpio_cb.bind(); } @@ -90,7 +83,9 @@ public: DECLARE_WRITE_LINE_MEMBER( tai_w ); DECLARE_WRITE_LINE_MEMBER( tbi_w ); - DECLARE_WRITE_LINE_MEMBER( write_rx ); + DECLARE_WRITE_LINE_MEMBER( si_w ); + DECLARE_WRITE_LINE_MEMBER( rc_w ); + DECLARE_WRITE_LINE_MEMBER( tc_w ); protected: // device-level overrides @@ -98,13 +93,10 @@ protected: virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - // device_serial_interface overrides - virtual void tra_callback() override; - virtual void tra_complete() override; - virtual void rcv_complete() override; - void check_interrupts(); void take_interrupt(u16 mask); + void tx_buffer_empty(); + void tx_error(); void rx_buffer_full(); void rx_error(); void timer_count(int index); @@ -112,6 +104,15 @@ protected: void gpio_input(int bit, int state); void gpio_output(); + void set_so(bool state); + void rx_frame_start(); + void rx_sync_found(); + void rx_async_frame_complete(); + void rx_sync_frame_complete(); + void rx_clock(bool si); + void tx_frame_load(u8 data); + void tx_clock(); + private: enum { @@ -204,8 +205,6 @@ private: static const int PRESCALER[]; int m_timer_clock; /* timer clock */ - int m_rx_clock; /* serial receive clock */ - int m_tx_clock; /* serial transmit clock */ devcb_write_line m_out_irq_cb; @@ -239,13 +238,12 @@ private: u8 m_tdr[4]; // timer data registers u8 m_scr; // synchronous character register + bool m_scr_parity; // parity of sync character u8 m_ucr; // USART control register u8 m_tsr; // transmitter status register u8 m_rsr; // receiver status register u8 m_transmit_buffer; // USART data register - bool m_transmit_pending; u8 m_receive_buffer; - bool m_overrun_pending; u8 m_gpio_input; u8 m_gpio_output; @@ -254,9 +252,25 @@ private: int m_ti[4]; // timer in latch int m_to[4]; // timer out latch - // serial state + // serial receiver state + u16 m_rframe; // receiver frame shift register + u8 m_rclk; // receiver clock counter + u8 m_rbits; // receiver bit counter + u8 m_si_scan; // receiver bitstream scan u8 m_next_rsr; // receiver status register latch - int m_rsr_read; // receiver status register read flag + bool m_rc; // receiver clock input + bool m_si; // serial data input + bool m_last_si; // synchronized serial data input + bool m_rparity; // receiver data parity + + // serial transmitter state + u16 m_osr; // output shift register + u8 m_tclk; // transmit clock counter + u8 m_tbits; // transmit bit counter + bool m_tc; // transmit clock input + bool m_so; // serial data output + bool m_tparity; // transmit data transmit + bool m_underrun; // underrun preset time // timers emu_timer *m_timer[4]; // counter timers diff --git a/src/mame/drivers/atarist.cpp b/src/mame/drivers/atarist.cpp index 13c67039f01..27b3fd6b514 100644 --- a/src/mame/drivers/atarist.cpp +++ b/src/mame/drivers/atarist.cpp @@ -1780,11 +1780,6 @@ WRITE_LINE_MEMBER(st_state::write_acia_clock) } -WRITE_LINE_MEMBER( st_state::mfp_tdo_w ) -{ - m_mfp->clock_w(state); -} - WRITE_LINE_MEMBER( st_state::fdc_drq_w ) { if (state && (!(m_fdc_mode & DMA_MODE_ENABLED)) && (m_fdc_mode & DMA_MODE_FDC_HDC_ACK)) @@ -2019,14 +2014,13 @@ void st_state::common(machine_config &config) MC68901(config, m_mfp, Y2/8); m_mfp->set_timer_clock(Y1); - m_mfp->set_rx_clock(0); - m_mfp->set_tx_clock(0); m_mfp->out_irq_cb().set_inputline(m_maincpu, M68K_IRQ_6); - m_mfp->out_tdo_cb().set(FUNC(st_state::mfp_tdo_w)); + m_mfp->out_tdo_cb().set(m_mfp, FUNC(mc68901_device::tc_w)); + m_mfp->out_tdo_cb().append(m_mfp, FUNC(mc68901_device::rc_w)); m_mfp->out_so_cb().set(m_rs232, FUNC(rs232_port_device::write_txd)); RS232_PORT(config, m_rs232, default_rs232_devices, nullptr); - m_rs232->rxd_handler().set(m_mfp, FUNC(mc68901_device::write_rx)); + m_rs232->rxd_handler().set(m_mfp, FUNC(mc68901_device::si_w)); m_rs232->dcd_handler().set(m_mfp, FUNC(mc68901_device::i1_w)); m_rs232->cts_handler().set(m_mfp, FUNC(mc68901_device::i2_w)); m_rs232->ri_handler().set(m_mfp, FUNC(mc68901_device::i6_w)); @@ -2224,10 +2218,9 @@ void stbook_state::stbook(machine_config &config) MC68901(config, m_mfp, U517/8); m_mfp->set_timer_clock(Y1); - m_mfp->set_rx_clock(0); - m_mfp->set_tx_clock(0); m_mfp->out_irq_cb().set_inputline(M68000_TAG, M68K_IRQ_6); - m_mfp->out_tdo_cb().set(FUNC(st_state::mfp_tdo_w)); + m_mfp->out_tdo_cb().set(m_mfp, FUNC(mc68901_device::tc_w)); + m_mfp->out_tdo_cb().append(m_mfp, FUNC(mc68901_device::rc_w)); m_mfp->out_so_cb().set(RS232_TAG, FUNC(rs232_port_device::write_txd)); WD1772(config, m_fdc, U517/2); @@ -2243,7 +2236,7 @@ void stbook_state::stbook(machine_config &config) m_centronics->set_output_latch(cent_data_out); RS232_PORT(config, m_rs232, default_rs232_devices, nullptr); - m_rs232->rxd_handler().set(m_mfp, FUNC(mc68901_device::write_rx)); + m_rs232->rxd_handler().set(m_mfp, FUNC(mc68901_device::si_w)); m_rs232->dcd_handler().set(m_mfp, FUNC(mc68901_device::i1_w)); m_rs232->cts_handler().set(m_mfp, FUNC(mc68901_device::i2_w)); m_rs232->ri_handler().set(m_mfp, FUNC(mc68901_device::i6_w)); diff --git a/src/mame/drivers/harriet.cpp b/src/mame/drivers/harriet.cpp index 9dac9ad279e..91dbdcd32fa 100644 --- a/src/mame/drivers/harriet.cpp +++ b/src/mame/drivers/harriet.cpp @@ -82,6 +82,17 @@ void harriet_state::machine_reset() } +static const input_device_default terminal_defaults[] = +{ + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_19200 ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_19200 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) + { nullptr, 0, 0 } +}; + void harriet_state::harriet(machine_config &config) { M68010(config, m_maincpu, 40_MHz_XTAL / 4); // MC68010FN10 @@ -91,11 +102,9 @@ void harriet_state::harriet(machine_config &config) mc68901_device &mfp(MC68901(config, "mfp", 40_MHz_XTAL / 16)); mfp.set_timer_clock(2.4576_MHz_XTAL); - mfp.set_rx_clock(9600); - mfp.set_tx_clock(9600); mfp.out_so_cb().set("rs232", FUNC(rs232_port_device::write_txd)); - //mfp.out_tco_cb().set("mfp", FUNC(mc68901_device::rc_w)); - //mfp.out_tdo_cb().set("mfp", FUNC(mc68901_device::tc_w)); + mfp.out_tco_cb().set("mfp", FUNC(mc68901_device::rc_w)); + mfp.out_tdo_cb().set("mfp", FUNC(mc68901_device::tc_w)); HD63450(config, "dmac", 40_MHz_XTAL / 4, "maincpu"); // MC68450R10 (or HD68450Y-10) @@ -103,8 +112,9 @@ void harriet_state::harriet(machine_config &config) NVRAM(config, "zpram", nvram_device::DEFAULT_ALL_0); // MK48Z02 rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); - rs232.rxd_handler().set("mfp", FUNC(mc68901_device::write_rx)); + rs232.rxd_handler().set("mfp", FUNC(mc68901_device::si_w)); rs232.rxd_handler().append("mfp", FUNC(mc68901_device::tbi_w)); + rs232.set_option_device_input_defaults("terminal", terminal_defaults); NSCSI_BUS(config, "scsia"); NSCSI_CONNECTOR(config, "scsia:7").option_set("wdc", WD33C93A).clock(40_MHz_XTAL / 4); diff --git a/src/mame/drivers/indiana.cpp b/src/mame/drivers/indiana.cpp index 9e87da7198b..3466fb936c1 100644 --- a/src/mame/drivers/indiana.cpp +++ b/src/mame/drivers/indiana.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic +// copyright-holders:Miodrag Milanovic, AJR /*************************************************************************** Indiana University 68030 board @@ -15,7 +15,8 @@ ****************************************************************************/ #include "emu.h" -#include "bus/rs232/keyboard.h" +#include "bus/pc_kbd/keyboards.h" +#include "bus/pc_kbd/pc_kbdc.h" #include "cpu/m68000/m68000.h" #include "bus/isa/com.h" #include "bus/isa/fdc.h" @@ -24,17 +25,19 @@ #include "bus/isa/isa_cards.h" #include "bus/isa/vga.h" #include "machine/mc68901.h" +#include "sound/spkrdev.h" +#include "speaker.h" -#define M68K_TAG "maincpu" #define ISABUS_TAG "isa" -#define MFP_TAG "mfp" class indiana_state : public driver_device { public: indiana_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , - m_maincpu(*this, M68K_TAG) { } + m_maincpu(*this, "maincpu") + { + } void indiana(machine_config &config); @@ -52,7 +55,7 @@ void indiana_state::indiana_mem(address_map &map) map.unmap_value_high(); map(0x00000000, 0x0000ffff).mirror(0x7f800000).rom().region("user1", 0); // 64Kb of EPROM map(0x00100000, 0x00107fff).mirror(0x7f8f8000).ram(); // SRAM 32Kb of SRAM - map(0x00200000, 0x002fffff).rw(MFP_TAG, FUNC(mc68901_device::read), FUNC(mc68901_device::write)).mirror(0x7f800000); // MFP + map(0x00200000, 0x002fffff).rw("mfp", FUNC(mc68901_device::read), FUNC(mc68901_device::write)).mirror(0x7f800000); // MFP map(0x00400000, 0x004fffff).rw(ISABUS_TAG, FUNC(isa16_device::io16_swap_r), FUNC(isa16_device::io16_swap_w)).mirror(0x7f800000); // 16 bit PC IO map(0x00500000, 0x005fffff).rw(ISABUS_TAG, FUNC(isa16_device::mem16_swap_r), FUNC(isa16_device::mem16_swap_w)).mirror(0x7f800000); // 16 bit PC MEM map(0x00600000, 0x006fffff).rw(ISABUS_TAG, FUNC(isa16_device::io_r), FUNC(isa16_device::io_w)).mirror(0x7f800000); // 8 bit PC IO @@ -86,38 +89,46 @@ void indiana_isa_cards(device_slot_interface &device) device.option_add("ide", ISA16_IDE); } -static DEVICE_INPUT_DEFAULTS_START( keyboard ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_1200 ) - DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) - DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 ) - DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE ) - DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) -DEVICE_INPUT_DEFAULTS_END - void indiana_state::indiana(machine_config &config) { /* basic machine hardware */ - M68030(config, m_maincpu, XTAL(16'000'000)); + M68030(config, m_maincpu, 16_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &indiana_state::indiana_mem); - // FIXME: determine ISA bus clock - isa16_device &isa(ISA16(config, ISABUS_TAG, 0)); + isa16_device &isa(ISA16(config, ISABUS_TAG, 16_MHz_XTAL / 2)); // OSC = CLK = CLK8 isa.set_custom_spaces(); + isa.irq3_callback().set_inputline(m_maincpu, M68K_IRQ_5); + isa.irq4_callback().set_inputline(m_maincpu, M68K_IRQ_4); + isa.irq5_callback().set_inputline(m_maincpu, M68K_IRQ_3); + isa.irq6_callback().set_inputline(m_maincpu, M68K_IRQ_2); + isa.irq7_callback().set_inputline(m_maincpu, M68K_IRQ_1); + isa.irq2_callback().set("mfp", FUNC(mc68901_device::i7_w)); // IRQ9 + isa.irq10_callback().set("mfp", FUNC(mc68901_device::i6_w)); + isa.irq11_callback().set("mfp", FUNC(mc68901_device::i5_w)); + isa.irq12_callback().set("mfp", FUNC(mc68901_device::i4_w)); + isa.irq14_callback().set("mfp", FUNC(mc68901_device::i3_w)); + isa.irq15_callback().set("mfp", FUNC(mc68901_device::i2_w)); ISA16_SLOT(config, "isa1", 0, ISABUS_TAG, indiana_isa_cards, "vga", false); ISA16_SLOT(config, "isa2", 0, ISABUS_TAG, indiana_isa_cards, "fdc_at", false); ISA16_SLOT(config, "isa3", 0, ISABUS_TAG, indiana_isa_cards, "comat", false); ISA16_SLOT(config, "isa4", 0, ISABUS_TAG, indiana_isa_cards, "ide", false); - mc68901_device &mfp(MC68901(config, MFP_TAG, XTAL(16'000'000)/4)); - mfp.set_timer_clock(XTAL(16'000'000)/4); - mfp.set_rx_clock(0); - mfp.set_tx_clock(0); - mfp.out_so_cb().set("keyboard", FUNC(rs232_port_device::write_txd)); + pc_kbdc_device &pc_kbdc(PC_KBDC(config, "pc_kbdc", 0)); + pc_kbdc.out_data_cb().set("mfp", FUNC(mc68901_device::i0_w)); + pc_kbdc.out_data_cb().append("mfp", FUNC(mc68901_device::si_w)); + pc_kbdc.out_clock_cb().set("mfp", FUNC(mc68901_device::i1_w)); + pc_kbdc.out_clock_cb().append("mfp", FUNC(mc68901_device::rc_w)); - rs232_port_device &keyboard(RS232_PORT(config, "keyboard", default_rs232_devices, "keyboard")); - keyboard.rxd_handler().set(MFP_TAG, FUNC(mc68901_device::write_rx)); - keyboard.set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(keyboard)); + PC_KBDC_SLOT(config, "kbd", pc_at_keyboards, STR_KBD_IBM_PC_AT_84).set_pc_kbdc_slot(subdevice("pc_kbdc")); + + mc68901_device &mfp(MC68901(config, "mfp", 16_MHz_XTAL / 4)); + mfp.set_timer_clock(16_MHz_XTAL / 16); + mfp.out_irq_cb().set_inputline(m_maincpu, M68K_IRQ_6); + mfp.out_tdo_cb().set("speaker", FUNC(speaker_sound_device::level_w)); + + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); } /* ROM definition */ diff --git a/src/mame/drivers/micro3d.cpp b/src/mame/drivers/micro3d.cpp index 9ffdcd847d7..d55a9a0ad94 100644 --- a/src/mame/drivers/micro3d.cpp +++ b/src/mame/drivers/micro3d.cpp @@ -346,11 +346,9 @@ void micro3d_state::micro3d(machine_config &config) mc68901_device &mfp(MC68901(config, "mfp", 4000000)); mfp.set_timer_clock(4000000); - mfp.set_rx_clock(0); - mfp.set_tx_clock(0); mfp.out_irq_cb().set_inputline("maincpu", M68K_IRQ_4); - //mfp.out_tao_cb().set("mfp", FUNC(mc68901_device::rc_w)); - //mfp.out_tao_cb().append("mfp", FUNC(mc68901_device::tc_w)); + mfp.out_tao_cb().set("mfp", FUNC(mc68901_device::rc_w)); + mfp.out_tao_cb().append("mfp", FUNC(mc68901_device::tc_w)); mfp.out_tco_cb().set("mfp", FUNC(mc68901_device::tbi_w)); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); diff --git a/src/mame/drivers/tti.cpp b/src/mame/drivers/tti.cpp index 16b1f5b8815..82eb421f8e0 100644 --- a/src/mame/drivers/tti.cpp +++ b/src/mame/drivers/tti.cpp @@ -157,9 +157,9 @@ void tti_state::tti(machine_config &config) m_maincpu->set_addrmap(m68008_device::AS_CPU_SPACE, &tti_state::fc7_map); MC68901(config, m_mfp, 20_MHz_XTAL / 2); // guess - m_mfp->set_timer_clock(20_MHz_XTAL / 2); // guess - m_mfp->set_rx_clock(9600); // for testing (FIXME: actually 16x) - m_mfp->set_tx_clock(9600); // for testing (FIXME: actually 16x) + m_mfp->set_timer_clock(2'457'600); // guess + m_mfp->out_tco_cb().set(m_mfp, FUNC(mc68901_device::rc_w)); + m_mfp->out_tdo_cb().set(m_mfp, FUNC(mc68901_device::tc_w)); m_mfp->out_so_cb().set("rs232", FUNC(rs232_port_device::write_txd)); m_mfp->out_irq_cb().set_inputline("maincpu", M68K_IRQ_2); // probably @@ -174,7 +174,7 @@ void tti_state::tti(machine_config &config) NSCSI_CONNECTOR(config, "scsibus:7", tti_scsi_devices, "asc", true).set_option_machine_config("asc", [this] (device_t *device) { asc_config(device); }); rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); - rs232.rxd_handler().set(m_mfp, FUNC(mc68901_device::write_rx)); + rs232.rxd_handler().set(m_mfp, FUNC(mc68901_device::si_w)); EEPROM_X24C44_16BIT(config, "novram").do_callback().set("mfp", FUNC(mc68901_device::i0_w)); diff --git a/src/mame/drivers/x68k.cpp b/src/mame/drivers/x68k.cpp index 3d190dc1d5a..4737c7fc512 100644 --- a/src/mame/drivers/x68k.cpp +++ b/src/mame/drivers/x68k.cpp @@ -1630,14 +1630,13 @@ void x68k_state::x68000_base(machine_config &config) /* device hardware */ MC68901(config, m_mfpdev, 16_MHz_XTAL / 4); m_mfpdev->set_timer_clock(16_MHz_XTAL / 4); - m_mfpdev->set_rx_clock(0); - m_mfpdev->set_tx_clock(0); m_mfpdev->out_irq_cb().set(FUNC(x68k_state::mfp_irq_callback)); - m_mfpdev->out_tbo_cb().set(m_mfpdev, FUNC(mc68901_device::clock_w)); + m_mfpdev->out_tbo_cb().set(m_mfpdev, FUNC(mc68901_device::tc_w)); + m_mfpdev->out_tbo_cb().append(m_mfpdev, FUNC(mc68901_device::rc_w)); m_mfpdev->out_so_cb().set("keyboard", FUNC(rs232_port_device::write_txd)); rs232_port_device &keyboard(RS232_PORT(config, "keyboard", keyboard_devices, "x68k")); - keyboard.rxd_handler().set(m_mfpdev, FUNC(mc68901_device::write_rx)); + keyboard.rxd_handler().set(m_mfpdev, FUNC(mc68901_device::si_w)); I8255A(config, m_ppi, 0); m_ppi->in_pa_callback().set(FUNC(x68k_state::ppi_port_a_r)); diff --git a/src/mame/includes/atarist.h b/src/mame/includes/atarist.h index 2c4d97fac46..cc369d40452 100644 --- a/src/mame/includes/atarist.h +++ b/src/mame/includes/atarist.h @@ -238,9 +238,6 @@ public: DECLARE_WRITE_LINE_MEMBER( ikbd_tx_w ); - DECLARE_READ8_MEMBER( mfp_gpio_r ); - DECLARE_WRITE_LINE_MEMBER( mfp_tdo_w ); - DECLARE_WRITE_LINE_MEMBER( write_acia_clock ); void toggle_dma_fifo(); diff --git a/src/mame/machine/x68k_kbd.cpp b/src/mame/machine/x68k_kbd.cpp index 6704afad127..d74a77f17a6 100644 --- a/src/mame/machine/x68k_kbd.cpp +++ b/src/mame/machine/x68k_kbd.cpp @@ -276,7 +276,7 @@ void x68k_keyboard_device::device_reset() buffered_rs232_device::device_reset(); set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); - set_rate(38'400); // TODO: Should be 2400 but MC68901 doesn't support divide by 16 + set_rate(2400); receive_register_reset(); transmit_register_reset();