diff --git a/src/devices/machine/6522via.cpp b/src/devices/machine/6522via.cpp index 1b1d0ea0766..d4a2de29f5c 100644 --- a/src/devices/machine/6522via.cpp +++ b/src/devices/machine/6522via.cpp @@ -535,7 +535,14 @@ TIMER_CALLBACK_MEMBER(via6522_device::t1_tick) if (T1_CONTINUOUS (m_acr)) { m_t1_pb7 = !m_t1_pb7; - m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY)); + if (TIMER1_VALUE > 0) + { + m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY)); + } + else + { + m_t1_active = 0; + } } else { @@ -934,8 +941,15 @@ void via6522_device::write(offs_t offset, u8 data) output_pb(); } - m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY)); - m_t1_active = 1; + if (TIMER1_VALUE > 0) + { + m_t1->adjust(clocks_to_attotime(TIMER1_VALUE + IFR_DELAY)); + m_t1_active = 1; + } + else + { + m_t1_active = 0; + } break; case VIA_T2CL: diff --git a/src/devices/machine/m68sfdc.cpp b/src/devices/machine/m68sfdc.cpp index f235f25bfd5..ced33a54510 100644 --- a/src/devices/machine/m68sfdc.cpp +++ b/src/devices/machine/m68sfdc.cpp @@ -842,6 +842,7 @@ void m68sfdc_device::device_add_mconfig(machine_config &config) m_pia->irqb_handler().set(FUNC(m68sfdc_device::handle_irq)); MC6852(config, m_ssda, 0); + m_ssda->set_tx_pull_mode(true); } DEFINE_DEVICE_TYPE(M68SFDC, m68sfdc_device, "m68sfdc", "M68SFDC") diff --git a/src/devices/machine/mc6852.cpp b/src/devices/machine/mc6852.cpp index af74f26516c..e54d5d3d4bf 100644 --- a/src/devices/machine/mc6852.cpp +++ b/src/devices/machine/mc6852.cpp @@ -51,6 +51,8 @@ mc6852_device::mc6852_device(const machine_config &mconfig, const char *tag, dev m_write_irq(*this), m_write_sm_dtr(*this), m_write_tuf(*this), + m_tx_pull_mode(false), + m_tx_active(false), m_rx_clock(0), m_tx_clock(0), m_cts(1), @@ -84,6 +86,8 @@ void mc6852_device::device_start() save_item(NAME(m_sm_dtr)); save_item(NAME(m_tuf)); save_item(NAME(m_in_sync)); + save_item(NAME(m_tx_active)); + save_item(NAME(m_tx_pull_mode)); } @@ -125,7 +129,39 @@ void mc6852_device::tra_callback() void mc6852_device::tra_complete() { - // TODO + int trigger = (m_cr[1] & C2_1_2_BYTE) ? 1 : 2; + int available = 3 - m_tx_fifo.size(); + uint8_t byte_to_send; + + if (available < 3) + { + // FIFO not empty - send the next byte. + byte_to_send = m_tx_fifo.front(); + m_tx_fifo.pop(); + available++; + } + else + { + // TX underflow + if (m_cr[1] & C2_TX_SYNC) + { + m_status |= S_TUF; + byte_to_send = m_scr; // Send Sync Code + + // TODO assert TUF pin for "approximately one Tx CLK high period" + } + else + { + byte_to_send = 0xff; // Send a "Mark" + } + } + + transmit_register_setup(byte_to_send); + + if (available >= trigger) + { + m_status |= S_TDRA; + } } //------------------------------------------------- @@ -234,7 +270,7 @@ uint8_t mc6852_device::read(offs_t offset) // TODO this might not be quite right, the datasheet // states that the RX overrun flag is cleared by // reading the status, and the RX data fifo? - m_status &= S_RX_OVRN; + m_status &= ~S_RX_OVRN; } } @@ -311,9 +347,9 @@ void mc6852_device::write(offs_t offset, uint8_t data) int data_bit_count = 0; parity_t parity = PARITY_NONE; - stop_bits_t stop_bits = STOP_BITS_1; + stop_bits_t stop_bits = STOP_BITS_0; - switch (data & C2_WS_MASK) + switch ((data & C2_WS_MASK) >> C2_WS_SHIFT) { case 0: data_bit_count = 6; parity = PARITY_EVEN; break; case 1: data_bit_count = 6; parity = PARITY_ODD; break; @@ -325,7 +361,7 @@ void mc6852_device::write(offs_t offset, uint8_t data) case 7: data_bit_count = 8; parity = PARITY_ODD; break; } - set_data_frame(1, data_bit_count, parity, stop_bits); + set_data_frame(0, data_bit_count, parity, stop_bits); // The fifo trigger levels may have changed, so update // the status bits. @@ -374,8 +410,17 @@ void mc6852_device::write(offs_t offset, uint8_t data) if (available > 0) { LOG("MC6852 Transmit FIFO %02x\n", data); - m_tx_fifo.push(data); - available--; + if (!m_tx_pull_mode && !m_tx_active) { + // transfer is idle: this emulates moving the first byte + // into the shift register, and kicking off transmission. + // tra_complete() will be called when the byte has been + // sent. + m_tx_active = true; + transmit_register_setup(data); + } else { + m_tx_fifo.push(data); + available--; + } } else { @@ -426,6 +471,7 @@ void mc6852_device::write(offs_t offset, uint8_t data) m_status &= ~(S_TUF | S_CTS); m_status |= S_TDRA; m_tx_fifo = std::queue(); + m_tx_active = false; transmit_register_reset(); } diff --git a/src/devices/machine/mc6852.h b/src/devices/machine/mc6852.h index 3092ba2374c..c7862be4d1e 100644 --- a/src/devices/machine/mc6852.h +++ b/src/devices/machine/mc6852.h @@ -47,6 +47,8 @@ public: void set_rx_clock(int clock) { m_rx_clock = clock; } void set_tx_clock(int clock) { m_tx_clock = clock; } + void set_tx_pull_mode(bool tx_pull_mode) { m_tx_pull_mode = tx_pull_mode; } + auto tx_data_callback() { return m_write_tx_data.bind(); } auto irq_callback() { return m_write_irq.bind(); } auto sm_dtr_callback() { return m_write_sm_dtr.bind(); } @@ -120,7 +122,8 @@ private: C2_1_2_BYTE = 0x04, C2_PC_MASK = 0x03, C2_PC2 = 0x02, - C2_PC1 = 0x01 + C2_PC1 = 0x01, + C2_WS_SHIFT = 3 }; enum @@ -147,6 +150,13 @@ private: std::queue m_rx_fifo; std::queue m_tx_fifo; + // If m_tx_pull_mode is true, get_tx_byte() must be called to retrieve + // the next byte to transmit, and the actual transmission must be + // carried out by some external mechanism. + bool m_tx_pull_mode; + + bool m_tx_active; + int m_rx_clock; int m_tx_clock; int m_cts; // clear to send diff --git a/src/mame/act/victor9k.cpp b/src/mame/act/victor9k.cpp index 235e70c46db..ed6e97f86d1 100644 --- a/src/mame/act/victor9k.cpp +++ b/src/mame/act/victor9k.cpp @@ -34,10 +34,12 @@ #include "machine/pit8253.h" #include "machine/pic8259.h" #include "machine/ram.h" +#include "machine/rescap.h" #include "victor9k_kb.h" #include "victor9k_fdc.h" #include "machine/z80sio.h" #include "sound/hc55516.h" +#include "sound/flt_biquad.h" #include "video/mc6845.h" #include "emupal.h" #include "screen.h" @@ -104,6 +106,8 @@ public: m_cvsd(*this, HC55516_TAG), m_crtc(*this, HD46505S_TAG), m_ram(*this, RAM_TAG), + m_cvsd_filter(*this, "cvsd_filter"), + m_cvsd_filter2(*this, "cvsd_filter2"), m_kb(*this, KB_TAG), m_fdc(*this, "fdc"), m_centronics(*this, "centronics"), @@ -138,6 +142,8 @@ private: required_device m_cvsd; required_device m_crtc; required_device m_ram; + optional_device m_cvsd_filter; + optional_device m_cvsd_filter2; required_device m_kb; required_device m_fdc; required_device m_centronics; @@ -391,7 +397,12 @@ void victor9k_state::ssda_sm_dtr_w(int state) { m_ssda->cts_w(state); m_ssda->dcd_w(!state); - //m_cvsd->enc_dec_w(!state); + + /* ___ + * We're supposed to set the ENC/DEC input of the HC55516 to !state, + * but only playback/decode is currently supported, and that input + * is not implemenented. + */ } @@ -733,10 +744,12 @@ void victor9k_state::victor9k(machine_config &config) m_crtc->set_begin_update_callback(FUNC(victor9k_state::crtc_begin_update)); // sound hardware + FILTER_BIQUAD(config, m_cvsd_filter2).opamp_mfb_lowpass_setup(RES_K(27), RES_K(15), RES_K(27), CAP_P(4700), CAP_P(1200)); + FILTER_BIQUAD(config, m_cvsd_filter).opamp_mfb_lowpass_setup(RES_K(43), RES_K(36), RES_K(180), CAP_P(1800), CAP_P(180)); + HC55516(config, m_cvsd, 0).add_route(ALL_OUTPUTS, m_cvsd_filter, 1.0); + m_cvsd_filter->add_route(ALL_OUTPUTS, m_cvsd_filter2, 1.0); + m_cvsd_filter2->add_route(ALL_OUTPUTS, "mono", 0.25); SPEAKER(config, "mono").front_center(); - HC55516(config, m_cvsd, 0); - //MCFG_HC55516_DIG_OUT_CB(WRITELINE(MC6852_TAG, mc6852_device, rx_w)) - m_cvsd->add_route(ALL_OUTPUTS, "mono", 0.25); // devices IEEE488(config, m_ieee488, 0); @@ -853,4 +866,4 @@ ROM_END //************************************************************************** // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1982, victor9k, 0, 0, victor9k, victor9k, victor9k_state, empty_init, "Victor Business Products", "Victor 9000", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +COMP( 1982, victor9k, 0, 0, victor9k, victor9k, victor9k_state, empty_init, "Victor Business Products", "Victor 9000", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE )