/* Sound and cassette port use a common pin. Therefore the signal to cassette will appear on audio output. Sound port is a simple one bit I/O and therefore it must be toggled at a specific rate under software control. */ static WRITE8_HANDLER( cassette_w ) { device_t *speaker = space->machine().device("speaker"); device_t *cassette = space->machine().device("cassette"); speaker_level_w(speaker, BIT(data, 0)); cassette_output(cassette, BIT(data, 0) ? +1.0 : -1.0); }
/* The cassette output signal for writing tapes is generated by a flip-flop which is toggled to produce the output waveform. Any access to the cassette I/O range, whether a read or a write, toggles this flip-flop. */ static void cassette_toggle_output(void) { static int cassette_output_flipflop = 0; cassette_output_flipflop = !cassette_output_flipflop; cassette_output(cassette_device_image(), cassette_output_flipflop ? 1.0 : -1.0); }
static WRITE8_HANDLER ( lviv_ppi_0_portc_w ) /* tape in/out, video memory on/off */ { lviv_ppi_port_outputs[0][2] = data; if (lviv_ppi_port_outputs[0][1]&0x80) speaker_level_w(0, data&0x01); cassette_output(image_from_devtype_and_index(IO_CASSETTE, 0), (data & 0x01) ? -1.0 : 1.0); lviv_update_memory(); }
static TIMER_CALLBACK(poly88_cassette_timer_callback) { poly88_state *state = machine.driver_data<poly88_state>(); int data; int current_level; // if (!(input_port_read(machine, "DSW0") & 0x02)) /* V.24 / Tape Switch */ //{ /* tape reading */ if (cassette_get_state(machine.device("cassette"))&CASSETTE_PLAY) { if (state->m_clk_level_tape) { state->m_previous_level = (cassette_input(machine.device("cassette")) > 0.038) ? 1 : 0; state->m_clk_level_tape = 0; } else { current_level = (cassette_input(machine.device("cassette")) > 0.038) ? 1 : 0; if (state->m_previous_level!=current_level) { data = (!state->m_previous_level && current_level) ? 1 : 0; //data = current_level; set_out_data_bit(state->m_cassette_serial_connection.State, data); serial_connection_out(machine, &state->m_cassette_serial_connection); msm8251_receive_clock(machine.device("uart")); state->m_clk_level_tape = 1; } } } /* tape writing */ if (cassette_get_state(machine.device("cassette"))&CASSETTE_RECORD) { data = get_in_data_bit(state->m_cassette_serial_connection.input_state); data ^= state->m_clk_level_tape; cassette_output(machine.device("cassette"), data&0x01 ? 1 : -1); if (!state->m_clk_level_tape) msm8251_transmit_clock(machine.device("uart")); state->m_clk_level_tape = state->m_clk_level_tape ? 0 : 1; return; } state->m_clk_level_tape = 1; if (!state->m_clk_level) msm8251_transmit_clock(machine.device("uart")); state->m_clk_level = state->m_clk_level ? 0 : 1; // } }
static WRITE8_DEVICE_HANDLER (ac1_port_b_w) { /* bit description 0 1 RTTY receive 2 RTTY transmit 3 RTTY PTT 4 5 6 cassette out 7 cassette in */ ac1_state *state = device->machine().driver_data<ac1_state>(); cassette_output(state->m_cassette, (data & 0x40) ? -1.0 : +1.0); }
// identical to sorcerer static TIMER_CALLBACK(sol20_cassette_tc) { sol20_state *state = machine.driver_data<sol20_state>(); UINT8 cass_ws = 0; switch (state->m_sol20_fa & 0x20) { case 0x20: /* Cassette 300 baud */ /* loading a tape - this is basically the same as the super80. We convert the 1200/2400 Hz signal to a 0 or 1, and send it to the uart. */ state->m_cass_data.input.length++; cass_ws = (cassette_input(cassette_device_image(machine)) > +0.02) ? 1 : 0; if (cass_ws != state->m_cass_data.input.level) { state->m_cass_data.input.level = cass_ws; state->m_cass_data.input.bit = ((state->m_cass_data.input.length < 0x6) || (state->m_cass_data.input.length > 0x20)) ? 1 : 0; state->m_cass_data.input.length = 0; ay31015_set_input_pin( state->m_uart, AY31015_SI, state->m_cass_data.input.bit ); } /* saving a tape - convert the serial stream from the uart, into 1200 and 2400 Hz frequencies. Synchronisation of the frequency pulses to the uart is extremely important. */ state->m_cass_data.output.length++; if (!(state->m_cass_data.output.length & 0x1f)) { cass_ws = ay31015_get_output_pin( state->m_uart, AY31015_SO ); if (cass_ws != state->m_cass_data.output.bit) { state->m_cass_data.output.bit = cass_ws; state->m_cass_data.output.length = 0; } } if (!(state->m_cass_data.output.length & 3)) { if (!((state->m_cass_data.output.bit == 0) && (state->m_cass_data.output.length & 4))) { state->m_cass_data.output.level ^= 1; // toggle output state, except on 2nd half of low bit cassette_output(cassette_device_image(machine), state->m_cass_data.output.level ? -1.0 : +1.0); } } return; case 0x00: /* Cassette 1200 baud */ /* loading a tape */ state->m_cass_data.input.length++; cass_ws = (cassette_input(cassette_device_image(machine)) > +0.02) ? 1 : 0; if (cass_ws != state->m_cass_data.input.level || state->m_cass_data.input.length == 10) { state->m_cass_data.input.bit = ((state->m_cass_data.input.length < 10) || (state->m_cass_data.input.length > 0x20)) ? 1 : 0; if ( cass_ws != state->m_cass_data.input.level ) { state->m_cass_data.input.length = 0; state->m_cass_data.input.level = cass_ws; } ay31015_set_input_pin( state->m_uart, AY31015_SI, state->m_cass_data.input.bit ); } /* saving a tape - convert the serial stream from the uart, into 600 and 1200 Hz frequencies. */ state->m_cass_data.output.length++; if (!(state->m_cass_data.output.length & 7)) { cass_ws = ay31015_get_output_pin( state->m_uart, AY31015_SO ); if (cass_ws != state->m_cass_data.output.bit) { state->m_cass_data.output.bit = cass_ws; state->m_cass_data.output.length = 0; } } if (!(state->m_cass_data.output.length & 7)) { if (!((state->m_cass_data.output.bit == 0) && (state->m_cass_data.output.length & 8))) { state->m_cass_data.output.level ^= 1; // toggle output state, except on 2nd half of low bit cassette_output(cassette_device_image(machine), state->m_cass_data.output.level ? -1.0 : +1.0); } } return; } }
static WRITE_LINE_DEVICE_HANDLER( cassette_w ) { cassette_output(device, state ? -1.0 : +1.0); }