From 993f19c8d2cdc3796183642c1345f54fa22ed237 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Sun, 27 Mar 2016 14:08:43 +0200 Subject: [PATCH] Added initial support for baudrate generator --- src/devices/machine/z80scc.cpp | 156 ++++++++++++++++++++++++++------- src/devices/machine/z80scc.h | 69 +++++++++------ 2 files changed, 167 insertions(+), 58 deletions(-) diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index de3ec568da7..810082a7241 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -76,7 +76,7 @@ TODO: // MACROS / CONSTANTS //************************************************************************** -#define VERBOSE 0 +#define VERBOSE 2 #define LOG(x) do { if (VERBOSE) logerror x; } while (0) #if VERBOSE == 2 @@ -85,8 +85,10 @@ TODO: #ifdef _MSC_VER #define FUNCNAME __func__ +#define LLFORMAT "%I64%" #else #define FUNCNAME __PRETTY_FUNCTION__ +#define LLFORMAT "%lld" #endif #define CHANA_TAG "cha" @@ -163,10 +165,12 @@ z80scc_device::z80scc_device(const machine_config &mconfig, const char *tag, dev device_z80daisy_interface(mconfig, *this), m_chanA(*this, CHANA_TAG), m_chanB(*this, CHANB_TAG), +#if 0 m_rxca(0), m_txca(0), m_rxcb(0), m_txcb(0), +#endif m_out_txda_cb(*this), m_out_dtra_cb(*this), m_out_rtsa_cb(*this), @@ -198,7 +202,7 @@ scc80230_device::scc80230_device(const machine_config &mconfig, const char *tag, : z80scc_device(mconfig, SCC80230, "SCC 80230", tag, owner, clock, TYPE_SCC80230, "scc80230", __FILE__){ } scc8530_device::scc8530_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: z80scc_device(mconfig, SCC8530N, "SCC 8530", tag, owner, clock, TYPE_SCC8530, "scc8530", __FILE__){ } + : z80scc_device(mconfig, SCC8530N, "SCC 8530", tag, owner, clock, TYPE_SCC8530, "scc8530", __FILE__){ } scc85C30_device::scc85C30_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : z80scc_device(mconfig, SCC85C30, "SCC 85C30", tag, owner, clock, TYPE_SCC85C30, "scc85C30", __FILE__){ } @@ -236,13 +240,17 @@ void z80scc_device::device_start() m_out_rxdrqb_cb.resolve_safe(); m_out_txdrqb_cb.resolve_safe(); +#if 0 // configure channel A m_chanA->m_rxc = m_rxca; m_chanA->m_txc = m_txca; + m_chanA->baudtimer = timer_alloc(0); // configure channel B m_chanB->m_rxc = m_rxcb; m_chanB->m_txc = m_txcb; + m_chanB->baudtimer = timer_alloc(1); +#endif // state saving save_item(NAME(m_int_state)); @@ -257,12 +265,22 @@ void z80scc_device::device_start() void z80scc_device::device_reset() { - LOG(("%s %s \n",FUNCNAME, tag())); + LOG(("%s %s \n",tag(), FUNCNAME)); m_chanA->reset(); m_chanB->reset(); } +#if 0 +static void z80scc_device::configure_channels(device_t &device, int rxa, int txa, int rxb, int txb) +{ + m_chanA->m_rxc = rxa; + m_chanA->m_txc = txa; + m_chanB->m_rxc = rxa; + m_chanB->m_txc = txa; +} +#endif + /* * Interrupts Each of the SCC's two channels contain three sources of interrupts, making a total of six interrupt @@ -277,7 +295,7 @@ int z80scc_device::z80daisy_irq_state() int state = 0; int i; - LOG(("%s %s A:%d%d%d B:%d%d%d ",FUNCNAME, tag(), + LOG(("%s %s A:%d%d%d B:%d%d%d ",tag(), FUNCNAME, m_int_state[0], m_int_state[1], m_int_state[2], m_int_state[3], m_int_state[4], m_int_state[5])); @@ -307,7 +325,7 @@ int z80scc_device::z80daisy_irq_ack() { int i; - LOG(("%s %s - needs fixing for SCC\n",FUNCNAME, tag())); + LOG(("%s %s - needs fixing for SCC\n",tag(), FUNCNAME)); // loop over all interrupt sources for (i = 0; i < 6; i++) @@ -320,7 +338,7 @@ int z80scc_device::z80daisy_irq_ack() //m_chanA->m_rr0 &= ~z80scc_channel::RR0_INTERRUPT_PENDING; check_interrupts(); - //LOG(("%s %s \n",FUNCNAME, tag(), m_chanB->m_rr2)); + //LOG(("%s %s : Interrupt Acknowledge Vector %02x\n",tag(), FUNCNAME, m_chanB->m_rr2)); return m_chanB->m_rr2; } @@ -340,7 +358,7 @@ void z80scc_device::z80daisy_irq_reti() { int i; - LOG(("%s %s \n",FUNCNAME, tag())); + LOG(("%s %s \n",tag(), FUNCNAME)); // loop over all interrupt sources for (i = 0; i < 6; i++) @@ -366,7 +384,7 @@ void z80scc_device::z80daisy_irq_reti() void z80scc_device::check_interrupts() { int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; - LOG(("%s %s \n",FUNCNAME, tag())); + LOG(("%s %s \n",tag(), FUNCNAME)); m_out_int_cb(state); } @@ -377,7 +395,7 @@ void z80scc_device::check_interrupts() void z80scc_device::reset_interrupts() { - LOG(("%s %s \n",FUNCNAME, tag())); + LOG(("%s %s \n",tag(), FUNCNAME)); // reset internal interrupt sources for (auto & elem : m_int_state) { @@ -404,7 +422,7 @@ UINT8 z80scc_device::modify_vector(UINT8 vec, int i, UINT8 src) 1 1 1 Ch A Special Receive Condition */ // Add channel offset according to table above - src |= (i == CHANNEL_A ? 0x04 : 0x00 ); + src |= (i == CHANNEL_A ? 0x04 : 0x00 ); // Modify vector according to Hi/lo bit of WR9 if (m_chanA->m_wr9 & z80scc_channel::WR9_BIT_SHSL) // Affect V4-V6 @@ -425,12 +443,12 @@ UINT8 z80scc_device::modify_vector(UINT8 vec, int i, UINT8 src) void z80scc_device::trigger_interrupt(int index, int state) { UINT8 vector = m_chanB->m_wr2; - UINT8 source; + UINT8 source = 0; int priority; - int prio_level; + int prio_level = 0; - LOG(("%s %s:%c %d \n",FUNCNAME, tag(), 'A' + index, state)); + LOG(("%s %s:%c %d \n",tag(), FUNCNAME, 'A' + index, state)); /* The Master Interrupt Enable (MIE) bit, WR9 D3, must be set to enable the SCC to generate interrupts.*/ if (!(m_chanA->m_wr9 & z80scc_channel::WR9_BIT_MIE)) @@ -484,7 +502,7 @@ void z80scc_device::trigger_interrupt(int index, int state) vector = modify_vector(vector, index, source); } - //LOG(("Z80SCC \"%s\": %c : Interrupt Request %u\n", tag(), 'A' + index, state)); + LOG(("Z80SCC \"%s\": %c : Interrupt Request %u\n", tag(), 'A' + index, state)); // update vector register // TODO: What if interrupts are nested? May we loose the modified vector or even get the wrong one? m_chanB->m_wr2 = vector; @@ -671,6 +689,7 @@ WRITE8_MEMBER( z80scc_device::ba_cd_inv_w ) z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, Z80SCC_CHANNEL, "Z80 SCC channel", tag, owner, clock, "z80scc_channel", __FILE__), device_serial_interface(mconfig, *this), + m_brg_counter(0), m_rx_error(0), m_rx_clock(0), m_rx_first(0), @@ -716,6 +735,9 @@ void z80scc_channel::device_start() m_rx_fifo_sz = (m_uart->m_variant & SET_ESCC) ? 8 : 3; m_rx_fifo_wp = m_rx_fifo_rp = 0; + // baudrate clocks and timers + baudtimer = timer_alloc(TIMER_ID_BAUD); + // state saving save_item(NAME(m_rr0)); save_item(NAME(m_rr1)); @@ -828,6 +850,32 @@ void z80scc_channel::device_reset() void z80scc_channel::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { +// LOG(("%s %d\n", FUNCNAME, id)); + + switch(id) + { + case TIMER_ID_BAUD: + { + int brconst = m_wr13 << 8 | m_wr12 | 1; // If the counter is 1 the effect is passthrough ehh?! To avoid div0... + if (m_wr14 & WR14_BRG_ENABLE) + { + int rate = m_owner->clock() / brconst; + attotime attorate = attotime::from_hz(rate); + timer.adjust(attorate, id, attorate); + txc_w(m_brg_counter & 1); + rxc_w(m_brg_counter & 1); + m_brg_counter++; // Will just keep track of state in timer mode, not hardware counter value. + } + else + { + LOG((" - turning off Baudrate timer\n")); + timer.adjust(attotime::never, 0, attotime::never); + } + } + break; + default: + logerror("Spurious timer %d event\n", id); + } device_serial_interface::device_timer(timer, id, param, ptr); } @@ -840,7 +888,7 @@ void z80scc_channel::tra_callback() { if (!(m_wr5 & WR5_TX_ENABLE)) { - LOG(("%d %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); // transmit mark if (m_index == z80scc_device::CHANNEL_A) m_uart->m_out_txda_cb(1); @@ -849,7 +897,7 @@ void z80scc_channel::tra_callback() } else if (m_wr5 & WR5_SEND_BREAK) { - LOG(("%d %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); // transmit break if (m_index == z80scc_device::CHANNEL_A) m_uart->m_out_txda_cb(0); @@ -860,7 +908,7 @@ void z80scc_channel::tra_callback() { int db = transmit_register_get_data_bit(); - LOG(("%d %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, db, m_wr5)); // transmit data if (m_index == z80scc_device::CHANNEL_A) m_uart->m_out_txda_cb(db); @@ -869,7 +917,7 @@ void z80scc_channel::tra_callback() } else { - LOG(("%d %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, m_owner->tag(), 'A' + m_index); } } @@ -883,7 +931,7 @@ void z80scc_channel::tra_complete() { if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK) && !(m_rr0 & RR0_TX_BUFFER_EMPTY)) { - LOG(("%d %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_tx_data, m_wr5)); transmit_register_setup(m_tx_data); @@ -895,7 +943,7 @@ void z80scc_channel::tra_complete() } else if (m_wr5 & WR5_SEND_BREAK) { - LOG(("%d %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); // transmit break if (m_index == z80scc_device::CHANNEL_A) m_uart->m_out_txda_cb(0); @@ -904,7 +952,7 @@ void z80scc_channel::tra_complete() } else { - LOG(("%d %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); // transmit mark if (m_index == z80scc_device::CHANNEL_A) m_uart->m_out_txda_cb(1); @@ -915,7 +963,7 @@ void z80scc_channel::tra_complete() // if transmit buffer is empty if (m_rr0 & RR0_TX_BUFFER_EMPTY) { - LOG(("%d %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, m_wr5)); // then all characters have been sent m_rr1 |= RR1_ALL_SENT; @@ -939,7 +987,7 @@ void z80scc_channel::rcv_callback() #if 1 else { - LOG(("%d %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index)); logerror("Z80SCC %s() \"%s \"Channel %c Received data dit but receiver is disabled\n", __func__, m_owner->tag(), 'A' + m_index); } #endif @@ -956,7 +1004,7 @@ void z80scc_channel::rcv_complete() receive_register_extract(); data = get_received_char(); - LOG(("%d %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data)); + LOG((LLFORMAT " %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, data)); receive_data(data); } @@ -1081,7 +1129,7 @@ int z80scc_channel::get_tx_word_length() * Break/Abort latch. */ UINT8 z80scc_channel::do_sccreg_rr0() { - LOG(("%s %s\n",FUNCNAME, tag())); + LOG(("%s %s <- %02x\n",tag(), FUNCNAME, m_rr0)); return m_rr0; } @@ -1090,7 +1138,7 @@ UINT8 z80scc_channel::do_sccreg_rr0() * codes for the I-Field in the SDLC Receive Mode. */ UINT8 z80scc_channel::do_sccreg_rr1() { - LOG(("%s %s\n",FUNCNAME, tag())); + LOG(("%s %s <- %02x\n",tag(), FUNCNAME, m_rr1)); return m_rr1; } @@ -1710,14 +1758,14 @@ void z80scc_channel::do_sccreg_wr11(UINT8 data) void z80scc_channel::do_sccreg_wr12(UINT8 data) { m_wr12 = data; - LOG(("Z80SCC \"%s\": %c : %s %02x Low byte of Time Constant for Baudrate generator - not implemented \n", m_owner->tag(), 'A' + m_index, __func__, data)); + LOG(("Z80SCC \"%s\": %c : %s %02x Low byte of Time Constant for Baudrate generator\n", m_owner->tag(), 'A' + m_index, __func__, data)); } /* WR13 contains the upper byte of the time constant for the baud rate generator. */ void z80scc_channel::do_sccreg_wr13(UINT8 data) { m_wr13 = data; - LOG(("Z80SCC \"%s\": %c : %s %02x High byte of Time Constant for Baudrate generator - not implemented \n", m_owner->tag(), 'A' + m_index, __func__, data)); + LOG(("Z80SCC \"%s\": %c : %s %02x High byte of Time Constant for Baudrate generator\n", m_owner->tag(), 'A' + m_index, __func__, data)); } /* @@ -1759,7 +1807,7 @@ void z80scc_channel::do_sccreg_wr14(UINT8 data) /* Issuing this command disables the DPLL, resets the clock missing latches in RR10, and forces a continuous Search mode state.*/ LOG(("Z80SCC \"%s\": %c : %s Misc Control Bits Disable DPLL Command - not implemented\n", m_owner->tag(), 'A' + m_index, __func__)); break; - case WR14_CMD_SS_BGR: + case WR14_CMD_SS_BRG: /* Issuing this command forces the clock for the DPLL to come from the output of the BRG. */ LOG(("Z80SCC \"%s\": %c : %s Misc Control Bits Baudrate Generator Input DPLL Command - not implemented\n", m_owner->tag(), 'A' + m_index, __func__)); break; @@ -1780,6 +1828,26 @@ void z80scc_channel::do_sccreg_wr14(UINT8 data) default: logerror("Z80SCC \"%s\": %c : %s Mics Control Bits command %02x - not implemented \n", m_owner->tag(), 'A' + m_index, __func__, data); } + /* Based on baudrate code from 8530scc.cpp */ + if ( !(m_wr14 & WR14_BRG_ENABLE) && (data & WR14_BRG_ENABLE) ) // baud rate generator beeing enabled? + { + LOG(("Z80SCC \"%s\": %c : %s Mics Control Bits Baudrate generator enabled with \n", m_owner->tag(), 'A' + m_index, __func__)); + m_brg_counter = m_wr13 << 8 | m_wr12 | 1; // If the counter is 1 the effect is passthrough ehh?! To avoid div0... + if (data & WR14_BRG_SOURCE) // Do we use the PCLK as baudrate source + { + int rate = m_owner->clock() / m_brg_counter; + LOG(("PCLK as source, rate (%d) = PCLK (%d) / (%d)\n", rate, m_owner->clock(), m_brg_counter)); + + baudtimer->adjust(attotime::from_hz(rate), TIMER_ID_BAUD, attotime::from_hz(rate)); // Start the baudrate generator + } + else + LOG(("external clock source\n")); + } + else if ( (m_wr14 & WR14_BRG_ENABLE) && !(data & WR14_BRG_ENABLE) ) // baud rate generator beeing disabled? + { + baudtimer->adjust(attotime::never, TIMER_ID_BAUD, attotime::never); // Stop the baudrate generator + m_brg_counter = 0; + } // TODO: Add info on the other bits of this register m_wr14 = data; } @@ -2181,7 +2249,34 @@ WRITE_LINE_MEMBER( z80scc_channel::sync_w ) //------------------------------------------------- WRITE_LINE_MEMBER( z80scc_channel::rxc_w ) { +/* Support for external clock as source for BRG yet to be finished */ +#if 0 //LOG(("Z80SCC \"%s\": %c : Receiver Clock Pulse\n", m_owner->tag(), m_index + 'A')); + if ( ((m_wr3 & WR3_RX_ENABLE) | (m_wr5 & WR5_TX_ENABLE)) && m_wr14 & WR14_BRG_ENABLE) + { + if (!(m_wr14 & WR14_BRG_SOURCE)) // Is the Baud rate Generator driven by RTxC? + { + printf("x"); + if (!m_brg_counter) // Zero crossing?! + { + printf("."); + m_brg_counter = m_wr13 << 8 | m_wr12; // Reload BRG counter + if ((m_wr11 & WR11_TRACLK_SRC_MASK) == WR11_TRACLK_SRC_BR) // Is transmitt clock driven by BRG? + { + printf("+"); + txc_w(state); + } + } + else + { + m_brg_counter--; + if ((m_wr11 & WR11_RCVCLK_SRC_MASK) == WR11_RCVCLK_SRC_BR) // Is receive clock driven by BRG and not zero cross + return; + } + } + } +#endif + if (m_wr3 & WR3_RX_ENABLE) { int clocks = get_clock_mode(); @@ -2194,7 +2289,6 @@ WRITE_LINE_MEMBER( z80scc_channel::rxc_w ) m_rx_clock++; if (m_rx_clock == clocks) m_rx_clock = 0; - } } } @@ -2240,7 +2334,7 @@ void z80scc_channel::update_serial() else parity = PARITY_NONE; - LOG(("%d %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, 1, + LOG((LLFORMAT " %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", machine().firstcpu->total_cycles(), FUNCNAME, m_owner->tag(), 'A' + m_index, 1, data_bit_count, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', (stop_bits + 1) / 2)); set_data_frame(1, data_bit_count, parity, stop_bits); diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h index 7f956ec9b74..04d64221e8f 100644 --- a/src/devices/machine/z80scc.h +++ b/src/devices/machine/z80scc.h @@ -137,7 +137,7 @@ public: UINT8 do_sccreg_rr5(); UINT8 do_sccreg_rr6(); UINT8 do_sccreg_rr7(); -// UINT8 do_sccreg_rr8(); + // UINT8 do_sccreg_rr8(); Short cutted due to frequent use UINT8 do_sccreg_rr9(); UINT8 do_sccreg_rr10(); UINT8 do_sccreg_rr11(); @@ -236,21 +236,21 @@ protected: // Read registers enum { - REG_RR0_STATUS = 0, // SIO + REG_RR0_STATUS = 0, // SIO REG_RR1_SPEC_RCV_COND = 1, // SIO REG_RR2_INTERRUPT_VECT = 2, // SIO REG_RR3_INTERUPPT_PEND = 3, - REG_RR4_WR4_OR_RR0 = 4, - REG_RR5_WR5_OR_RR0 = 5, - REG_RR6_LSB_OR_RR2 = 6, - REG_RR7_MSB_OR_RR3 = 7, + REG_RR4_WR4_OR_RR0 = 4, + REG_RR5_WR5_OR_RR0 = 5, + REG_RR6_LSB_OR_RR2 = 6, + REG_RR7_MSB_OR_RR3 = 7, REG_RR8_RECEIVE_DATA = 8, - REG_RR9_WR3_OR_RR13 = 9, + REG_RR9_WR3_OR_RR13 = 9, REG_RR10_MISC_STATUS = 10, REG_RR11_WR10_OR_RR15 = 11, REG_RR12_LO_TIME_CONST = 12, REG_RR13_HI_TIME_CONST = 13, - REG_RR14_WR7_OR_R10 = 14, + REG_RR14_WR7_OR_R10 = 14, REG_RR15_WR15_EXT_STAT = 15 }; @@ -259,10 +259,10 @@ protected: { REG_WR0_COMMAND_REGPT = 0, // SIO REG_WR1_INT_DMA_ENABLE = 1, // SIO - REG_WR2_INT_VECTOR = 2, // SIO - REG_WR3_RX_CONTROL = 3, // SIO - REG_WR4_RX_TX_MODES = 4, // SIO - REG_WR5_TX_CONTROL = 5, // SIO + REG_WR2_INT_VECTOR = 2, // SIO + REG_WR3_RX_CONTROL = 3, // SIO + REG_WR4_RX_TX_MODES = 4, // SIO + REG_WR5_TX_CONTROL = 5, // SIO REG_WR6_SYNC_OR_SDLC_A = 6, // SIO REG_WR7_SYNC_OR_SDLC_F = 7, // SIO REG_WR8_TRANSMIT_DATA = 8, @@ -271,21 +271,21 @@ protected: REG_WR11_CLOCK_MODES = 11, REG_WR12_LO_BAUD_GEN = 12, REG_WR13_HI_BAUD_GEN = 13, - REG_WR14_MISC_CTRL = 14, + REG_WR14_MISC_CTRL = 14, REG_WR15_EXT_ST_INT_CTRL= 15 }; enum { RR0_RX_CHAR_AVAILABLE = 0x01, // SIO bit - RR0_ZC = 0x02, // SCC bit - RR0_TX_BUFFER_EMPTY = 0x04, // SIO - RR0_DCD = 0x08, // SIO - RR0_RI = 0x10, // DART bit? TODO: investigate function and remove - RR0_SYNC_HUNT = 0x10, // SIO bit, not supported - RR0_CTS = 0x20, // SIO bit - RR0_TX_UNDERRUN = 0x40, // SIO bit, not supported - RR0_BREAK_ABORT = 0x80 // SIO bit, not supported + RR0_ZC = 0x02, // SCC bit + RR0_TX_BUFFER_EMPTY = 0x04, // SIO + RR0_DCD = 0x08, // SIO + RR0_RI = 0x10, // DART bit? TODO: investigate function and remove + RR0_SYNC_HUNT = 0x10, // SIO bit, not supported + RR0_CTS = 0x20, // SIO bit + RR0_TX_UNDERRUN = 0x40, // SIO bit, not supported + RR0_BREAK_ABORT = 0x80 // SIO bit, not supported }; enum @@ -456,16 +456,31 @@ protected: enum { WR14_DPLL_CMD_MASK = 0xe0, // Command - WR14_CMD_NULL = 0x00, // 0 0 0 - WR14_CMD_ESM = 0x20, // 0 0 1 - WR14_CMD_RMC = 0x40, // 0 1 0 + WR14_CMD_NULL = 0x00, // 0 0 0 + WR14_CMD_ESM = 0x20, // 0 0 1 + WR14_CMD_RMC = 0x40, // 0 1 0 WR14_CMD_DISABLE_DPLL = 0x60, // 0 1 1 - WR14_CMD_SS_BGR = 0x80, // 1 0 0 + WR14_CMD_SS_BRG = 0x80, // 1 0 0 WR14_CMD_SS_RTXC = 0xa0, // 1 0 1 - WR14_CMD_SET_FM = 0xc0, // 1 1 0 - WR14_CMD_SET_NRZI = 0xe0 // 1 1 1 + WR14_CMD_SET_FM = 0xc0, // 1 1 0 + WR14_CMD_SET_NRZI = 0xe0, // 1 1 1 + WR14_BRG_ENABLE = 0x01, + WR14_BRG_SOURCE = 0x02, + WR14_DTR_REQ_FUNC = 0x04, + WR14_AUTO_ECHO = 0x08, + WR14_LOCAL_LOOPBACK = 0x010 }; + enum + { + TIMER_ID_BAUD, + TIMER_ID_XTAL, + TIMER_ID_RTXC, + TIMER_ID_TRXC + }; + emu_timer *baudtimer; + UINT16 m_brg_counter; + void update_serial(); void set_dtr(int state); void set_rts(int state);