From 743ac098e40f2e9aa8df0a0ef9b0233a8cc68d9d Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Mon, 8 May 2023 16:16:50 +0700 Subject: mcs51: implement serial input/output as bit stream (#11190) * fix [MT#05495](https://mametesters.org/view.php?id=5495) --- src/devices/cpu/mcs51/mcs51.cpp | 330 +++++++++++++++++++++----------- src/devices/cpu/mcs51/mcs51.h | 21 +- src/devices/cpu/mcs51/mcs51ops.hxx | 2 +- src/devices/machine/archimedes_keyb.cpp | 37 +--- src/devices/machine/archimedes_keyb.h | 13 +- src/devices/sound/qs1000.cpp | 28 --- src/devices/sound/qs1000.h | 7 - src/emu/diserial.cpp | 3 +- src/mame/acorn/ssfindo.cpp | 22 ++- src/mame/eolith/eolith.cpp | 18 +- src/mame/ibm/rtpc.cpp | 23 +-- src/mame/intel/basic52.cpp | 76 ++++---- src/mame/leapfrog/iquest.cpp | 25 --- src/mame/maygay/maygayv1.cpp | 94 +++------ src/mame/misc/micro3d.cpp | 2 - src/mame/misc/micro3d.h | 2 - src/mame/misc/micro3d_m.cpp | 22 +-- src/mame/misc/piggypas.cpp | 17 +- src/mame/philips/cdi.cpp | 57 +++--- src/mame/philips/cdi.h | 12 +- src/mame/philips/minitel_2_rpic.cpp | 13 +- src/mame/pinball/mephistp.cpp | 1 - src/mame/siemens/pcd.h | 15 +- src/mame/siemens/pcd_v.cpp | 33 ++-- src/mame/skeleton/pes.cpp | 43 +++-- src/mame/skeleton/sk101bl.cpp | 2 - src/mame/trs/trs80dt1.cpp | 23 ++- src/mame/wang/wangpckb.cpp | 100 ++-------- src/mame/wang/wangpckb.h | 14 +- 29 files changed, 487 insertions(+), 568 deletions(-) diff --git a/src/devices/cpu/mcs51/mcs51.cpp b/src/devices/cpu/mcs51/mcs51.cpp index 0b85d6c22cf..0b874abe784 100644 --- a/src/devices/cpu/mcs51/mcs51.cpp +++ b/src/devices/cpu/mcs51/mcs51.cpp @@ -134,9 +134,13 @@ #include "mcs51.h" #include "mcs51dasm.h" -#define VERBOSE 0 +#define LOG_RX (1U << 1) +#define LOG_TX (1U << 2) + +#define VERBOSE (0) + +#include "logmacro.h" -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) /*************************************************************************** CONSTANTS @@ -223,6 +227,22 @@ enum V_PFI = 0x02b /* Power Failure Interrupt */ }; +enum serial_state : u8 +{ + SIO_IDLE, + SIO_START_LE, + SIO_START, + SIO_DATA0, + SIO_DATA1, + SIO_DATA2, + SIO_DATA3, + SIO_DATA4, + SIO_DATA5, + SIO_DATA6, + SIO_DATA7, + SIO_DATA8, + SIO_STOP, +}; DEFINE_DEVICE_TYPE(I8031, i8031_device, "i8031", "Intel 8031") DEFINE_DEVICE_TYPE(I8032, i8032_device, "i8032", "Intel 8032") @@ -281,8 +301,6 @@ mcs51_cpu_device::mcs51_cpu_device(const machine_config &mconfig, device_type ty , m_scratchpad(*this, "scratchpad") , m_port_in_cb(*this) , m_port_out_cb(*this) - , m_serial_tx_cb(*this) - , m_serial_rx_cb(*this) , m_rtemp(0) { m_ds5002fp.mcon = 0; @@ -797,7 +815,7 @@ void mcs51_cpu_device::clear_current_irq() m_cur_irq_prio = 0; else m_cur_irq_prio = -1; - LOG(("New: %d %02x\n", m_cur_irq_prio, m_irq_active)); + LOG("New: %d %02x\n", m_cur_irq_prio, m_irq_active); } uint8_t mcs51_cpu_device::r_acc() { return SFR_A(ADDR_ACC); } @@ -997,19 +1015,65 @@ void mcs51_cpu_device::do_sub_flags(uint8_t a, uint8_t data, uint8_t c) SET_OV((result1 < -128 || result1 > 127)); } +void mcs51_cpu_device::transmit(bool state) +{ + if (BIT(SFR_A(ADDR_P3), 1) != state) + { + if (state) + SFR_A(ADDR_P3) |= 1U << 1; + else + SFR_A(ADDR_P3) &= ~(1U << 1); + + m_port_out_cb[3](SFR_A(ADDR_P3)); + } +} + void mcs51_cpu_device::transmit_receive(int source) { int mode = (GET_SM0<<1) | GET_SM1; if (source == 1) /* timer1 */ - m_uart.smod_div = (m_uart.smod_div + 1) & (2-GET_SMOD); + m_uart.smod_div = (m_uart.smod_div + 1) & (1-GET_SMOD); switch(mode) { - //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12 + // 8 bit shifter - rate set by clock freq / 12 case 0: - m_uart.rx_clk += (source == 0) ? 16 : 0; /* clock / 12 */ - m_uart.tx_clk += (source == 0) ? 16 : 0; /* clock / 12 */ - break; + if (source == 0) + { + // TODO: mode 0 serial input is unemulated + // FIXME: output timing is highly simplified and incorrect + switch (m_uart.txbit) + { + case SIO_IDLE: + break; + case SIO_START: + SFR_A(ADDR_P3) |= 0x03; + m_port_out_cb[3](SFR_A(ADDR_P3)); + m_uart.txbit = SIO_DATA0; + break; + case SIO_DATA0: case SIO_DATA1: case SIO_DATA2: case SIO_DATA3: + case SIO_DATA4: case SIO_DATA5: case SIO_DATA6: case SIO_DATA7: + SFR_A(ADDR_P3) &= ~0x03; + if (BIT(m_uart.data_out, m_uart.txbit - SIO_DATA0)) + SFR_A(ADDR_P3) |= 1U << 0; + m_port_out_cb[3](SFR_A(ADDR_P3)); + + if (m_uart.txbit == SIO_DATA7) + { + SET_TI(1); + m_uart.txbit = SIO_STOP; + } + else + m_uart.txbit++; + break; + case SIO_STOP: + SFR_A(ADDR_P3) |= 0x03; + m_port_out_cb[3](SFR_A(ADDR_P3)); + m_uart.txbit = SIO_IDLE; + break; + } + } + return; //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2 case 1: case 3: @@ -1030,39 +1094,139 @@ void mcs51_cpu_device::transmit_receive(int source) m_uart.tx_clk += (source == 0) ? (GET_SMOD ? 6 : 3) : 0; /* clock / 12 */ break; } - /* transmit ? */ + + // transmit if (m_uart.tx_clk >= 16) { m_uart.tx_clk &= 0x0f; - if(m_uart.bits_to_send) + + switch (m_uart.txbit) { - m_uart.bits_to_send--; - if(m_uart.bits_to_send == 0) { - //Call the callback function - m_serial_tx_cb(0, m_uart.data_out, 0xff); - //Set Interrupt Flag - SET_TI(1); - } + case SIO_IDLE: + transmit(1); + break; + case SIO_START: + LOGMASKED(LOG_TX, "tx start bit (%s)\n", machine().time().to_string()); + transmit(0); + m_uart.txbit = SIO_DATA0; + break; + case SIO_DATA0: case SIO_DATA1: case SIO_DATA2: case SIO_DATA3: + case SIO_DATA4: case SIO_DATA5: case SIO_DATA6: case SIO_DATA7: + LOGMASKED(LOG_TX, "tx bit %d data %d (%s)\n", m_uart.txbit - SIO_DATA0, BIT(m_uart.data_out, m_uart.txbit - SIO_DATA0), machine().time().to_string()); + transmit(BIT(m_uart.data_out, m_uart.txbit - SIO_DATA0)); + + // mode 1 has no data8/parity bit + if (mode == 1 && m_uart.txbit == SIO_DATA7) + m_uart.txbit = SIO_STOP; + else + m_uart.txbit++; + break; + case SIO_DATA8: // data8/parity bit + LOGMASKED(LOG_TX, "tx bit %d data %d (%s)\n", m_uart.txbit - SIO_DATA0, GET_TB8, machine().time().to_string()); + transmit(GET_TB8); + m_uart.txbit = SIO_STOP; + break; + case SIO_STOP: + LOGMASKED(LOG_TX, "tx stop bit (%s)\n", machine().time().to_string()); + transmit(1); + SET_TI(1); + m_uart.txbit = SIO_IDLE; + break; } - } - /* receive */ - if (m_uart.rx_clk >= 16) + + // receive + if (m_uart.rx_clk >= 16 || m_uart.rxbit < SIO_START) { m_uart.rx_clk &= 0x0f; - if (m_uart.delay_cycles>0) + + if (GET_REN) { - m_uart.delay_cycles--; - if (m_uart.delay_cycles == 0) + // directly read RXD input + bool const data = BIT(m_port_in_cb[3](), 0); + + switch (m_uart.rxbit) { - int data = 0; - //Call our callball function to retrieve the data - data = m_serial_rx_cb(0, 0xff); - LOG(("RX Deliver %d\n", data)); - SET_SBUF(data); - //Flag the IRQ - SET_RI(1); - SET_RB8(1); // HACK force 2nd stop bit + case SIO_IDLE: + if (data) + m_uart.rxbit = SIO_START_LE; + break; + case SIO_START_LE: // start bit leading edge + if (!data) + { + LOGMASKED(LOG_RX, "rx start leading edge (%s)\n", machine().time().to_string()); + m_uart.rxbit = SIO_START; + m_uart.rx_clk = 8; + } + break; + case SIO_START: + if (!data) + { + LOGMASKED(LOG_RX, "rx start bit (%s)\n", machine().time().to_string()); + + m_uart.data_in = 0; + m_uart.rxbit = SIO_DATA0; + } + else + // false start bit + m_uart.rxbit = SIO_START_LE; + break; + case SIO_DATA0: case SIO_DATA1: case SIO_DATA2: case SIO_DATA3: + case SIO_DATA4: case SIO_DATA5: case SIO_DATA6: case SIO_DATA7: + LOGMASKED(LOG_RX, "rx bit %d data %d (%s)\n", m_uart.rxbit - SIO_DATA0, data, machine().time().to_string()); + if (data) + m_uart.data_in |= 1U << (m_uart.rxbit - SIO_DATA0); + + // mode 1 has no data8/parity bit + if (mode == 1 && m_uart.rxbit == SIO_DATA7) + m_uart.rxbit = SIO_STOP; + else + m_uart.rxbit++; + break; + case SIO_DATA8: // data8/parity bit + LOGMASKED(LOG_RX, "rx bit %d data %d (%s)\n", m_uart.rxbit - SIO_DATA0, data, machine().time().to_string()); + m_uart.rxb8 = data; + m_uart.rxbit = SIO_STOP; + break; + case SIO_STOP: + if (!GET_RI) + { + switch (mode) + { + case 1: + LOGMASKED(LOG_RX, "rx byte 0x%02x stop %d (%s)\n", m_uart.data_in, data, machine().time().to_string()); + SET_SBUF(m_uart.data_in); + if (!GET_SM2) + { + // RB8 contains stop bit + SET_RB8(data); + SET_RI(1); + } + else if (data) + // RI if valid stop bit + SET_RI(1); + break; + case 2: + case 3: + LOGMASKED(LOG_RX, "rx byte 0x%02x RB8 %d stop %d (%s)\n", m_uart.data_in, m_uart.rxb8, data, machine().time().to_string()); + SET_SBUF(m_uart.data_in); + SET_RB8(m_uart.rxb8); + + // no RI if SM2 && !RB8 + if (!GET_SM2 || GET_RB8) + SET_RI(1); + break; + } + } + else + LOGMASKED(LOG_RX, "rx overrun discarding data 0x%02x\n", m_uart.data_in); + + // next state depends on stop bit validity + if (data) + m_uart.rxbit = SIO_START_LE; + else + m_uart.rxbit = SIO_IDLE; + break; } } } @@ -1325,56 +1489,6 @@ void mcs51_cpu_device::update_timers(int cycles) } } -//Set up to transmit data out of serial port -//NOTE: Enable Serial Port Interrupt bit is NOT required to send/receive data! - -void mcs51_cpu_device::serial_transmit(uint8_t data) -{ - int mode = (GET_SM0<<1) | GET_SM1; - - //Flag that we're sending data - m_uart.data_out = data; - LOG(("serial_transmit: %x %x\n", mode, data)); - switch(mode) { - //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12 - case 0: - m_uart.bits_to_send = 8+2; - break; - //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2 - case 1: - m_uart.bits_to_send = 8+2; - break; - //9 bit uart - case 2: - case 3: - m_uart.bits_to_send = 8+3; - break; - } -} - -void mcs51_cpu_device::serial_receive() -{ - int mode = (GET_SM0<<1) | GET_SM1; - - if (GET_REN) { - switch(mode) { - //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12 - case 0: - m_uart.delay_cycles = 8+2; - break; - //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2 - case 1: - m_uart.delay_cycles = 8+2; - break; - //9 bit uart - case 2: - case 3: - m_uart.delay_cycles = 8+3; - break; - } - } -} - /* Check and update status of serial port */ void mcs51_cpu_device::update_serial(int cycles) { @@ -1819,10 +1933,10 @@ void mcs51_cpu_device::check_irqs() /* Skip the interrupt request if currently processing interrupt * and the new request does not have a higher priority */ - LOG(("Request: %d\n", priority_request)); + LOG("Request: %d\n", priority_request); if (m_irq_active && (priority_request <= m_cur_irq_prio)) { - LOG(("higher or equal priority irq (%u) in progress already, skipping ...\n", m_cur_irq_prio)); + LOG("higher or equal priority irq (%u) in progress already, skipping ...\n", m_cur_irq_prio); return; } @@ -1853,7 +1967,7 @@ void mcs51_cpu_device::check_irqs() m_cur_irq_prio = priority_request; m_irq_active |= (1 << priority_request); - LOG(("Take: %d %02x\n", m_cur_irq_prio, m_irq_active)); + LOG("Take: %d %02x\n", m_cur_irq_prio, m_irq_active); //Clear any interrupt flags that should be cleared since we're servicing the irq! switch(int_vec) { @@ -1994,14 +2108,6 @@ void mcs51_cpu_device::execute_set_input(int irqline, int state) fatalerror("mcs51: Trying to set T2EX_LINE on a non I8052 type cpu.\n"); break; - case MCS51_RX_LINE: /* Serial Port Receive */ - /* Is the enable flags for this interrupt set? */ - if (state != CLEAR_LINE) - { - serial_receive(); - } - break; - /* Power Fail Interrupt */ case DS5002FP_PFI_LINE: if (m_features & FEATURE_DS5002FP) @@ -2099,12 +2205,14 @@ void mcs51_cpu_device::sfr_write(size_t offset, uint8_t data) case ADDR_P1: m_port_out_cb[1](data); break; case ADDR_P2: m_port_out_cb[2](data); break; case ADDR_P3: m_port_out_cb[3](data); break; - case ADDR_SBUF: serial_transmit(data); break; + case ADDR_SBUF: + LOGMASKED(LOG_TX, "tx byte 0x%02x\n", data); + m_uart.data_out = data; + m_uart.txbit = SIO_START; + break; case ADDR_PSW: SET_PARITY(); break; case ADDR_ACC: SET_PARITY(); break; case ADDR_IP: update_irq_prio(data, 0); break; - /* R_SBUF = data; //This register is used only for "Receiving data coming in!" */ - case ADDR_B: case ADDR_SP: case ADDR_DPL: @@ -2117,10 +2225,18 @@ void mcs51_cpu_device::sfr_write(size_t offset, uint8_t data) case ADDR_TL1: case ADDR_TH0: case ADDR_TH1: + break; case ADDR_SCON: + if (!GET_REN && BIT(data, 4)) + { + LOGMASKED(LOG_RX, "rx enabled SCON 0x%02x\n", data); + if (!BIT(data, 6, 2)) + logerror("mode 0 serial input is not emulated\n"); + m_uart.rxbit = SIO_IDLE; + } break; default: - LOG(("mcs51 '%s': attemping to write to an invalid/non-implemented SFR address: %x at 0x%04x, data=%x\n", tag(), (uint32_t)offset,PC,data)); + LOG("attemping to write to an invalid/non-implemented SFR address: %x at 0x%04x, data=%x\n", (uint32_t)offset,PC,data); /* no write in this case according to manual */ return; } @@ -2162,7 +2278,7 @@ uint8_t mcs51_cpu_device::sfr_read(size_t offset) return m_data.read_byte((size_t) offset | 0x100); /* Illegal or non-implemented sfr */ default: - LOG(("mcs51 '%s': attemping to read an invalid/non-implemented SFR address: %x at 0x%04x\n", tag(), (uint32_t)offset,PC)); + LOG("attemping to read an invalid/non-implemented SFR address: %x at 0x%04x\n", (uint32_t)offset,PC); /* according to the manual, the read may return random bits */ return 0xff; } @@ -2177,8 +2293,6 @@ void mcs51_cpu_device::device_start() m_port_in_cb.resolve_all_safe(0xff); m_port_out_cb.resolve_all_safe(); - m_serial_rx_cb.resolve_safe(0); - m_serial_tx_cb.resolve_safe(); /* Save states */ save_item(NAME(m_ppc)); @@ -2200,11 +2314,10 @@ void mcs51_cpu_device::device_start() save_item(NAME(m_ds5002fp.rnr_delay) ); save_item(NAME(m_ds5002fp.range) ); save_item(NAME(m_uart.data_out)); - save_item(NAME(m_uart.bits_to_send)); + save_item(NAME(m_uart.data_in)); save_item(NAME(m_uart.smod_div)); save_item(NAME(m_uart.rx_clk)); save_item(NAME(m_uart.tx_clk)); - save_item(NAME(m_uart.delay_cycles)); state_add( MCS51_PC, "PC", m_pc).formatstr("%04X"); state_add( MCS51_SP, "SP", SP).formatstr("%02X"); @@ -2346,10 +2459,11 @@ void mcs51_cpu_device::device_reset() } m_uart.data_out = 0; + m_uart.data_in = 0; m_uart.rx_clk = 0; m_uart.tx_clk = 0; - m_uart.bits_to_send = 0; - m_uart.delay_cycles = 0; + m_uart.txbit = SIO_IDLE; + m_uart.rxbit = SIO_IDLE; m_uart.smod_div = 0; m_recalc_parity = 0; @@ -2441,8 +2555,8 @@ uint8_t i80c52_device::sfr_read(size_t offset) ****************************************************************************/ -#define DS5_LOGW(a, d) LOG(("ds5002fp '%s': write to " # a " register at 0x%04x, data=%x\n", tag(), PC, d)) -#define DS5_LOGR(a, d) LOG(("ds5002fp '%s': read from " # a " register at 0x%04x\n", tag(), PC)) +#define DS5_LOGW(a, d) LOG("write to " # a " register at 0x%04x, data=%x\n", PC, d) +#define DS5_LOGR(a, d) LOG("read from " # a " register at 0x%04x\n", PC) uint8_t mcs51_cpu_device::ds5002fp_protected(size_t offset, uint8_t data, uint8_t ta_mask, uint8_t mask) { @@ -2467,7 +2581,7 @@ void ds5002fp_device::sfr_write(size_t offset, uint8_t data) if ((data == 0xaa) && (m_ds5002fp.ta_window == 0)) { m_ds5002fp.ta_window = 6; /* 4*12 + 2*12 */ - LOG(("ds5002fp '%s': TA window initiated at 0x%04x\n", tag(), PC)); + LOG("TA window initiated at 0x%04x\n", PC); } break; case ADDR_MCON: data = ds5002fp_protected(ADDR_MCON, data, 0x0f, 0xf7); DS5_LOGW(MCON, data); break; diff --git a/src/devices/cpu/mcs51/mcs51.h b/src/devices/cpu/mcs51/mcs51.h index 32925c23de8..4dd8fb125f5 100644 --- a/src/devices/cpu/mcs51/mcs51.h +++ b/src/devices/cpu/mcs51/mcs51.h @@ -44,8 +44,7 @@ enum { MCS51_INT0_LINE = 0, /* P3.2: External Interrupt 0 */ MCS51_INT1_LINE, /* P3.3: External Interrupt 1 */ - MCS51_RX_LINE, /* P3.0: Serial Port Receive Line */ - MCS51_T0_LINE, /* P3,4: Timer 0 External Input */ + MCS51_T0_LINE, /* P3.4: Timer 0 External Input */ MCS51_T1_LINE, /* P3.5: Timer 1 External Input */ MCS51_T2_LINE, /* P1.0: Timer 2 External Input */ MCS51_T2EX_LINE, /* P1.1: Timer 2 Capture Reload Trigger */ @@ -64,8 +63,6 @@ public: template auto port_in_cb() { return m_port_in_cb[N].bind(); } template auto port_out_cb() { return m_port_out_cb[N].bind(); } - auto serial_rx_cb() { return m_serial_rx_cb.bind(); } - auto serial_tx_cb() { return m_serial_tx_cb.bind(); } void program_internal(address_map &map); void data_internal(address_map &map); @@ -132,12 +129,14 @@ protected: struct mcs51_uart { uint8_t data_out; //Data to send out - uint8_t bits_to_send; //How many bits left to send when transmitting out the serial port + uint8_t data_in; + uint8_t txbit; + uint8_t rxbit; + bool rxb8; int smod_div; /* signal divided by 2^SMOD */ int rx_clk; /* rx clock */ int tx_clk; /* tx clock */ - uint8_t delay_cycles; //Gross Hack; } m_uart; /* internal uart */ /* Internal Ram */ @@ -148,6 +147,8 @@ protected: virtual void sfr_write(size_t offset, uint8_t data); virtual uint8_t sfr_read(size_t offset); + void transmit(bool state); + /* Memory spaces */ memory_access<16, 0, 0, ENDIANNESS_LITTLE>::cache m_program; memory_access< 9, 0, 0, ENDIANNESS_LITTLE>::specific m_data; @@ -156,10 +157,6 @@ protected: devcb_read8::array<4> m_port_in_cb; devcb_write8::array<4> m_port_out_cb; - /* Serial Port TX/RX Callbacks */ - devcb_write8 m_serial_tx_cb; //Call back function when sending data out of serial port - devcb_read8 m_serial_rx_cb; //Call back function to retrieve data when receiving serial port data - /* DS5002FP */ struct { uint8_t previous_ta; /* Previous Timed Access value */ @@ -197,9 +194,7 @@ protected: void update_timer_t1(int cycles); void update_timer_t2(int cycles); void update_timers(int cycles); - void serial_transmit(uint8_t data); - void serial_receive(); - void update_serial(int cycles); + void update_serial(int source); void update_irq_prio(uint8_t ipl, uint8_t iph); void execute_op(uint8_t op); void check_irqs(); diff --git a/src/devices/cpu/mcs51/mcs51ops.hxx b/src/devices/cpu/mcs51/mcs51ops.hxx index 99917328232..aed2fa897c8 100644 --- a/src/devices/cpu/mcs51/mcs51ops.hxx +++ b/src/devices/cpu/mcs51/mcs51ops.hxx @@ -978,5 +978,5 @@ OPHANDLER( xrl_a_r ) //illegal opcodes OPHANDLER( illegal ) { - LOG(("i8051 '%s': illegal opcode at 0x%03x: %02x\n", tag(), PC-1, r)); + LOG("illegal opcode at 0x%03x: %02x\n", PC-1, r); } diff --git a/src/devices/machine/archimedes_keyb.cpp b/src/devices/machine/archimedes_keyb.cpp index a6aa8278969..ff97b22bd58 100644 --- a/src/devices/machine/archimedes_keyb.cpp +++ b/src/devices/machine/archimedes_keyb.cpp @@ -232,7 +232,6 @@ ioport_constructor archimedes_keyboard_device::device_input_ports() const archimedes_keyboard_device::archimedes_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, ARCHIMEDES_KEYBOARD, tag, owner, clock) - , device_serial_interface(mconfig, *this) , m_mcu(*this, "mcu") , m_kout(*this) , m_keyboard(*this, "ROW.%u", 0U) @@ -250,10 +249,6 @@ void archimedes_keyboard_device::device_resolve_objects() void archimedes_keyboard_device::device_start() { - // KART interface - set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2); - set_rate(31250); - m_mouse_timer = timer_alloc(FUNC(archimedes_keyboard_device::update_mouse), this); save_item(NAME(m_mouse_x)); @@ -265,6 +260,7 @@ void archimedes_keyboard_device::device_start() save_item(NAME(m_mouse_yref)); save_item(NAME(m_mouse_ydir)); save_item(NAME(m_mux)); + save_item(NAME(m_kin)); } //------------------------------------------------- @@ -282,9 +278,7 @@ void archimedes_keyboard_device::device_reset() m_mouse_yref = 1; m_mouse_ydir = 1; m_mux = 0; - - transmit_register_reset(); - receive_register_reset(); + m_kin = false; m_mouse_timer->adjust(attotime::from_hz(1000 * 4), 0, attotime::from_hz(1000 * 4)); } @@ -299,11 +293,9 @@ void archimedes_keyboard_device::device_add_mconfig(machine_config &config) m_mcu->port_in_cb<0>().set([this]() { return m_keyboard[m_mux]->read() & 0xff; }); m_mcu->port_in_cb<1>().set([this]() { return (m_keyboard[m_mux]->read() >> 8) & 0xff; }); m_mcu->port_in_cb<2>().set(FUNC(archimedes_keyboard_device::mouse_r)); - m_mcu->port_in_cb<3>().set([this]() { return m_mouse[2]->read() & 0xff; }); + m_mcu->port_in_cb<3>().set([this]() { return (m_mouse[2]->read() & 0xfe) | m_kin; }); m_mcu->port_out_cb<2>().set([this](uint8_t data) { m_mux = data & 0x0f; }); m_mcu->port_out_cb<3>().set(FUNC(archimedes_keyboard_device::leds_w)); - m_mcu->serial_rx_cb().set([this]() { return get_received_char(); }); - m_mcu->serial_tx_cb().set(FUNC(archimedes_keyboard_device::tx_w)); } //------------------------------------------------- @@ -321,22 +313,6 @@ const tiny_rom_entry *archimedes_keyboard_device::device_rom_region() const return ROM_NAME( archimedes_keyboard ); } -void archimedes_keyboard_device::tra_complete() -{ -} - -void archimedes_keyboard_device::rcv_complete() -{ - receive_register_extract(); - m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); -} - -void archimedes_keyboard_device::tra_callback() -{ - m_kout(transmit_register_get_data_bit()); -} - TIMER_CALLBACK_MEMBER(archimedes_keyboard_device::update_mouse) { // Mouse quadrature signals @@ -418,10 +394,12 @@ TIMER_CALLBACK_MEMBER(archimedes_keyboard_device::update_mouse) void archimedes_keyboard_device::leds_w(uint8_t data) { // Keyboard LEDs + // --- --x- TXD // --- -x-- Caps Lock // --- x--- Scroll Lock // --x ---- Num Lock + m_kout(BIT(data, 1)); for (int i = 0; i < 3; i++) m_leds[i] = BIT(data, 2 + i); } @@ -431,8 +409,7 @@ uint8_t archimedes_keyboard_device::mouse_r() return (m_mouse_xref << 4) | (m_mouse_xdir << 5) | (m_mouse_yref << 6) | (m_mouse_ydir << 7); } -void archimedes_keyboard_device::tx_w(uint8_t data) +WRITE_LINE_MEMBER(archimedes_keyboard_device::kin_w) { - if (is_transmit_register_empty()) - transmit_register_setup(data); + m_kin = state; } diff --git a/src/devices/machine/archimedes_keyb.h b/src/devices/machine/archimedes_keyb.h index 7acf6ae8d59..2690f4bac71 100644 --- a/src/devices/machine/archimedes_keyb.h +++ b/src/devices/machine/archimedes_keyb.h @@ -13,15 +13,13 @@ #include "cpu/mcs51/mcs51.h" -#include "diserial.h" - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // ======================> archimedes_keyboard_device -class archimedes_keyboard_device : public device_t, public device_serial_interface +class archimedes_keyboard_device : public device_t { public: // construction/destruction @@ -29,7 +27,7 @@ public: auto kout() { return m_kout.bind(); } - DECLARE_WRITE_LINE_MEMBER(kin_w) { rx_w(state); } + DECLARE_WRITE_LINE_MEMBER(kin_w); protected: // device-level overrides @@ -42,15 +40,9 @@ protected: virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; - // device_serial_interface overrides - virtual void tra_callback() override; - virtual void tra_complete() override; - virtual void rcv_complete() override; - TIMER_CALLBACK_MEMBER(update_mouse); private: - void tx_w(uint8_t data); uint8_t mouse_r(); void leds_w(uint8_t data); @@ -70,6 +62,7 @@ private: int16_t m_mouse_x; int16_t m_mouse_y; uint8_t m_mux; + bool m_kin; }; diff --git a/src/devices/sound/qs1000.cpp b/src/devices/sound/qs1000.cpp index fb42e4936db..65c6e4cd24c 100644 --- a/src/devices/sound/qs1000.cpp +++ b/src/devices/sound/qs1000.cpp @@ -175,7 +175,6 @@ qs1000_device::qs1000_device(const machine_config &mconfig, const char *tag, dev m_out_p1_cb(*this), m_out_p2_cb(*this), m_out_p3_cb(*this), - //m_serial_w_cb(*this), m_stream(nullptr), m_cpu(*this, "cpu") { @@ -207,7 +206,6 @@ void qs1000_device::device_add_mconfig(machine_config &config) m_cpu->port_out_cb<2>().set(FUNC(qs1000_device::p2_w)); m_cpu->port_in_cb<3>().set(FUNC(qs1000_device::p3_r)); m_cpu->port_out_cb<3>().set(FUNC(qs1000_device::p3_w)); - m_cpu->serial_rx_cb().set(FUNC(qs1000_device::data_to_i8052)); } @@ -241,9 +239,6 @@ void qs1000_device::device_start() m_out_p2_cb.resolve_safe(); m_out_p3_cb.resolve_safe(); - //m_serial_w_cb.resolve_safe(); - - save_item(NAME(m_serial_data_in)); save_item(NAME(m_wave_regs)); for (int i = 0; i < QS1000_CHANNELS; i++) @@ -267,19 +262,6 @@ void qs1000_device::device_start() } -//------------------------------------------------- -// serial_in - send data to the chip -//------------------------------------------------- -void qs1000_device::serial_in(uint8_t data) -{ - m_serial_data_in = data; - - // Signal to the CPU that data is available - m_cpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_cpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); -} - - //------------------------------------------------- // set_irq - interrupt the internal CPU //------------------------------------------------- @@ -290,16 +272,6 @@ void qs1000_device::set_irq(int state) } -//------------------------------------------------- -// data_to_i8052 - called by the 8052 core to -// receive serial data -//------------------------------------------------- -uint8_t qs1000_device::data_to_i8052() -{ - return m_serial_data_in; -} - - //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- diff --git a/src/devices/sound/qs1000.h b/src/devices/sound/qs1000.h index 22683ff7d35..f921c2fd947 100644 --- a/src/devices/sound/qs1000.h +++ b/src/devices/sound/qs1000.h @@ -40,11 +40,9 @@ public: auto p1_out() { return m_out_p1_cb.bind(); } auto p2_out() { return m_out_p2_cb.bind(); } auto p3_out() { return m_out_p3_cb.bind(); } - //auto serial_w() { return m_serial_w_cb.bind(); } // external i8052_device &cpu() const { return *m_cpu; } - void serial_in(uint8_t data); void set_irq(int state); void wave_w(offs_t offset, uint8_t data); @@ -101,14 +99,11 @@ private: devcb_write8 m_out_p2_cb; devcb_write8 m_out_p3_cb; - //devcb_write8 m_serial_w_cb; - // Internal state sound_stream * m_stream; required_device m_cpu; // Wavetable engine - uint8_t m_serial_data_in; uint8_t m_wave_regs[18]; struct qs1000_channel @@ -129,8 +124,6 @@ private: }; qs1000_channel m_channels[QS1000_CHANNELS]; - - uint8_t data_to_i8052(); }; diff --git a/src/emu/diserial.cpp b/src/emu/diserial.cpp index 4e44a77d53d..b6ebb90b1c9 100644 --- a/src/emu/diserial.cpp +++ b/src/emu/diserial.cpp @@ -311,6 +311,7 @@ void device_serial_interface::receive_register_extract() data &= ~(0xff<>(m_tra_bit_count-1-m_tra_bit_count_transmitted))&1; if (m_tra_bit_count_transmitted < m_df_start_bit_count) - LOGMASKED(LOG_TX, "Transmitting start bit as %d (%s)\n", m_tra_bit_count_transmitted, bit, device().machine().time().to_string()); + LOGMASKED(LOG_TX, "Transmitting start bit %d as %d (%s)\n", m_tra_bit_count_transmitted, bit, device().machine().time().to_string()); else LOGMASKED(LOG_TX, "Transmitting bit %d as %d (%s)\n", m_tra_bit_count_transmitted - m_df_start_bit_count, bit, device().machine().time().to_string()); m_tra_bit_count_transmitted++; diff --git a/src/mame/acorn/ssfindo.cpp b/src/mame/acorn/ssfindo.cpp index b61234bbd5d..486c311f1ab 100644 --- a/src/mame/acorn/ssfindo.cpp +++ b/src/mame/acorn/ssfindo.cpp @@ -133,6 +133,7 @@ Notes: #include "machine/arm_iomd.h" #include "machine/i2cmem.h" #include "sound/qs1000.h" +#include "diserial.h" #include "emupal.h" #include "screen.h" #include "speaker.h" @@ -140,11 +141,12 @@ Notes: namespace { -class ssfindo_state : public driver_device +class ssfindo_state : public driver_device, public device_serial_interface { public: ssfindo_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) + , device_serial_interface(mconfig, *this) , m_maincpu(*this, "maincpu") , m_vidc(*this, "vidc") , m_iomd(*this, "iomd") @@ -178,6 +180,7 @@ protected: bool m_i2cmem_clock = false; + virtual void tra_callback() override; void sound_w(uint8_t data); private: @@ -209,6 +212,8 @@ private: uint8_t iolines_r(); void iolines_w(uint8_t data); bool m_flash_bank_select = false; + + bool m_txd = true; }; class tetfight_state : public ssfindo_state @@ -371,7 +376,7 @@ uint32_t ssfindo_state::randomized_r() void ssfindo_state::sound_w(uint8_t data) { - m_qs1000->serial_in(data); + transmit_register_setup(data); m_maincpu->spin_until_time(attotime::from_usec(2000)); // give time to the QS1000 CPU to react. TODO: sync things correctly } @@ -441,11 +446,23 @@ void ssfindo_state::machine_start() save_item(NAME(m_flashN)); save_item(NAME(m_i2cmem_clock)); save_item(NAME(m_flash_bank_select)); + + set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); + set_rate(31250); } void ssfindo_state::machine_reset() { // ... + receive_register_reset(); + transmit_register_reset(); + + m_txd = true; +} + +void ssfindo_state::tra_callback() +{ + m_txd = transmit_register_get_data_bit(); } static INPUT_PORTS_START( ssfindo ) @@ -616,6 +633,7 @@ void ssfindo_state::ssfindo(machine_config &config) qs1000_device &qs1000(QS1000(config, "qs1000", 24_MHz_XTAL)); qs1000.set_external_rom(true); // qs1000.p1_out().set(FUNC()); // TODO: writes something here + qs1000.p3_in().set([this]() { return u8(0xfeU | m_txd); }); qs1000.add_route(0, "lspeaker", 0.25); qs1000.add_route(1, "rspeaker", 0.25); } diff --git a/src/mame/eolith/eolith.cpp b/src/mame/eolith/eolith.cpp index b2fc413b998..7e23a3251ab 100644 --- a/src/mame/eolith/eolith.cpp +++ b/src/mame/eolith/eolith.cpp @@ -153,9 +153,10 @@ private: void eolith_vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); uint16_t eolith_vram_r(offs_t offset); void sound_p1_w(uint8_t data); + void sound_p3_w(uint8_t data); uint8_t qs1000_p1_r(); void qs1000_p1_w(uint8_t data); - void soundcpu_to_qs1000(uint8_t data); + uint8_t qs1000_p3_r(); uint32_t screen_update_eolith(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -176,6 +177,7 @@ private: int m_coin_counter_bit = 0; std::unique_ptr m_vram; int m_buffer = 0; + uint8_t m_sound_txd = 0; }; @@ -315,6 +317,11 @@ void eolith_state::sound_p1_w(uint8_t data) m_sndbank->set_entry(data & 0x0f); } +void eolith_state::sound_p3_w(uint8_t data) +{ + // Sound CPU -> QS1000 CPU serial link + m_sound_txd = BIT(data, 1); +} /************************************* * @@ -352,10 +359,9 @@ void eolith_state::qs1000_p1_w(uint8_t data) * *************************************/ -void eolith_state::soundcpu_to_qs1000(uint8_t data) +uint8_t eolith_state::qs1000_p3_r() { - m_qs1000->serial_in(data); - machine().scheduler().perfect_quantum(attotime::from_usec(250)); + return m_sound_txd; } @@ -693,7 +699,8 @@ void eolith_state::eolith45(machine_config &config) m_soundcpu->set_addrmap(AS_PROGRAM, &eolith_state::sound_prg_map); m_soundcpu->set_addrmap(AS_IO, &eolith_state::sound_io_map); m_soundcpu->port_out_cb<1>().set(FUNC(eolith_state::sound_p1_w)); - m_soundcpu->serial_tx_cb().set(FUNC(eolith_state::soundcpu_to_qs1000)); // Sound CPU -> QS1000 CPU serial link + m_soundcpu->port_out_cb<3>().set(FUNC(eolith_state::sound_p3_w)); + config.set_perfect_quantum(m_soundcpu); // HACK: ensure serial sync between Sound CPU and QS1000 EEPROM_93C66_8BIT(config, "eeprom") .erase_time(attotime::from_usec(250)) @@ -724,6 +731,7 @@ void eolith_state::eolith45(machine_config &config) m_qs1000->set_external_rom(true); m_qs1000->p1_in().set(FUNC(eolith_state::qs1000_p1_r)); m_qs1000->p1_out().set(FUNC(eolith_state::qs1000_p1_w)); + m_qs1000->p3_in().set(FUNC(eolith_state::qs1000_p3_r)); m_qs1000->add_route(0, "lspeaker", 1.0); m_qs1000->add_route(1, "rspeaker", 1.0); } diff --git a/src/mame/ibm/rtpc.cpp b/src/mame/ibm/rtpc.cpp index 458cdc7222e..bf215eb0c77 100644 --- a/src/mame/ibm/rtpc.cpp +++ b/src/mame/ibm/rtpc.cpp @@ -200,7 +200,6 @@ protected: u8 m_mcu_p1; u8 m_mcu_p2; u8 m_mcu_p3; - u8 m_mcu_uart; u8 m_ppi_pa; u8 m_ppi_pb; @@ -223,7 +222,6 @@ void rtpc_state::machine_start() m_mcu_p1 = 0; m_mcu_p2 = 0; m_mcu_p3 = 0; - m_mcu_uart = 0; m_ppi_pa = 0; m_ppi_pb = 0; @@ -375,6 +373,15 @@ void rtpc_state::mcu_port3_w(u8 data) // 6 o kbd data out // 7 o kbd clock out + // uart txd -> rxd wrap + if (BIT(m_kls_cmd, 5)) + { + if (BIT(data, 1)) + m_mcu_p3 |= 1; + else + m_mcu_p3 &= ~1; + } + m_kbd_con->data_write_from_mb(BIT(data, 6)); m_kbd_con->clock_write_from_mb(BIT(data, 7)); @@ -578,18 +585,6 @@ void rtpc_state::common(machine_config &config) m_mcu->port_out_cb<2>().set(FUNC(rtpc_state::mcu_port2_w)); m_mcu->port_in_cb<3>().set([this]() { return m_mcu_p3 | 0xce; }); m_mcu->port_out_cb<3>().set(FUNC(rtpc_state::mcu_port3_w)); - m_mcu->serial_tx_cb().set( - [this](u8 data) - { - if (BIT(m_kls_cmd, 5)) - { - m_mcu_uart = data; - m_mcu->set_input_line(MCS51_RX_LINE, 1); - } - else - LOGMASKED(LOG_KLS, "kls uart tx 0x%02x\n", data); - }); - m_mcu->serial_rx_cb().set([this]() { return m_mcu_uart; }); TIMER(config, "mcu_timer").configure_periodic(FUNC(rtpc_state::mcu_timer), attotime::from_hz(32768)); diff --git a/src/mame/intel/basic52.cpp b/src/mame/intel/basic52.cpp index f7409575321..d90ae5f2a66 100644 --- a/src/mame/intel/basic52.cpp +++ b/src/mame/intel/basic52.cpp @@ -14,17 +14,6 @@ BASIC-31 (and variants) as found on the below url, are homebrews. https://web.archive.org/web/20110908004037/http://dsaprojects.110mb.com/electronics/8031-ah/8031-bas.html - -The driver is working, however there are issues with the cpu serial code. -When started, you are supposed to press Space and the system works out -the baud rate and boots up. - -However, the way the cpu is written, it actually passes bytes around, so -the auto-speed detection doesn't work as intended. Also the cpu interface -is horribly outdated and needs to be brought up to date. - -The optional eprom presents the ability to bypass the auto-speed problems. - Once the system starts, all input must be in uppercase. Read the manual to discover the special features of this Basic. @@ -36,7 +25,8 @@ Sound: BASIC-31 has sound, and BASIC-52 doesn't. The sound command is PWM. #include "emu.h" #include "cpu/mcs51/mcs51.h" #include "machine/i8255.h" -#include "machine/terminal.h" +#include "bus/rs232/terminal.h" +#include "bus/rs232/rs232.h" #include "sound/spkrdev.h" #include "speaker.h" @@ -49,7 +39,7 @@ public: basic52_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_terminal(*this, "terminal") + , m_serial(*this, "serial") , m_speaker(*this, "speaker") { } @@ -58,15 +48,15 @@ public: private: void machine_start() override; - void kbd_put(u8 data); void port1_w(u8 data); - uint8_t unk_r(); - uint8_t from_term(); + uint8_t port3_r(); + void port3_w(u8 data); + void rx_w(int state); void io_map(address_map &map); void mem_map(address_map &map); - uint8_t m_term_data = 0U; + uint8_t m_port3 = 0U; required_device m_maincpu; - required_device m_terminal; + required_device m_serial; required_device m_speaker; }; @@ -82,9 +72,6 @@ void basic52_state::io_map(address_map &map) map.unmap_value_high(); map(0x0000, 0x7fff).ram(); // 8000-9FFF is reserved for a plug-in EPROM containing BASIC programs. - // We have used this to preset the baud rate and skip the unreliable auto-detect. - map(0x8000, 0x8000).lr8(NAME([] () { return 0x31; })); // we will be manually setting the baud rate - map(0x8001, 0x8002).lr8(NAME([] () { return 0xFE; })); // to the fastest possible map(0xa000, 0xa003).rw("ppi8255", FUNC(i8255_device::read), FUNC(i8255_device::write)); // PPI-8255 } @@ -93,14 +80,9 @@ static INPUT_PORTS_START( basic52 ) INPUT_PORTS_END -uint8_t basic52_state::from_term() -{ - return m_term_data; -} - -uint8_t basic52_state::unk_r() +uint8_t basic52_state::port3_r() { - return m_term_data; // won't boot without this + return m_port3; } void basic52_state::port1_w(u8 data) @@ -108,17 +90,30 @@ void basic52_state::port1_w(u8 data) m_speaker->level_w(BIT(data, 2)); } +void basic52_state::port3_w(u8 data) +{ + // preserve RXD + m_port3 = (m_port3 & 1) | (data & ~1); + + m_serial->write_txd(BIT(data, 1)); +} -void basic52_state::kbd_put(u8 data) +void basic52_state::rx_w(int state) { - m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); - m_term_data = data; + if (state) + m_port3 |= 1; + else + m_port3 &= ~1; } void basic52_state::machine_start() { - save_item(NAME(m_term_data)); + save_item(NAME(m_port3)); +} + +static void serial_devices(device_slot_interface &device) +{ + device.option_add("terminal", SERIAL_TERMINAL); } void basic52_state::basic31(machine_config &config) @@ -128,13 +123,11 @@ void basic52_state::basic31(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &basic52_state::mem_map); m_maincpu->set_addrmap(AS_IO, &basic52_state::io_map); m_maincpu->port_out_cb<1>().set(FUNC(basic52_state::port1_w)); - m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::unk_r)); - m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write)); - m_maincpu->serial_rx_cb().set(FUNC(basic52_state::from_term)); + m_maincpu->port_out_cb<3>().set(FUNC(basic52_state::port3_w)); + m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::port3_r)); - /* video hardware */ - GENERIC_TERMINAL(config, m_terminal, 0); - m_terminal->set_keyboard_callback(FUNC(basic52_state::kbd_put)); + RS232_PORT(config, m_serial, serial_devices, "terminal"); + m_serial->rxd_handler().set(FUNC(basic52_state::rx_w)); I8255(config, "ppi8255", 0); @@ -150,9 +143,8 @@ void basic52_state::basic52(machine_config &config) I8052(config.replace(), m_maincpu, XTAL(11'059'200)); m_maincpu->set_addrmap(AS_PROGRAM, &basic52_state::mem_map); m_maincpu->set_addrmap(AS_IO, &basic52_state::io_map); - m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::unk_r)); - m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write)); - m_maincpu->serial_rx_cb().set(FUNC(basic52_state::from_term)); + m_maincpu->port_out_cb<3>().set(FUNC(basic52_state::port3_w)); + m_maincpu->port_in_cb<3>().set(FUNC(basic52_state::port3_r)); } /* ROM definition */ diff --git a/src/mame/leapfrog/iquest.cpp b/src/mame/leapfrog/iquest.cpp index b61b102d008..d3a620cd4e2 100644 --- a/src/mame/leapfrog/iquest.cpp +++ b/src/mame/leapfrog/iquest.cpp @@ -117,10 +117,6 @@ private: void unk_ffa9_w(uint8_t data); - void tx(uint8_t data); - uint8_t rx(); - - uint8_t port0_r(); void port0_w(u8 data); uint8_t port1_r(); @@ -520,28 +516,9 @@ uint32_t leapfrog_iquest_state::screen_update(screen_device &screen, bitmap_rgb3 return 0; } -// never triggered? -void leapfrog_iquest_state::tx(uint8_t data) -{ - logerror("%s: transmitting %02x\n", machine().describe_context().c_str(), data); -} - -// never triggered? -uint8_t leapfrog_iquest_state::rx() -{ - logerror("%s: receiving\n", machine().describe_context().c_str()); - return machine().rand(); -} - - // doesn't help? WRITE_LINE_MEMBER(leapfrog_iquest_state::rx_line_hack) { - /* - m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); - */ - if (0) { // HACK: force past the wait loop if we're treating ff80 - ffff as RAM @@ -605,8 +582,6 @@ void leapfrog_iquest_state::leapfrog_base(machine_config &config) I8032(config, m_maincpu, 96000000/10); // unknown clock m_maincpu->set_addrmap(AS_PROGRAM, &leapfrog_iquest_state::prog_map); m_maincpu->set_addrmap(AS_IO, &leapfrog_iquest_state::ext_map); - m_maincpu->serial_tx_cb().set(FUNC(leapfrog_iquest_state::tx)); - m_maincpu->serial_rx_cb().set(FUNC(leapfrog_iquest_state::rx)); m_maincpu->port_in_cb<0>().set(FUNC(leapfrog_iquest_state::port0_r)); m_maincpu->port_out_cb<0>().set(FUNC(leapfrog_iquest_state::port0_w)); m_maincpu->port_in_cb<1>().set(FUNC(leapfrog_iquest_state::port1_r)); diff --git a/src/mame/maygay/maygayv1.cpp b/src/mame/maygay/maygayv1.cpp index 95240f3bd6b..61243e8ff45 100644 --- a/src/mame/maygay/maygayv1.cpp +++ b/src/mame/maygay/maygayv1.cpp @@ -234,8 +234,6 @@ private: void write_odd(uint16_t data); uint16_t read_odd(); void vsync_int_ctrl(uint16_t data); - uint8_t mcu_r(offs_t offset); - void mcu_w(offs_t offset, uint8_t data); uint8_t b_read(); void b_writ(uint8_t data); void strobe_w(uint8_t data); @@ -243,14 +241,13 @@ private: uint8_t kbd_r(); uint32_t screen_update_maygayv1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); DECLARE_WRITE_LINE_MEMBER(screen_vblank_maygayv1); - void data_from_i8031(uint8_t data); - uint8_t data_to_i8031(); + uint8_t sound_p1_r(); + void sound_p1_w(uint8_t data); + uint8_t sound_p3_r(); + void sound_p3_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER(duart_irq_handler); DECLARE_WRITE_LINE_MEMBER(duart_txa); void main_map(address_map &map); - void sound_data(address_map &map); - void sound_io(address_map &map); - void sound_prg(address_map &map); void cpu_space_map(address_map &map); required_device m_maincpu; @@ -273,7 +270,6 @@ private: int m_vsync_latch_preset = 0; uint8_t m_p1 = 0; uint8_t m_p3 = 0; - int m_d68681_val = 0; i82716_t m_i82716; output_finder<8 * 256> m_lamp; }; @@ -616,59 +612,34 @@ void maygayv1_state::main_map(address_map &map) */ -uint8_t maygayv1_state::mcu_r(offs_t offset) +uint8_t maygayv1_state::sound_p1_r() { - switch (offset) - { - case 1: - { - if ( !BIT(m_p3, 4) ) - return (ioport("REEL")->read()); // Reels??? - else - return 0; - } - - case 3: return m_upd7759->busy_r() ? 0 : 0x08; - } - return 0; + if (!BIT(m_p3, 4)) + return (ioport("REEL")->read()); // Reels??? + else + return m_p1; } -void maygayv1_state::mcu_w(offs_t offset, uint8_t data) +void maygayv1_state::sound_p1_w(uint8_t data) { - logerror("O %x D %x",offset,data); + m_p1 = data; - switch (offset) - { - // Bottom nibble = UPD - case 1: - m_p1 = data; -// m_upd7759->msg_w(data);//? - break; - case 3: - m_upd7759->reset_w (BIT(data, 2)); - m_upd7759->start_w(BIT(data, 6)); - -// if ( !BIT(m_p3, 7) && BIT(data, 7) ) - // P1 propagates to outputs - - m_p3 = data; - break; - } + m_upd7759->port_w(data);//? } - -void maygayv1_state::sound_prg(address_map &map) +uint8_t maygayv1_state::sound_p3_r() { - map(0x0000, 0xffff).rom(); + return m_upd7759->busy_r() ? m_p3 : (m_p3 | 0x08); } -void maygayv1_state::sound_data(address_map &map) +void maygayv1_state::sound_p3_w(uint8_t data) { -} + // preserve RXD + m_p3 = (m_p3 & 1) | (m_p3 & ~1); -void maygayv1_state::sound_io(address_map &map) -{ - map(0x00, 0xff).rw(FUNC(maygayv1_state::mcu_r), FUNC(maygayv1_state::mcu_w)); + m_duart68681->rx_a_w(BIT(data, 1)); + m_upd7759->reset_w(BIT(data, 2)); + m_upd7759->start_w(BIT(data, 6)); } @@ -835,18 +806,10 @@ WRITE_LINE_MEMBER(maygayv1_state::duart_irq_handler) WRITE_LINE_MEMBER(maygayv1_state::duart_txa) { - m_d68681_val = state; - m_soundcpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); // ? -} - -uint8_t maygayv1_state::data_to_i8031() -{ - return m_d68681_val; -} - -void maygayv1_state::data_from_i8031(uint8_t data) -{ - m_duart68681->rx_a_w(data); + if (state) + m_p3 |= 1; + else + m_p3 &= ~1; } uint8_t maygayv1_state::b_read() @@ -886,11 +849,10 @@ void maygayv1_state::maygayv1(machine_config &config) m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &maygayv1_state::cpu_space_map); I8052(config, m_soundcpu, SOUND_CLOCK); - m_soundcpu->set_addrmap(AS_PROGRAM, &maygayv1_state::sound_prg); - m_soundcpu->set_addrmap(AS_DATA, &maygayv1_state::sound_data); - m_soundcpu->set_addrmap(AS_IO, &maygayv1_state::sound_io); - m_soundcpu->serial_tx_cb().set(FUNC(maygayv1_state::data_from_i8031)); - m_soundcpu->serial_rx_cb().set(FUNC(maygayv1_state::data_to_i8031)); + m_soundcpu->port_in_cb<1>().set(FUNC(maygayv1_state::sound_p1_r)); + m_soundcpu->port_out_cb<1>().set(FUNC(maygayv1_state::sound_p1_w)); + m_soundcpu->port_in_cb<3>().set(FUNC(maygayv1_state::sound_p3_r)); + m_soundcpu->port_out_cb<3>().set(FUNC(maygayv1_state::sound_p3_w)); /* U25 ST 2 9148 EF68B21P */ pia6821_device &pia(PIA6821(config, "pia", 0)); diff --git a/src/mame/misc/micro3d.cpp b/src/mame/misc/micro3d.cpp index 1867e3aa483..99b13509947 100644 --- a/src/mame/misc/micro3d.cpp +++ b/src/mame/misc/micro3d.cpp @@ -334,8 +334,6 @@ void micro3d_state::micro3d(machine_config &config) m_audiocpu->port_out_cb<1>().set(FUNC(micro3d_state::micro3d_sound_p1_w)); m_audiocpu->port_in_cb<3>().set(FUNC(micro3d_state::micro3d_sound_p3_r)); m_audiocpu->port_out_cb<3>().set(FUNC(micro3d_state::micro3d_sound_p3_w)); - m_audiocpu->serial_tx_cb().set(FUNC(micro3d_state::data_from_i8031)); - m_audiocpu->serial_rx_cb().set(FUNC(micro3d_state::data_to_i8031)); MC68681(config, m_duart, 3.6864_MHz_XTAL); m_duart->irq_cb().set(FUNC(micro3d_state::duart_irq_handler)); diff --git a/src/mame/misc/micro3d.h b/src/mame/misc/micro3d.h index eb3d005069b..ff86d2f0592 100644 --- a/src/mame/misc/micro3d.h +++ b/src/mame/misc/micro3d.h @@ -177,8 +177,6 @@ private: INTERRUPT_GEN_MEMBER(micro3d_vblank); TIMER_CALLBACK_MEMBER(mac_done_callback); void micro3d_upd7759_w(uint8_t data); - void data_from_i8031(uint8_t data); - uint8_t data_to_i8031(); DECLARE_WRITE_LINE_MEMBER(duart_irq_handler); uint8_t duart_input_r(); void duart_output_w(uint8_t data); diff --git a/src/mame/misc/micro3d_m.cpp b/src/mame/misc/micro3d_m.cpp index ba8d9a57736..b25c23252a7 100644 --- a/src/mame/misc/micro3d_m.cpp +++ b/src/mame/misc/micro3d_m.cpp @@ -39,20 +39,10 @@ WRITE_LINE_MEMBER(micro3d_state::duart_irq_handler) WRITE_LINE_MEMBER(micro3d_state::duart_txb) { - m_m68681_tx0 = state; - m_audiocpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - // TODO: next line should be behind a timer callback which lasts one audiocpu clock cycle - m_audiocpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); -} - -uint8_t micro3d_state::data_to_i8031() -{ - return m_m68681_tx0; -} - -void micro3d_state::data_from_i8031(uint8_t data) -{ - m_duart->rx_b_w(data); + if (state) + m_sound_port_latch[3] |= 1; + else + m_sound_port_latch[3] &= ~1; } /* @@ -463,8 +453,10 @@ void micro3d_state::micro3d_sound_p1_w(uint8_t data) void micro3d_state::micro3d_sound_p3_w(uint8_t data) { - m_sound_port_latch[3] = data; + // preserve RXD input + m_sound_port_latch[3] = (m_sound_port_latch[3] & 1) | (data & ~1); + m_duart->rx_b_w(BIT(data, 1)); m_upd7759->set_rom_bank(BIT(data, 2)); m_upd7759->reset_w(!BIT(data, 4)); } diff --git a/src/mame/misc/piggypas.cpp b/src/mame/misc/piggypas.cpp index 989ecbbefa6..587c553ee94 100644 --- a/src/mame/misc/piggypas.cpp +++ b/src/mame/misc/piggypas.cpp @@ -45,7 +45,7 @@ private: virtual void machine_start() override; virtual void machine_reset() override; void ctrl_w(uint8_t data); - void mcs51_tx_callback(uint8_t data); + void port3_w(uint8_t data); void led_strobe_w(uint8_t data); void lcd_latch_w(uint8_t data); void lcd_control_w(uint8_t data); @@ -71,6 +71,8 @@ void piggypas_state::output_digits() m_digits[1] = bitswap<8>((m_digit_latch >> 8) & 0xff, 7,6,4,3,2,1,0,5) & 0x7f; m_digits[2] = bitswap<8>((m_digit_latch >> 16) & 0xff, 7,6,4,3,2,1,0,5) & 0x7f; m_digits[3] = bitswap<8>((m_digit_latch >> 24) & 0xff, 7,6,4,3,2,1,0,5) & 0x7f; + + m_digit_latch = 0; } void piggypas_state::ctrl_w(uint8_t data) @@ -83,9 +85,15 @@ void piggypas_state::ctrl_w(uint8_t data) m_ctrl = data; } -void piggypas_state::mcs51_tx_callback(uint8_t data) +void piggypas_state::port3_w(uint8_t data) { - m_digit_latch = (m_digit_latch >> 8) | (u32(data) << 24); + if (!BIT(data, 1)) + { + m_digit_latch >>= 1; + + if (BIT(data, 0)) + m_digit_latch |= (1U << 31); + } } void piggypas_state::led_strobe_w(uint8_t data) @@ -197,7 +205,7 @@ void piggypas_state::piggypas(machine_config &config) m_maincpu->set_addrmap(AS_IO, &piggypas_state::piggypas_io); m_maincpu->port_out_cb<1>().set(FUNC(piggypas_state::led_strobe_w)); m_maincpu->port_in_cb<3>().set_ioport("IN2"); - m_maincpu->serial_tx_cb().set(FUNC(piggypas_state::mcs51_tx_callback)); + m_maincpu->port_out_cb<3>().set(FUNC(piggypas_state::port3_w)); // m_maincpu->set_vblank_int("screen", FUNC(piggypas_state::irq0_line_hold)); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // DS1220AD @@ -235,7 +243,6 @@ void piggypas_state::fidlstix(machine_config &config) piggypas(config); m_maincpu->set_addrmap(AS_IO, &piggypas_state::fidlstix_io); - m_maincpu->serial_tx_cb().set_nop(); m_maincpu->port_in_cb<1>().set(m_hd44780, FUNC(hd44780_device::db_r)); m_maincpu->port_out_cb<1>().set(FUNC(piggypas_state::lcd_latch_w)); m_maincpu->port_out_cb<3>().set(FUNC(piggypas_state::lcd_control_w)); diff --git a/src/mame/philips/cdi.cpp b/src/mame/philips/cdi.cpp index 6eeff63bed9..a7264fe7432 100644 --- a/src/mame/philips/cdi.cpp +++ b/src/mame/philips/cdi.cpp @@ -195,21 +195,21 @@ void cdi_state::machine_reset() void quizard_state::machine_start() { - save_item(NAME(m_mcu_rx_from_cpu)); - save_item(NAME(m_mcu_initial_byte)); save_item(NAME(m_boot_press)); m_boot_timer = timer_alloc(FUNC(quizard_state::boot_press_tick), this); + + set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); + set_rate(9600); } void quizard_state::machine_reset() { cdi_state::machine_reset(); - m_mcu_rx_from_cpu = 0x00; - m_mcu_initial_byte = true; m_boot_press = false; m_boot_timer->adjust(attotime::from_seconds(13), 1); + m_mcu_p3 = 0x04; } @@ -288,16 +288,8 @@ void quizard_state::mcu_rtsn_from_cpu(int state) void quizard_state::mcu_rx_from_cpu(uint8_t data) { LOGMASKED(LOG_UART, "MCU receiving %02x from CPU\n", data); - if (m_mcu_initial_byte) - { - m_mcu_initial_byte = false; - return; - } - m_mcu_rx_from_cpu = data; - - m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); + transmit_register_setup(data); } uint8_t quizard_state::mcu_p0_r() @@ -325,8 +317,8 @@ uint8_t quizard_state::mcu_p2_r() uint8_t quizard_state::mcu_p3_r() { - LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 3 Read (%02x)\n", machine().describe_context(), 0x04); - return 0x04; + LOGMASKED(LOG_QUIZARD_READS, "%s: MCU Port 3 Read (%02x)\n", machine().describe_context(), m_mcu_p3); + return m_mcu_p3; } void quizard_state::mcu_p0_w(uint8_t data) @@ -347,22 +339,10 @@ void quizard_state::mcu_p2_w(uint8_t data) void quizard_state::mcu_p3_w(uint8_t data) { LOGMASKED(LOG_QUIZARD_WRITES, "%s: MCU Port 3 Write (%02x)\n", machine().describe_context(), data); + rx_w(BIT(data, 1)); m_maincpu->uart_ctsn(BIT(data, 6)); } -void quizard_state::mcu_tx(uint8_t data) -{ - LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU transmitting %02x\n", machine().describe_context(), data); - m_maincpu->uart_rx(data); -} - -uint8_t quizard_state::mcu_rx() -{ - uint8_t data = m_mcu_rx_from_cpu; - LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU receiving %02x\n", machine().describe_context(), data); - return data; -} - /************************* * DVC cartridge * *************************/ @@ -601,7 +581,7 @@ void quizard_state::quizard(machine_config &config) m_maincpu->uart_rtsn_callback().set(FUNC(quizard_state::mcu_rtsn_from_cpu)); m_maincpu->uart_tx_callback().set(FUNC(quizard_state::mcu_rx_from_cpu)); - I8751(config, m_mcu, 8000000); + I8751(config, m_mcu, 11.0592_MHz_XTAL); m_mcu->port_in_cb<0>().set(FUNC(quizard_state::mcu_p0_r)); m_mcu->port_in_cb<1>().set(FUNC(quizard_state::mcu_p1_r)); m_mcu->port_in_cb<2>().set(FUNC(quizard_state::mcu_p2_r)); @@ -610,12 +590,27 @@ void quizard_state::quizard(machine_config &config) m_mcu->port_out_cb<1>().set(FUNC(quizard_state::mcu_p1_w)); m_mcu->port_out_cb<2>().set(FUNC(quizard_state::mcu_p2_w)); m_mcu->port_out_cb<3>().set(FUNC(quizard_state::mcu_p3_w)); - m_mcu->serial_tx_cb().set(FUNC(quizard_state::mcu_tx)); - m_mcu->serial_rx_cb().set(FUNC(quizard_state::mcu_rx)); m_slave_hle->read_mousebtn().set(FUNC(quizard_state::mcu_button_press)); } +void quizard_state::tra_callback() +{ + if (transmit_register_get_data_bit()) + m_mcu_p3 |= 1; + else + m_mcu_p3 &= ~1; +} + +void quizard_state::rcv_complete() +{ + receive_register_extract(); + + const uint8_t data = get_received_char(); + LOGMASKED(LOG_QUIZARD_OTHER, "%s: MCU transmitting %02x\n", machine().describe_context(), data); + m_maincpu->uart_rx(data); +} + /************************* * Rom Load * *************************/ diff --git a/src/mame/philips/cdi.h b/src/mame/philips/cdi.h index 83fca558144..f52a189f8fa 100644 --- a/src/mame/philips/cdi.h +++ b/src/mame/philips/cdi.h @@ -11,6 +11,7 @@ #include "mcd212.h" #include "cpu/mcs51/mcs51.h" #include "cpu/m6805/m68hc05.h" +#include "diserial.h" #include "screen.h" /*----------- driver state -----------*/ @@ -81,11 +82,12 @@ private: required_device_array m_dmadac; }; -class quizard_state : public cdi_state +class quizard_state : public cdi_state, public device_serial_interface { public: quizard_state(const machine_config &mconfig, device_type type, const char *tag) : cdi_state(mconfig, type, tag) + , device_serial_interface(mconfig, *this) , m_mcu(*this, "mcu") , m_inputs(*this, "P%u", 0U) { } @@ -96,6 +98,9 @@ private: virtual void machine_start() override; virtual void machine_reset() override; + virtual void tra_callback() override; + virtual void rcv_complete() override; + TIMER_CALLBACK_MEMBER(boot_press_tick); uint8_t mcu_p0_r(); @@ -106,8 +111,6 @@ private: void mcu_p1_w(uint8_t data); void mcu_p2_w(uint8_t data); void mcu_p3_w(uint8_t data); - void mcu_tx(uint8_t data); - uint8_t mcu_rx(); void mcu_rx_from_cpu(uint8_t data); void mcu_rtsn_from_cpu(int state); @@ -117,10 +120,9 @@ private: required_device m_mcu; required_ioport_array<3> m_inputs; - uint8_t m_mcu_rx_from_cpu = 0U; - bool m_mcu_initial_byte = false; bool m_boot_press = false; emu_timer *m_boot_timer = nullptr; + uint8_t m_mcu_p3 = 0x04; }; // Quizard 2 language values: diff --git a/src/mame/philips/minitel_2_rpic.cpp b/src/mame/philips/minitel_2_rpic.cpp index e58059cfa3d..db712aca376 100644 --- a/src/mame/philips/minitel_2_rpic.cpp +++ b/src/mame/philips/minitel_2_rpic.cpp @@ -156,6 +156,8 @@ private: uint8_t port1_r(); uint8_t port3_r(); + void serial_rxd(int state); + void dev_ctrl_reg_w(offs_t offset, uint8_t data); uint8_t dev_keyb_ser_r(offs_t offset); @@ -243,9 +245,16 @@ void minitel_state::port3_w(uint8_t data) m_serport->write_txd( !!(data & PORT_3_SER_TXD) ); - port3 = data; + port3 = (port3 & PORT_3_SER_RXD) | (data & ~PORT_3_SER_RXD); } +void minitel_state::serial_rxd(int state) +{ + if (state) + port3 |= PORT_3_SER_RXD; + else + port3 &= ~PORT_3_SER_RXD; +} void minitel_state::update_modem_state() @@ -532,7 +541,7 @@ void minitel_state::minitel2(machine_config &config) m_modem->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(m_modem)); RS232_PORT(config, m_serport, default_rs232_devices, nullptr); - m_serport->rxd_handler().set_inputline(m_maincpu, MCS51_RX_LINE); + m_serport->rxd_handler().set(FUNC(minitel_state::serial_rxd)); m_serport->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(m_serport)); lineconnected = 0; diff --git a/src/mame/pinball/mephistp.cpp b/src/mame/pinball/mephistp.cpp index 68041ae03d4..49f51c907a5 100644 --- a/src/mame/pinball/mephistp.cpp +++ b/src/mame/pinball/mephistp.cpp @@ -235,7 +235,6 @@ void mephisto_state::mephisto(machine_config &config) soundcpu.port_in_cb<1>().set(FUNC(mephisto_state::ay8910_read)); soundcpu.port_out_cb<1>().set(FUNC(mephisto_state::ay8910_write)); soundcpu.port_out_cb<3>().set(FUNC(mephisto_state::t0_t1_w)); - soundcpu.serial_rx_cb().set_constant(0); // from MUART /* Sound */ genpin_audio(config); diff --git a/src/mame/siemens/pcd.h b/src/mame/siemens/pcd.h index ed10e17cace..acae456094e 100644 --- a/src/mame/siemens/pcd.h +++ b/src/mame/siemens/pcd.h @@ -10,8 +10,6 @@ #include "video/scn2674.h" #include "emupal.h" -#include "diserial.h" - class pcdx_video_device : public device_t, public device_gfx_interface { @@ -78,12 +76,12 @@ private: SCN2674_DRAW_CHARACTER_MEMBER(display_pixels); }; -class pcx_video_device : public pcdx_video_device, - public device_serial_interface +class pcx_video_device : public pcdx_video_device { public: pcx_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); auto txd_handler() { return m_txd_handler.bind(); } + void rx_w(int state); virtual void map(address_map &map) override; uint8_t term_r(offs_t offset); @@ -103,18 +101,15 @@ protected: virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; - void tra_callback() override; - void rcv_complete() override; - private: required_device m_crtc; required_region_ptr m_charrom; devcb_write_line m_txd_handler; - uint8_t m_term_key, m_term_char, m_term_stat, m_p1; + uint8_t m_term_key, m_term_char, m_term_stat, m_p1, m_p3; - uint8_t rx_callback(); - void tx_callback(uint8_t data); + uint8_t p3_r(); + void p3_w(uint8_t data); SCN2672_DRAW_CHARACTER_MEMBER(display_pixels); }; diff --git a/src/mame/siemens/pcd_v.cpp b/src/mame/siemens/pcd_v.cpp index e472116b2cc..da5df9e8927 100644 --- a/src/mame/siemens/pcd_v.cpp +++ b/src/mame/siemens/pcd_v.cpp @@ -34,7 +34,6 @@ pcd_video_device::pcd_video_device(const machine_config &mconfig, const char *ta pcx_video_device::pcx_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pcdx_video_device(mconfig, PCX_VIDEO, tag, owner, clock), - device_serial_interface(mconfig, *this), m_crtc(*this, "crtc"), m_charrom(*this, "char"), m_txd_handler(*this) @@ -152,8 +151,8 @@ void pcx_video_device::device_add_mconfig(machine_config &config) gfx.set_addrmap(AS_PROGRAM, &pcx_video_device::pcx_vid_map); gfx.set_addrmap(AS_IO, &pcx_video_device::pcx_vid_io); gfx.port_out_cb<1>().set(FUNC(pcx_video_device::p1_w)); - gfx.serial_tx_cb().set(FUNC(pcx_video_device::tx_callback)); - gfx.serial_rx_cb().set(FUNC(pcx_video_device::rx_callback)); + gfx.port_in_cb<3>().set(FUNC(pcx_video_device::p3_r)); + gfx.port_out_cb<3>().set(FUNC(pcx_video_device::p3_w)); // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); @@ -422,9 +421,6 @@ void pcx_video_device::device_start() m_maincpu->space(AS_IO).install_readwrite_handler(0xfb00, 0xfb01, read8smo_delegate(*this, FUNC(pcdx_video_device::detect_r)), write8smo_delegate(*this, FUNC(pcdx_video_device::detect_w)), 0x00ff); m_txd_handler.resolve_safe(); - set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); - set_rate(600); - decode_gfx(gfx_pcx); } @@ -432,8 +428,6 @@ void pcx_video_device::device_reset() { m_term_key = 0; m_term_stat = 0; - transmit_register_reset(); - receive_register_reset(); m_txd_handler(1); } @@ -443,24 +437,23 @@ void pcx_video_device::map(address_map &map) map(0x0, 0xf).rw(FUNC(pcx_video_device::term_r), FUNC(pcx_video_device::term_w)); } -uint8_t pcx_video_device::rx_callback() +void pcx_video_device::rx_w(int state) { - return get_received_char(); + if (state) + m_p3 |= 1; + else + m_p3 &= ~1; } -void pcx_video_device::tx_callback(uint8_t data) +uint8_t pcx_video_device::p3_r() { - transmit_register_setup(data); + return m_p3; } -void pcx_video_device::tra_callback() +void pcx_video_device::p3_w(uint8_t data) { - m_txd_handler(transmit_register_get_data_bit()); -} + // preserve RXD + m_p3 = (m_p3 & 1) | (data & ~1); -void pcx_video_device::rcv_complete() -{ - receive_register_extract(); - m_mcu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_mcu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); + m_txd_handler(BIT(data, 1)); } diff --git a/src/mame/skeleton/pes.cpp b/src/mame/skeleton/pes.cpp index bf2e8aa242e..6f2aa74d798 100644 --- a/src/mame/skeleton/pes.cpp +++ b/src/mame/skeleton/pes.cpp @@ -64,7 +64,8 @@ Current status: #include "emu.h" #include "cpu/mcs51/mcs51.h" #include "sound/tms5220.h" -#include "machine/terminal.h" +#include "bus/rs232/terminal.h" +#include "bus/rs232/rs232.h" #include "speaker.h" @@ -76,7 +77,7 @@ public: pes_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_terminal(*this, "terminal") + , m_serial(*this, "serial") , m_speech(*this, "tms5220") { } @@ -84,34 +85,25 @@ public: private: - u8 m_term_data = 0U; u8 m_port3 = 0U; virtual void machine_reset() override; void port3_w(u8 data); u8 port3_r(); - void kbd_put(u8 data); + void rx_w(int state); void io_map(address_map &map); void prg_map(address_map &map); required_device m_maincpu; - required_device m_terminal; + required_device m_serial; required_device m_speech; }; -/* Devices */ -void pes_state::kbd_put(u8 data) -{ - m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); - m_term_data = data; -} - - /* Port Handlers */ void pes_state::port3_w(u8 data) { - m_port3 = data; + // preserve RXD + m_port3 = (m_port3 & 0x01) | (data & ~0x01); #if 0 logerror("port3 write: control data written: %02X; ", data); logerror("RXD: %d; ", BIT(data,0)); @@ -123,7 +115,7 @@ void pes_state::port3_w(u8 data) logerror("WR: %d; ", BIT(data,6)); logerror("RD: %d;\n", BIT(data,7)); #endif - // todo: poke serial handler here somehow? + m_serial->write_txd(BIT(data, 1)); } u8 pes_state::port3_r() @@ -136,6 +128,14 @@ u8 pes_state::port3_r() return data; } +void pes_state::rx_w(int state) +{ + if (state) + m_port3 |= 1; + else + m_port3 &= ~1; +} + /* Reset */ void pes_state::machine_reset() @@ -171,6 +171,11 @@ INPUT_PORTS_END Machine Drivers ******************************************************************************/ +static void serial_devices(device_slot_interface &device) +{ + device.option_add("terminal", SERIAL_TERMINAL); +} + void pes_state::pes(machine_config &config) { /* basic machine hardware */ @@ -181,16 +186,14 @@ void pes_state::pes(machine_config &config) m_maincpu->port_out_cb<1>().set(m_speech, FUNC(tms5220_device::data_w)); m_maincpu->port_in_cb<3>().set(FUNC(pes_state::port3_r)); m_maincpu->port_out_cb<3>().set(FUNC(pes_state::port3_w)); - m_maincpu->serial_tx_cb().set(m_terminal, FUNC(generic_terminal_device::write)); - m_maincpu->serial_rx_cb().set([this] () { return m_term_data; }); /* sound hardware */ SPEAKER(config, "mono").front_center(); TMS5220C(config, m_speech, 720000); /* 720Khz clock, 9khz sample-rate, adjustable with 10-turn trimpot */ m_speech->add_route(ALL_OUTPUTS, "mono", 1.0); - GENERIC_TERMINAL(config, m_terminal, 0); - m_terminal->set_keyboard_callback(FUNC(pes_state::kbd_put)); + RS232_PORT(config, m_serial, serial_devices, "terminal"); + m_serial->rxd_handler().set(FUNC(pes_state::rx_w)); } /****************************************************************************** diff --git a/src/mame/skeleton/sk101bl.cpp b/src/mame/skeleton/sk101bl.cpp index f0e801f2186..c44d1f6ce8d 100644 --- a/src/mame/skeleton/sk101bl.cpp +++ b/src/mame/skeleton/sk101bl.cpp @@ -52,7 +52,6 @@ private: void scan_load_w(u8 data); u8 scan_shift_r(); void lcd_control_w(u8 data); - void serial_tx_w(u8 data) { logerror("Serial TX: %02X\n", data); } void prog_map(address_map &map); void ext_map(address_map &map); @@ -163,7 +162,6 @@ void sk101bl_state::sk101bl(machine_config &config) m_maincpu->port_in_cb<1>().set(FUNC(sk101bl_state::p1_r)); m_maincpu->port_out_cb<1>().set(FUNC(sk101bl_state::p1_w)); m_maincpu->port_out_cb<3>().set("alarm", FUNC(speaker_sound_device::level_w)).bit(3); - m_maincpu->serial_tx_cb().set(FUNC(sk101bl_state::serial_tx_w)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); screen.set_refresh_hz(50); diff --git a/src/mame/trs/trs80dt1.cpp b/src/mame/trs/trs80dt1.cpp index 891e5697dea..0910018a5c5 100644 --- a/src/mame/trs/trs80dt1.cpp +++ b/src/mame/trs/trs80dt1.cpp @@ -71,9 +71,11 @@ private: u8 dma_r(offs_t offset); u8 key_r(offs_t offset); u8 port1_r(); + u8 port3_r(); void store_w(u8 data); void port1_w(u8 data); void port3_w(u8 data); + void rx_w(int state); I8275_DRAW_CHARACTER_MEMBER(crtc_update_row); void io_map(address_map &map); @@ -94,6 +96,8 @@ private: required_device m_7474; required_device m_rs232; required_device m_centronics; + + u8 m_port3; }; void trs80dt1_state::machine_reset() @@ -103,6 +107,7 @@ void trs80dt1_state::machine_reset() // line is active low in the real chip m_nvram->recall(1); m_nvram->recall(0); + m_port3 = 0; } u8 trs80dt1_state::dma_r(offs_t offset) @@ -158,6 +163,21 @@ void trs80dt1_state::port3_w(u8 data) { m_rs232->write_txd(BIT(data, 1)); m_buzzer->set_state(BIT(data, 4)); + + m_port3 = (m_port3 & 1) | (data & ~1); +} + +u8 trs80dt1_state::port3_r() +{ + return m_port3; +} + +void trs80dt1_state::rx_w(int state) +{ + if (state) + m_port3 |= 1; + else + m_port3 &= ~1; } void trs80dt1_state::prg_map(address_map &map) @@ -341,6 +361,7 @@ void trs80dt1_state::trs80dt1(machine_config &config) m_maincpu->port_out_cb<1>().set(FUNC(trs80dt1_state::port1_w)); m_maincpu->port_in_cb<1>().set(FUNC(trs80dt1_state::port1_r)); m_maincpu->port_out_cb<3>().set(FUNC(trs80dt1_state::port3_w)); + m_maincpu->port_in_cb<3>().set(FUNC(trs80dt1_state::port3_r)); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); @@ -373,7 +394,7 @@ void trs80dt1_state::trs80dt1(machine_config &config) BEEP(config, m_buzzer, 2000).add_route(ALL_OUTPUTS, "mono", 0.50); RS232_PORT(config, m_rs232, default_rs232_devices, nullptr); - m_rs232->rxd_handler().set_inputline("maincpu", MCS51_RX_LINE); + m_rs232->rxd_handler().set(FUNC(trs80dt1_state::rx_w)); /* printer */ CENTRONICS(config, m_centronics, centronics_devices, "printer"); diff --git a/src/mame/wang/wangpckb.cpp b/src/mame/wang/wangpckb.cpp index 0f4bfa0d72e..8faba3f7954 100644 --- a/src/mame/wang/wangpckb.cpp +++ b/src/mame/wang/wangpckb.cpp @@ -44,7 +44,6 @@ Notes: TODO: - - rewrite the mcs51.c serial I/O to replace this horrible, horrible hack - dip switches */ @@ -119,9 +118,8 @@ void wangpc_keyboard_device::device_add_mconfig(machine_config &config) m_maincpu->port_in_cb<1>().set(FUNC(wangpc_keyboard_device::kb_p1_r)); m_maincpu->port_out_cb<1>().set(FUNC(wangpc_keyboard_device::kb_p1_w)); m_maincpu->port_out_cb<2>().set(FUNC(wangpc_keyboard_device::kb_p2_w)); + m_maincpu->port_in_cb<3>().set(FUNC(wangpc_keyboard_device::kb_p3_r)); m_maincpu->port_out_cb<3>().set(FUNC(wangpc_keyboard_device::kb_p3_w)); - m_maincpu->serial_tx_cb().set(FUNC(wangpc_keyboard_device::mcs51_tx_callback)); - m_maincpu->serial_rx_cb().set(FUNC(wangpc_keyboard_device::mcs51_rx_callback)); // sound hardware SPEAKER(config, "mono").front_center(); @@ -369,7 +367,6 @@ ioport_constructor wangpc_keyboard_device::device_input_ports() const wangpc_keyboard_device::wangpc_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, WANGPC_KEYBOARD, tag, owner, clock), - device_serial_interface(mconfig, *this), m_maincpu(*this, I8051_TAG), m_y(*this, "Y%u", 0), m_txd_handler(*this), @@ -389,11 +386,6 @@ void wangpc_keyboard_device::device_start() m_txd_handler.resolve_safe(); m_leds.resolve(); - set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2); - - set_rcv_rate(62500); - set_tra_rate(62500); - save_item(NAME(m_keylatch)); save_item(NAME(m_rxd)); } @@ -405,63 +397,10 @@ void wangpc_keyboard_device::device_start() void wangpc_keyboard_device::device_reset() { - receive_register_reset(); - transmit_register_reset(); - m_txd_handler(1); } -//------------------------------------------------- -// tra_callback - -//------------------------------------------------- - -void wangpc_keyboard_device::tra_callback() -{ - int bit = transmit_register_get_data_bit(); - - if (LOG) logerror("KB '%s' Transmit Bit %u\n", tag(), bit); - - m_txd_handler(bit); -} - - -//------------------------------------------------- -// tra_complete - -//------------------------------------------------- - -void wangpc_keyboard_device::tra_complete() -{ -} - - -//------------------------------------------------- -// rcv_callback - -//------------------------------------------------- - -void wangpc_keyboard_device::rcv_callback() -{ - if (LOG) logerror("KB '%s' Receive Bit %u\n", tag(), m_rxd); - - receive_register_update_bit(m_rxd); -} - - -//------------------------------------------------- -// rcv_complete - -//------------------------------------------------- - -void wangpc_keyboard_device::rcv_complete() -{ - receive_register_extract(); - - if (LOG) logerror("KB '%s' Receive Data %02x\n", tag(), get_received_char()); - - m_maincpu->set_input_line(MCS51_RX_LINE, ASSERT_LINE); - m_maincpu->set_input_line(MCS51_RX_LINE, CLEAR_LINE); -} - - //------------------------------------------------- // write_rxd - //------------------------------------------------- @@ -469,32 +408,6 @@ void wangpc_keyboard_device::rcv_complete() WRITE_LINE_MEMBER(wangpc_keyboard_device::write_rxd) { m_rxd = state; - - device_serial_interface::rx_w(state); -} - - -//------------------------------------------------- -// mcs51_rx_callback - -//------------------------------------------------- - -uint8_t wangpc_keyboard_device::mcs51_rx_callback() -{ - if (LOG) logerror("KB '%s' CPU Receive Data %02x\n", tag(), get_received_char()); - - return get_received_char(); -} - - -//------------------------------------------------- -// mcs51_tx_callback - -//------------------------------------------------- - -void wangpc_keyboard_device::mcs51_tx_callback(uint8_t data) -{ - if (LOG) logerror("KB '%s' CPU Transmit Data %02x\n", tag(), data); - - transmit_register_setup(data); } @@ -565,6 +478,16 @@ void wangpc_keyboard_device::kb_p2_w(uint8_t data) } +//------------------------------------------------- +// kb_p3_r - +//------------------------------------------------- + +uint8_t wangpc_keyboard_device::kb_p3_r() +{ + return m_rxd; +} + + //------------------------------------------------- // kb_p3_w - //------------------------------------------------- @@ -587,4 +510,5 @@ void wangpc_keyboard_device::kb_p3_w(uint8_t data) */ //if (LOG) logerror("P3 %02x\n", data); + m_txd_handler(BIT(data, 1)); } diff --git a/src/mame/wang/wangpckb.h b/src/mame/wang/wangpckb.h index 99b011cebfc..9a095b9a4f0 100644 --- a/src/mame/wang/wangpckb.h +++ b/src/mame/wang/wangpckb.h @@ -15,8 +15,6 @@ #include "sound/sn76496.h" -#include "diserial.h" - //************************************************************************** // TYPE DEFINITIONS @@ -24,7 +22,7 @@ // ======================> wangpc_keyboard_device -class wangpc_keyboard_device : public device_t, public device_serial_interface +class wangpc_keyboard_device : public device_t { public: // construction/destruction @@ -46,12 +44,6 @@ protected: virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; - // device_serial_interface overrides - virtual void tra_callback() override; - virtual void tra_complete() override; - virtual void rcv_callback() override; - virtual void rcv_complete() override; - private: required_device m_maincpu; required_ioport_array<16> m_y; @@ -61,12 +53,10 @@ private: uint8_t m_keylatch; int m_rxd; - uint8_t mcs51_rx_callback(); - void mcs51_tx_callback(uint8_t data); - uint8_t kb_p1_r(); void kb_p1_w(uint8_t data); void kb_p2_w(uint8_t data); + uint8_t kb_p3_r(); void kb_p3_w(uint8_t data); }; -- cgit v1.2.3