Skip to content

Commit dd1591e

Browse files
committed
mos6551: Do not disable the transmitter when a command deasserts RTS
1 parent d1f600c commit dd1591e

File tree

2 files changed

+104
-109
lines changed

2 files changed

+104
-109
lines changed

src/devices/machine/mos6551.cpp

Lines changed: 104 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ mos6551_device::mos6551_device(const machine_config &mconfig, const char *tag, d
4545
m_tx_state(STATE_START),
4646
m_tx_output(OUTPUT_MARK),
4747
m_tx_clock(0), m_tx_bits(0), m_tx_shift(0), m_tx_parity(0),
48-
m_tx_counter(0), m_tx_enable(0), m_tx_irq_enable(0), m_tx_internal_clock(0)
48+
m_tx_counter(0), m_tx_irq_enable(0), m_tx_internal_clock(0)
4949
{
5050
}
5151

@@ -56,7 +56,7 @@ const int mos6551_device::internal_divider[] =
5656

5757
const int mos6551_device::transmitter_controls[4][3] =
5858
{
59-
//tx irq, tx ena, brk
59+
//tx irq, rts, brk
6060
{0, 0, 0},
6161
{1, 1, 0},
6262
{0, 1, 0},
@@ -125,7 +125,6 @@ void mos6551_device::device_start()
125125
save_item(NAME(m_tx_shift));
126126
save_item(NAME(m_tx_parity));
127127
save_item(NAME(m_tx_counter));
128-
save_item(NAME(m_tx_enable));
129128
save_item(NAME(m_tx_irq_enable));
130129
save_item(NAME(m_tx_internal_clock));
131130

@@ -362,7 +361,7 @@ void mos6551_device::write_command(uint8_t data)
362361
// bits 2-3
363362
int transmitter_control = (m_command >> 2) & 3;
364363
m_tx_irq_enable = transmitter_controls[transmitter_control][0] && !m_dtr;
365-
m_tx_enable = transmitter_controls[transmitter_control][1];
364+
bool rts_active = transmitter_controls[transmitter_control][1];
366365
m_brk = transmitter_controls[transmitter_control][2];
367366
if (!m_tx_irq_enable && (m_irq_state & IRQ_TDRE))
368367
{
@@ -380,9 +379,9 @@ void mos6551_device::write_command(uint8_t data)
380379
m_parity = PARITY_NONE;
381380
}
382381

383-
output_rts(!(m_tx_enable || m_echo_mode));
382+
output_rts(!(rts_active || m_echo_mode));
384383

385-
if (m_dtr || m_rts)
384+
if (m_dtr)
386385
{
387386
m_tx_output = OUTPUT_MARK;
388387
output_txd(1);
@@ -713,145 +712,142 @@ void mos6551_device::transmitter_clock(int state)
713712
}
714713
}
715714

716-
if (m_tx_enable)
715+
if (!m_cts && m_tx_output == OUTPUT_MARK && !(m_status & SR_TDRE))
717716
{
718-
if (!m_cts && m_tx_output == OUTPUT_MARK && !(m_status & SR_TDRE))
717+
m_tx_state = STATE_START;
718+
m_tx_counter = 0;
719+
}
720+
721+
m_tx_counter++;
722+
723+
switch (m_tx_state)
724+
{
725+
case STATE_START:
726+
m_tx_counter = 0;
727+
728+
m_tx_state = STATE_DATA;
729+
m_tx_shift = m_tdr;
730+
m_tx_bits = 0;
731+
m_tx_parity = 0;
732+
733+
if (m_cts)
719734
{
720-
m_tx_state = STATE_START;
721-
m_tx_counter = 0;
735+
m_tx_output = OUTPUT_MARK;
722736
}
737+
else if (!(m_status & SR_TDRE))
738+
{
739+
LOG("MOS6551: TX DATA %x\n", m_tdr);
723740

724-
m_tx_counter++;
741+
m_tx_output = OUTPUT_TXD;
725742

726-
switch (m_tx_state)
743+
LOG("MOS6551: TX START BIT\n");
744+
745+
m_status |= SR_TDRE;
746+
}
747+
else if (m_brk)
727748
{
728-
case STATE_START:
729-
m_tx_counter = 0;
749+
m_tx_output = OUTPUT_BREAK;
730750

731-
m_tx_state = STATE_DATA;
732-
m_tx_shift = m_tdr;
733-
m_tx_bits = 0;
734-
m_tx_parity = 0;
751+
LOG("MOS6551: TX BREAK START\n");
752+
}
753+
else
754+
{
755+
m_tx_output = OUTPUT_MARK;
756+
}
735757

736-
if (m_cts)
737-
{
738-
m_tx_output = OUTPUT_MARK;
739-
}
740-
else if (!(m_status & SR_TDRE))
741-
{
742-
LOG("MOS6551: TX DATA %x\n", m_tdr);
758+
if (m_tx_irq_enable && m_tx_output != OUTPUT_BREAK)
759+
{
760+
m_irq_state |= IRQ_TDRE;
761+
update_irq();
762+
}
743763

744-
m_tx_output = OUTPUT_TXD;
764+
output_txd(0);
765+
break;
745766

746-
LOG("MOS6551: TX START BIT\n");
767+
case STATE_DATA:
768+
if (m_tx_counter == m_divide)
769+
{
770+
m_tx_counter = 0;
747771

748-
m_status |= SR_TDRE;
749-
}
750-
else if (m_brk)
772+
if (m_tx_bits < m_wordlength)
751773
{
752-
m_tx_output = OUTPUT_BREAK;
774+
output_txd((m_tx_shift >> m_tx_bits) & 1);
753775

754-
LOG("MOS6551: TX BREAK START\n");
755-
}
756-
else
757-
{
758-
m_tx_output = OUTPUT_MARK;
759-
}
776+
m_tx_bits++;
777+
m_tx_parity ^= m_txd;
760778

761-
if (m_tx_irq_enable && m_tx_output != OUTPUT_BREAK)
762-
{
763-
m_irq_state |= IRQ_TDRE;
764-
update_irq();
779+
if (m_tx_output == OUTPUT_TXD)
780+
{
781+
LOG("MOS6551: TX DATA BIT %d %d\n", m_tx_bits, m_txd);
782+
}
765783
}
766-
767-
output_txd(0);
768-
break;
769-
770-
case STATE_DATA:
771-
if (m_tx_counter == m_divide)
784+
else if (m_tx_bits == m_wordlength && m_parity != PARITY_NONE)
772785
{
773-
m_tx_counter = 0;
786+
m_tx_bits++;
774787

775-
if (m_tx_bits < m_wordlength)
788+
switch (m_parity)
776789
{
777-
output_txd((m_tx_shift >> m_tx_bits) & 1);
790+
case PARITY_ODD:
791+
m_tx_parity = !m_tx_parity;
792+
break;
778793

779-
m_tx_bits++;
780-
m_tx_parity ^= m_txd;
794+
case PARITY_MARK:
795+
m_tx_parity = 1;
796+
break;
781797

782-
if (m_tx_output == OUTPUT_TXD)
783-
{
784-
LOG("MOS6551: TX DATA BIT %d %d\n", m_tx_bits, m_txd);
785-
}
798+
case PARITY_SPACE:
799+
m_tx_parity = 0;
800+
break;
786801
}
787-
else if (m_tx_bits == m_wordlength && m_parity != PARITY_NONE)
788-
{
789-
m_tx_bits++;
790-
791-
switch (m_parity)
792-
{
793-
case PARITY_ODD:
794-
m_tx_parity = !m_tx_parity;
795-
break;
796-
797-
case PARITY_MARK:
798-
m_tx_parity = 1;
799-
break;
800-
801-
case PARITY_SPACE:
802-
m_tx_parity = 0;
803-
break;
804-
}
805802

806-
output_txd(m_tx_parity);
803+
output_txd(m_tx_parity);
807804

808-
if (m_tx_output == OUTPUT_TXD)
809-
{
810-
LOG("MOS6551: TX PARITY BIT %d\n", m_txd);
811-
}
812-
}
813-
else
805+
if (m_tx_output == OUTPUT_TXD)
814806
{
815-
m_tx_state = STATE_STOP;
807+
LOG("MOS6551: TX PARITY BIT %d\n", m_txd);
808+
}
809+
}
810+
else
811+
{
812+
m_tx_state = STATE_STOP;
816813

817-
output_txd(1);
814+
output_txd(1);
818815

819-
if (m_tx_output == OUTPUT_TXD)
820-
{
821-
LOG("MOS6551: TX STOP BIT\n");
822-
}
816+
if (m_tx_output == OUTPUT_TXD)
817+
{
818+
LOG("MOS6551: TX STOP BIT\n");
823819
}
824820
}
825-
break;
821+
}
822+
break;
826823

827-
case STATE_STOP:
828-
if (m_tx_counter >= stoplength())
824+
case STATE_STOP:
825+
if (m_tx_counter >= stoplength())
826+
{
827+
if (m_tx_output == OUTPUT_BREAK)
829828
{
830-
if (m_tx_output == OUTPUT_BREAK)
829+
if (!m_brk)
831830
{
832-
if (!m_brk)
833-
{
834-
LOG("MOS6551: TX BREAK END\n");
835-
836-
m_tx_counter = 0;
837-
m_tx_state = STATE_STOP;
838-
m_tx_output = OUTPUT_TXD;
839-
840-
output_txd(1);
841-
}
842-
else
843-
{
844-
m_tx_counter--;
845-
}
831+
LOG("MOS6551: TX BREAK END\n");
832+
833+
m_tx_counter = 0;
834+
m_tx_state = STATE_STOP;
835+
m_tx_output = OUTPUT_TXD;
836+
837+
output_txd(1);
846838
}
847839
else
848840
{
849-
m_tx_state = STATE_START;
850-
m_tx_counter = 0;
841+
m_tx_counter--;
851842
}
852843
}
853-
break;
844+
else
845+
{
846+
m_tx_state = STATE_START;
847+
m_tx_counter = 0;
848+
}
854849
}
850+
break;
855851
}
856852
}
857853
}

src/devices/machine/mos6551.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ class mos6551_device : public device_t
185185
int m_tx_shift;
186186
int m_tx_parity;
187187
int m_tx_counter;
188-
int m_tx_enable;
189188
int m_tx_irq_enable;
190189
int m_tx_internal_clock;
191190
};

0 commit comments

Comments
 (0)