diff options
author | 2014-03-17 00:57:15 +0000 | |
---|---|---|
committer | 2014-03-17 00:57:15 +0000 | |
commit | 0ce1612feb4675ad57afd7dc9c4725c24c298978 (patch) | |
tree | 3bb593bdbf9d2b1fe0c24e13d8d4991cbd582c2b /src/emu/machine/mos6551.c | |
parent | af9918bd4d6af6605e705c8bf339d612760e3885 (diff) |
Rewritten 6551 emulation. Changed clock to be the o2 clock instead of the baud rate xtal, supports external clocking, generates transmit interrupts when idle, added echo mode, dcd/dsr/cts input handling, parity & stop bit checking. Tested and fixed hookup to commodore lcd & plus 4. [smf]
Diffstat (limited to 'src/emu/machine/mos6551.c')
-rw-r--r-- | src/emu/machine/mos6551.c | 885 |
1 files changed, 634 insertions, 251 deletions
diff --git a/src/emu/machine/mos6551.c b/src/emu/machine/mos6551.c index 700f199eabb..a103b6072e2 100644 --- a/src/emu/machine/mos6551.c +++ b/src/emu/machine/mos6551.c @@ -1,5 +1,5 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder +// license:MAME +// copyright-holders:smf /********************************************************************** MOS Technology 6551 Asynchronous Communication Interface Adapter @@ -9,399 +9,782 @@ **********************************************************************/ -/* - - TODO: - - - receiver disable - - IRQ on DCD/DSR change - - parity - - framing error - -*/ - #include "mos6551.h" - - -//************************************************************************** -// MACROS / CONSTANTS -//************************************************************************** - #define LOG 0 - -const int mos6551_device::brg_divider[] = { - 0, 2304, 1536, 1048, 856, 768, 384, 192, 96, 64, 48, 32, 24, 16, 12, 6 -}; - - - -//************************************************************************** -// DEVICE DEFINITIONS -//************************************************************************** - -// device type definition const device_type MOS6551 = &device_creator<mos6551_device>; +mos6551_device::mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, MOS6551, "MOS6551", tag, owner, clock, "mos6551", __FILE__), + m_internal_clock(*this, "clock"), + m_irq_handler(*this), + m_txd_handler(*this), + m_rxc_handler(*this), + m_rts_handler(*this), + m_dtr_handler(*this), + m_irq(0), + m_txd(0), + m_rxc(0), + m_rts(0), + m_dtr(0), + m_xtal(0), + m_cts(1), + m_dsr(1), + m_dcd(1), + m_rxd(1), + m_tx_output(OUTPUT_MARK) +{ +} +const int mos6551_device::internal_divider[] = +{ + 0, 2304, 1536, 1048, 856, 768, 384, 192, 96, 64, 48, 32, 24, 16, 12, 6 +}; -//************************************************************************** -// LIVE DEVICE -//************************************************************************** +const int mos6551_device::transmitter_controls[4][3] = +{ + //tx irq, tx ena, brk + {0, 0, 0}, + {1, 1, 0}, + {0, 1, 0}, + {0, 1, 1} +}; -//------------------------------------------------- -// mos6551_device - constructor -//------------------------------------------------- +static MACHINE_CONFIG_FRAGMENT( mos6551 ) + MCFG_DEVICE_ADD("clock", CLOCK, 0) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(mos6551_device, internal_clock)) +MACHINE_CONFIG_END -mos6551_device::mos6551_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MOS6551, "MOS6551", tag, owner, clock, "mos6551", __FILE__), - device_serial_interface(mconfig, *this), - m_irq_handler(*this), - m_txd_handler(*this), - m_rts_handler(*this), - m_dtr_handler(*this), - m_ctrl(0), - m_cmd(CMD_RIE), - m_st(ST_TDRE), - m_ext_rxc(0), - m_cts(1), - m_dsr(1), - m_dcd(1), - m_chip_type(MOS6551_TYPE_MOS) +machine_config_constructor mos6551_device::device_mconfig_additions() const { + return MACHINE_CONFIG_NAME( mos6551 ); } - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - void mos6551_device::device_start() { // resolve callbacks m_irq_handler.resolve_safe(); m_txd_handler.resolve_safe(); + m_rxc_handler.resolve_safe(); m_rts_handler.resolve_safe(); m_dtr_handler.resolve_safe(); // state saving - save_item(NAME(m_ctrl)); - save_item(NAME(m_cmd)); - save_item(NAME(m_st)); + save_item(NAME(m_control)); + save_item(NAME(m_command)); + save_item(NAME(m_status)); save_item(NAME(m_tdr)); - save_item(NAME(m_ext_rxc)); + save_item(NAME(m_rdr)); + + save_item(NAME(m_irq_state)); + + save_item(NAME(m_irq)); + save_item(NAME(m_txd)); + save_item(NAME(m_rxc)); + save_item(NAME(m_rts)); + save_item(NAME(m_dtr)); + + save_item(NAME(m_xtal)); save_item(NAME(m_cts)); save_item(NAME(m_dsr)); save_item(NAME(m_dcd)); + save_item(NAME(m_rxd)); + + save_item(NAME(m_wordlength)); + save_item(NAME(m_extrastop)); + save_item(NAME(m_brk)); + save_item(NAME(m_echo_mode)); + save_item(NAME(m_parity)); + + save_item(NAME(m_rx_state)); + save_item(NAME(m_rx_clock)); + save_item(NAME(m_rx_bits)); + save_item(NAME(m_rx_shift)); + save_item(NAME(m_rx_parity)); + save_item(NAME(m_rx_counter)); + save_item(NAME(m_rx_irq_enable)); + save_item(NAME(m_rx_internal_clock)); + + save_item(NAME(m_tx_state)); + save_item(NAME(m_tx_output)); + save_item(NAME(m_tx_clock)); + save_item(NAME(m_tx_bits)); + save_item(NAME(m_tx_shift)); + save_item(NAME(m_tx_parity)); + save_item(NAME(m_tx_counter)); + save_item(NAME(m_tx_enable)); + save_item(NAME(m_tx_irq_enable)); + save_item(NAME(m_tx_internal_clock)); + + m_internal_clock->set_unscaled_clock(m_xtal); + + output_irq(1); + output_txd(1); + output_rxc(1); + output_rts(1); + output_dtr(1); } - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - void mos6551_device::device_reset() { - m_ctrl = 0; + m_status = SR_TDRE; - switch (m_chip_type) + if (m_dsr) { - case MOS6551_TYPE_MOS: - m_cmd = CMD_RIE; - break; - - case MOS6551_TYPE_ROCKWELL: - m_cmd = 0; - break; + m_status |= SR_DSR; + } - default: - fatalerror("mos6551: unknown type %d", m_chip_type); + if (m_dcd) + { + m_status |= SR_DCD; } - transmit_register_reset(); - receive_register_reset(); + m_rx_state = STATE_START; + m_rx_counter = 0; - update_serial(); + write_command(0); + write_control(0); } -//------------------------------------------------- -// static_set_type - configuration helper to set -// the chip type -//------------------------------------------------- - -void mos6551_device::static_set_type(device_t &device, int type) +void mos6551_device::output_irq(int irq) { - mos6551_device &mos = downcast<mos6551_device &>(device); - mos.m_chip_type = type; + if (m_irq != irq) + { + m_irq = irq; + + if (m_irq) + { + m_status &= ~SR_IRQ; + } + else + { + m_status |= SR_IRQ; + } + + m_irq_handler(!m_irq); + } } -void mos6551_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +void mos6551_device::output_txd(int txd) { - device_serial_interface::device_timer(timer, id, param, ptr); -} + switch (m_tx_output) + { + case OUTPUT_MARK: + txd = 1; + break; + case OUTPUT_BREAK: + txd = 0; + break; + } -//------------------------------------------------- -// tra_callback - -//------------------------------------------------- + if (m_txd != txd) + { + m_txd = txd; + m_txd_handler(m_txd); + } +} -void mos6551_device::tra_callback() +void mos6551_device::output_rxc(int rxc) { - m_txd_handler(transmit_register_get_data_bit()); + if (m_rxc != rxc) + { + m_rxc = rxc; + m_rxc_handler(m_rxc); + } } - -//------------------------------------------------- -// tra_complete - -//------------------------------------------------- - -void mos6551_device::tra_complete() +void mos6551_device::output_rts(int rts) { - if (!(m_st & ST_TDRE)) + if (m_rts != rts) { - transmit_register_setup(m_tdr); - m_st |= ST_TDRE; - - if ((m_cmd & CMD_TC_MASK) == CMD_TC_TIE_RTS_LO) - { - m_st |= ST_IRQ; - m_irq_handler(ASSERT_LINE); - } + m_rts = rts; + m_rts_handler(m_rts); } } +void mos6551_device::output_dtr(int dtr) +{ + if (m_dtr != dtr) + { + m_dtr = dtr; + m_dtr_handler(m_dtr); + } +} -//------------------------------------------------- -// rcv_complete - -//------------------------------------------------- - -void mos6551_device::rcv_complete() +void mos6551_device::update_irq() { - if (m_st & ST_RDRF) + if (m_irq_state != 0) + { + output_irq(0); + } + else { - m_st |= ST_OR; + output_irq(1); } +} - m_st &= ~(ST_FE | ST_PE); +UINT8 mos6551_device::read_rdr() +{ + m_status &= ~(SR_PARITY_ERROR | SR_FRAMING_ERROR | SR_OVERRUN | SR_RDRF); + return m_rdr; +} + +UINT8 mos6551_device::read_status() +{ + UINT8 status = m_status; - m_st |= ST_RDRF; + if (m_cts) + { + status &= ~SR_TDRE; + } - if (!(m_cmd & CMD_RIE)) + if (m_irq_state != 0) { - m_st |= ST_IRQ; - m_irq_handler(ASSERT_LINE); + m_irq_state = 0; + update_irq(); } + + return status; } +UINT8 mos6551_device::read_command() +{ + return m_command; +} -//------------------------------------------------- -// update_serial - -//------------------------------------------------- +UINT8 mos6551_device::read_control() +{ + return m_control; +} -void mos6551_device::update_serial() +void mos6551_device::write_tdr(UINT8 data) { - int brg = m_ctrl & CTRL_BRG_MASK; + m_tdr = data; + m_status &= ~SR_TDRE; +} - int data_bits_count; - switch (m_ctrl & CTRL_WL_MASK) - { - case CTRL_WL_8: default: data_bits_count = 8; break; - case CTRL_WL_7: data_bits_count = 7; break; - case CTRL_WL_6: data_bits_count = 6; break; - case CTRL_WL_5: data_bits_count = 5; break; - } +void mos6551_device::write_reset(UINT8 data) +{ + m_status &= ~SR_OVERRUN; + m_irq_state &= ~(IRQ_DCD | IRQ_DSR); - parity_t parity = PARITY_NONE; - stop_bits_t stop_bits = STOP_BITS_1; + write_command(m_command & ~0x1f); +} - set_data_frame(1, data_bits_count, parity, stop_bits); +void mos6551_device::write_control(UINT8 data) +{ + m_control = data; - if (brg == CTRL_BRG_16X_EXTCLK) + // bits 0-3 + double scale = internal_divider[(m_control >> 0) & 0xf]; + if (scale != 0) { - set_rcv_rate(m_ext_rxc / 16); - set_tra_rate(m_ext_rxc / 16); + m_tx_internal_clock = true; + scale = (double) 1 / scale; } else { - int baud = clock() / brg_divider[brg] / 16; + m_tx_internal_clock = false; + } - set_tra_rate(baud); + m_internal_clock->set_clock_scale(scale); - if (m_ctrl & CTRL_RXC_BRG) - { - set_rcv_rate(baud); - } - else - { - set_rcv_rate(m_ext_rxc / 16); - } - } + // bit 4 + m_rx_internal_clock = (m_control >> 4) & 1; + // bits 5-6 + m_wordlength = 8 - ((m_control >> 5) & 3); - m_dtr_handler(!(m_cmd & CMD_DTR)); - m_rts_handler(!((m_cmd & CMD_TC_MASK) == CMD_TC_RTS_HI)); + // bit 7 + m_extrastop = (m_control >> 7) & 1; + + if (!m_rx_internal_clock) + { + output_rxc(1); + } } +void mos6551_device::write_command(UINT8 data) +{ + m_command = data; + + // bit 0 + output_dtr(!((m_command >> 0) & 1)); -//------------------------------------------------- -// read - -//------------------------------------------------- + // bit 1 + m_rx_irq_enable = !((m_command >> 1) & 1) && !m_dtr; + + // bits 2-3 + int transmitter_control = (m_command >> 2) & 3; + m_tx_irq_enable = transmitter_controls[transmitter_control][0] && !m_dtr; + m_tx_enable = transmitter_controls[transmitter_control][1]; + m_brk = transmitter_controls[transmitter_control][2]; + + // bit 4 + m_echo_mode = (m_command >> 4) & 1; + + // bits 5-7 + m_parity = (m_command >> 5) & 7; + if (!(m_parity & 1)) + { + m_parity = PARITY_NONE; + } + + output_rts(!(m_tx_enable || m_echo_mode)); + + if (m_dtr || m_rts) + { + m_tx_output = OUTPUT_MARK; + output_txd(1); + } +} READ8_MEMBER( mos6551_device::read ) { - UINT8 data = 0; - switch (offset & 0x03) { case 0: - if (is_receive_register_full()) - { - receive_register_extract(); - data = get_received_char(); - } - - m_st &= ~(ST_RDRF | ST_OR | ST_FE | ST_PE); - break; + return read_rdr(); case 1: - data = (m_dsr << 6) | (m_dcd << 5) | m_st; - m_st &= ~ST_IRQ; - m_irq_handler(CLEAR_LINE); - break; + return read_status(); case 2: - data = m_cmd; - break; + return read_command(); case 3: - data = m_ctrl; - break; + default: + return read_control(); } - - return data; } - -//------------------------------------------------- -// write - -//------------------------------------------------- - WRITE8_MEMBER( mos6551_device::write ) { switch (offset & 0x03) { case 0: - m_tdr = data; - m_st &= ~ST_TDRE; - - if (is_transmit_register_empty()) - { - transmit_register_setup(m_tdr); - m_st |= ST_TDRE; - - if ((m_cmd & CMD_TC_MASK) == CMD_TC_TIE_RTS_LO) - { - m_st |= ST_IRQ; - m_irq_handler(ASSERT_LINE); - } - } + write_tdr(data); break; case 1: - // programmed reset - m_cmd = (m_cmd & 0xe0); - if (m_chip_type == MOS6551_TYPE_MOS) - { - m_cmd |= CMD_RIE; - } - m_st &= ~ST_OR; - update_serial(); + write_reset(data); break; case 2: - m_cmd = data; - update_serial(); + write_command(data); break; case 3: - m_ctrl = data; - update_serial(); + write_control(data); break; } } - -//------------------------------------------------- -// set_rxc - set external receiver clock -//------------------------------------------------- - -void mos6551_device::set_rxc(int clock) +int mos6551_device::stoplength() { - m_ext_rxc = clock; + if (m_extrastop == 1) + { + if (m_wordlength == 5 && m_parity == PARITY_NONE) + { + return m_divide + (m_divide / 2); + } - update_serial(); + if (m_wordlength < 8 || m_parity == PARITY_NONE) + { + return m_divide * 2; + } + } + + return m_divide; } +void mos6551_device::set_xtal(UINT32 xtal) +{ + m_xtal = xtal; -//------------------------------------------------- -// rxd_w - receive data write -//------------------------------------------------- + if (started()) + { + m_internal_clock->set_unscaled_clock(m_xtal); + } +} -WRITE_LINE_MEMBER( mos6551_device::rxd_w ) +WRITE_LINE_MEMBER( mos6551_device::internal_clock ) { - device_serial_interface::rx_w(state); + if (m_tx_internal_clock) + { + transmitter_clock(state); + } } - -//------------------------------------------------- -// rxc_w - receive clock write -//------------------------------------------------- - -WRITE_LINE_MEMBER( mos6551_device::rxc_w ) +WRITE_LINE_MEMBER(mos6551_device::write_xtal1) { - rx_clock_w(state); - tx_clock_w(state); + if (!m_tx_internal_clock) + { + transmitter_clock(state); + } } +WRITE_LINE_MEMBER( mos6551_device::write_rxd ) +{ + m_rxd = state; +} -//------------------------------------------------- -// cts_w - clear to send write -//------------------------------------------------- - -WRITE_LINE_MEMBER( mos6551_device::cts_w ) +WRITE_LINE_MEMBER( mos6551_device::write_rxc ) { - m_cts = state; + if (!m_rx_internal_clock) + { + receiver_clock(state); + } } +WRITE_LINE_MEMBER( mos6551_device::write_cts ) +{ + if (m_cts != state) + { + m_cts = state; -//------------------------------------------------- -// dsr_w - data set ready write -//------------------------------------------------- + if (m_cts) + { + if (m_tx_output == OUTPUT_TXD) + { + m_tx_output = OUTPUT_MARK; + output_txd(1); + } + } + } +} -WRITE_LINE_MEMBER( mos6551_device::dsr_w ) +WRITE_LINE_MEMBER( mos6551_device::write_dsr ) { if (m_dsr != state) { - m_st |= ST_IRQ; - m_irq_handler(ASSERT_LINE); + m_dsr = state; } +} - m_dsr = state; +WRITE_LINE_MEMBER( mos6551_device::write_dcd ) +{ + if (m_dcd != state) + { + m_dcd = state; + } } +WRITE_LINE_MEMBER(mos6551_device::receiver_clock) +{ + if (m_rx_clock != state) + { + m_rx_clock = state; -//------------------------------------------------- -// dcd_w - data carrier detect write -//------------------------------------------------- + if (m_rx_clock) + { + /// TODO: find out whether this should be here or in write_dcd + if ((m_irq_state & IRQ_DCD) == 0 && !m_dcd != !(m_status & SR_DCD)) + { + m_status ^= SR_DCD; -WRITE_LINE_MEMBER( mos6551_device::dcd_w ) + if (!m_dtr) + { + m_irq_state |= IRQ_DCD; + update_irq(); + } + } + + /// TODO: find out whether this should be here or in write_dsr + if ((m_irq_state & IRQ_DSR) == 0 && !m_dsr != !(m_status & SR_DSR)) + { + m_status ^= SR_DSR; + + if (!m_dtr) + { + m_irq_state |= IRQ_DSR; + update_irq(); + } + } + + m_rx_counter++; + + switch (m_rx_state) + { + case STATE_START: + if (m_rx_counter == 1) + { + if (!m_rxd && !m_dtr) + { + if (LOG) logerror("MOS6551 '%s': RX START BIT\n", tag()); + } + else + { + m_rx_counter = 0; + } + } + + if (m_rx_counter >= m_divide / 2) + { + if (!m_rxd) + { + m_rx_state = STATE_DATA; + m_rx_counter = 0; + m_rx_shift = 0; + m_rx_parity = 0; + m_rx_bits = 0; + } + else + { + m_rx_counter = 0; + + if (LOG) logerror("MOS6551 '%s': RX FALSE START BIT\n", tag()); + } + } + break; + + case STATE_DATA: + if (m_rx_counter == m_divide) + { + m_rx_counter = 0; + + if (m_rx_bits < m_wordlength) + { + if (LOG) logerror("MOS6551 '%s': RX DATA BIT %d %d\n", tag(), m_rx_bits, m_rxd); + } + else + { + if (LOG) logerror("MOS6551 '%s': RX PARITY BIT %x\n", tag(), m_rxd); + } + + if (m_rxd) + { + m_rx_shift |= 1 << m_rx_bits; + } + + m_rx_bits++; + + m_rx_parity ^= m_rxd; + + if ((m_rx_bits == m_wordlength && m_parity == PARITY_NONE) || + (m_rx_bits == (m_wordlength + 1) && m_parity == PARITY_NONE)) + { + m_rx_state = STATE_STOP; + } + } + break; + + case STATE_STOP: + if (m_rx_counter >= stoplength()) + { + m_rx_counter = 0; + + if (LOG) logerror("MOS6551 '%s': RX STOP BIT\n", tag()); + + if (!(m_status & SR_RDRF)) + { + if (!m_rxd) + { + m_status |= SR_FRAMING_ERROR; + } + + if ((m_parity == PARITY_ODD && !m_rx_parity) || + (m_parity == PARITY_EVEN && m_rx_parity)) + { + m_status |= SR_PARITY_ERROR; + } + + m_rdr = m_rx_shift; + + if (m_wordlength == 7 && m_parity != PARITY_NONE) + { + m_rdr &= 0x7f; + } + + m_status |= SR_RDRF; + } + else + { + m_status |= SR_OVERRUN; + } + + if (m_rx_irq_enable) + { + m_irq_state |= IRQ_RDRF; + update_irq(); + } + + m_rx_state = STATE_START; + } + break; + } + } + } +} + +WRITE_LINE_MEMBER(mos6551_device::transmitter_clock) { - if (m_dcd != state) + if (m_rx_internal_clock) { - m_st |= ST_IRQ; - m_irq_handler(ASSERT_LINE); + output_rxc(state); + receiver_clock(state); } - m_dcd = state; + if (m_tx_clock != state) + { + m_tx_clock = state; + + if (!m_tx_clock && !m_dtr) + { + if (m_echo_mode) + { + if (!(m_status & SR_OVERRUN)) + { + output_txd(m_rxd); + } + else + { + output_txd(1); + } + } + + if (m_tx_enable) + { + if (!m_cts && m_tx_output == OUTPUT_MARK && !(m_status & SR_TDRE)) + { + m_tx_state = STATE_START; + m_tx_counter = 0; + } + + m_tx_counter++; + + switch (m_tx_state) + { + case STATE_START: + m_tx_counter = 0; + + m_tx_state = STATE_DATA; + m_tx_shift = m_tdr; + m_tx_bits = 0; + m_tx_parity = 0; + + if (m_cts) + { + m_tx_output = OUTPUT_MARK; + } + else if (!(m_status & SR_TDRE)) + { + if (LOG) logerror("MOS6551 '%s': TX DATA %x\n", tag(), m_tdr); + + m_tx_output = OUTPUT_TXD; + + if (LOG) logerror("MOS6551 '%s': TX START BIT\n", tag()); + + m_status |= SR_TDRE; + } + else if (m_brk) + { + m_tx_output = OUTPUT_BREAK; + + if (LOG) logerror("MOS6551 '%s': TX BREAK START\n", tag()); + } + else + { + m_tx_output = OUTPUT_MARK; + } + + if (m_tx_irq_enable && m_tx_output != OUTPUT_BREAK) + { + m_irq_state |= IRQ_TDRE; + update_irq(); + } + + output_txd(0); + break; + + case STATE_DATA: + if (m_tx_counter == m_divide) + { + m_tx_counter = 0; + + if (m_tx_bits < m_wordlength) + { + output_txd((m_tx_shift >> m_tx_bits) & 1); + + m_tx_bits++; + m_tx_parity ^= m_txd; + + if (m_tx_output == OUTPUT_TXD) + { + if (LOG) logerror("MOS6551 '%s': TX DATA BIT %d %d\n", tag(), m_tx_bits, m_txd); + } + } + else if (m_tx_bits == m_wordlength && m_parity != PARITY_NONE) + { + m_tx_bits++; + + switch (m_parity) + { + case PARITY_ODD: + m_tx_parity = !m_tx_parity; + break; + + case PARITY_MARK: + m_tx_parity = 1; + break; + + case PARITY_SPACE: + m_tx_parity = 0; + break; + } + + output_txd(m_tx_parity); + + if (m_tx_output == OUTPUT_TXD) + { + if (LOG) logerror("MOS6551 '%s': TX PARITY BIT %d\n", tag(), m_txd); + } + } + else + { + m_tx_state = STATE_STOP; + + output_txd(1); + + if (m_tx_output == OUTPUT_TXD) + { + if (LOG) logerror("MOS6551 '%s': TX STOP BIT\n", tag()); + } + } + } + break; + + case STATE_STOP: + if (m_tx_counter >= stoplength()) + { + if (m_tx_output == OUTPUT_BREAK) + { + if (!m_brk) + { + if (LOG) logerror("MOS6551 '%s': TX BREAK END\n", tag()); + + m_tx_counter = 0; + m_tx_state = STATE_STOP; + m_tx_output = OUTPUT_TXD; + + output_txd(1); + } + else + { + m_tx_counter--; + } + } + else + { + m_tx_state = STATE_START; + m_tx_counter = 0; + } + } + break; + } + } + } + } } |