static int tzx_handle_direct(int16_t **buffer, const uint8_t *bytes, int pause, int data_size, int tstates, int bits_in_last_byte) { int size = 0; int samples = tcycles_to_samplecount(tstates); /* data */ for (int data_index = 0; data_index < data_size; data_index++) { uint8_t byte = bytes[data_index]; int bits_to_go = (data_index == (data_size - 1)) ? bits_in_last_byte : 8; for ( ; bits_to_go > 0; byte <<= 1, bits_to_go--) { if (byte & 0x80) wave_data = WAVE_HIGH; else wave_data = WAVE_LOW; tzx_output_wave(buffer, samples); size += samples; } } /* pause */ if (pause > 0) { int start_pause_samples = millisec_to_samplecount(1); int rest_pause_samples = millisec_to_samplecount(pause - 1); tzx_output_wave(buffer, start_pause_samples); size += start_pause_samples; wave_data = WAVE_LOW; tzx_output_wave(buffer, rest_pause_samples); size += rest_pause_samples; } return size; }
static int tzx_cas_handle_block( INT16 **buffer, const UINT8 *bytes, int pause, int data_size, int pilot, int pilot_length, int sync1, int sync2, int bit0, int bit1, int bits_in_last_byte ) { int pilot_samples = tcycles_to_samplecount( pilot ); int sync1_samples = tcycles_to_samplecount( sync1 ); int sync2_samples = tcycles_to_samplecount( sync2 ); int bit0_samples = tcycles_to_samplecount( bit0 ); int bit1_samples = tcycles_to_samplecount( bit1 ); int data_index; int size = 0; logerror( "tzx_cas_block_size: pliot_length = %d, pilot_samples = %d, sync1_samples = %d, sync2_samples = %d, bit0_samples = %d, bit1_samples = %d\n", pilot_length, pilot_samples, sync1_samples, sync2_samples, bit0_samples, bit1_samples ); /* PILOT */ for( ; pilot_length > 0; pilot_length-- ) { tzx_output_wave( buffer, pilot_samples ); size += pilot_samples; toggle_wave_data(); } /* SYNC1 */ if ( sync1_samples > 0 ) { tzx_output_wave( buffer, sync1_samples ); size += sync1_samples; toggle_wave_data(); } /* SYNC2 */ if ( sync2_samples > 0 ) { tzx_output_wave( buffer, sync2_samples ); size += sync2_samples; toggle_wave_data(); } /* data */ for( data_index = 0; data_index < data_size; data_index++ ) { UINT8 byte = bytes[data_index]; int bits_to_go = ( data_index == ( data_size - 1 ) ) ? bits_in_last_byte : 8; for( ; bits_to_go > 0; byte <<= 1, bits_to_go-- ) { int bit_samples = ( byte & 0x80 ) ? bit1_samples : bit0_samples; tzx_output_wave( buffer, bit_samples ); size += bit_samples; toggle_wave_data(); tzx_output_wave( buffer, bit_samples ); size += bit_samples; toggle_wave_data(); } } /* pause */ if ( pause > 0 ) { int start_pause_samples = millisec_to_samplecount( 1 ); int rest_pause_samples = millisec_to_samplecount( pause - 1 ); tzx_output_wave( buffer, start_pause_samples ); size += start_pause_samples; wave_data = WAVE_LOW; tzx_output_wave( buffer, rest_pause_samples ); size += rest_pause_samples; } return size; }
static inline int tzx_handle_symbol(int16_t **buffer, const uint8_t *symtable, uint8_t symbol, int maxp) { int size = 0; const uint8_t *cursymb = symtable + (2 * maxp + 1)*symbol; uint8_t starttype = cursymb[0]; switch (starttype) { case 0x00: toggle_wave_data(); break; case 0x01: // don't change break; case 0x02: // force low wave_data = WAVE_LOW; break; case 0x03: // force high wave_data = WAVE_HIGH; break; default: printf("SYMDEF invalid - bad starting polarity"); } for (int i = 0; i < maxp; i++) { uint16_t pulse_length = cursymb[1 + (i*2)] | (cursymb[2 + (i*2)] << 8); // shorter lists can be terminated with a pulse_length of 0 if (pulse_length != 0) { int samples = tcycles_to_samplecount(pulse_length); tzx_output_wave(buffer, samples); size += samples; toggle_wave_data(); } else { toggle_wave_data(); i = maxp; continue; } } return size; }
static int tzx_handle_generalized(int16_t **buffer, const uint8_t *bytes, int pause, int data_size, uint32_t totp, int npp, int asp, uint32_t totd, int npd, int asd ) { int size = 0; if (totp > 0) { // printf("pilot block table %04x\n", totp); const uint8_t *symtable = bytes; const uint8_t *table2 = symtable + (2 * npp + 1)*asp; // the Pilot and sync data stream has an RLE encoding for (int i = 0; i < totp; i+=3) { uint8_t symbol = table2[i + 0]; uint16_t repetitions = table2[i + 1] + (table2[i + 2] << 8); //printf("symbol %02x repetitions %04x\n", symbol, repetitions); // does 1 mean repeat once, or that it only occurs once? for (int j = 0; j < repetitions; j++) { size += tzx_handle_symbol(buffer, symtable, symbol, npp); } } // advance to after this data bytes += ((2 * npp + 1)*asp) + totp * 3; } if (totd > 0) { // printf("data block table %04x (has %0d symbols, max symbol length is %d)\n", totd, asd, npd); const uint8_t *symtable = bytes; const uint8_t *table2 = bytes + (2 * npd + 1)*asd; int NB = ceil(compute_log2(asd)); // number of bits needed to represent each symbol uint8_t stream_bit = 0; uint32_t stream_byte = 0; for (int i = 0; i < totd; i++) { uint8_t symbol = 0; for (int j = 0; j < NB; j++) { symbol |= stream_get_bit(table2, stream_bit, stream_byte) << j; } size += tzx_handle_symbol(buffer, symtable, symbol, npd); } } /* pause */ if (pause > 0) { int start_pause_samples = millisec_to_samplecount(1); int rest_pause_samples = millisec_to_samplecount(pause - 1); tzx_output_wave(buffer, start_pause_samples); size += start_pause_samples; wave_data = WAVE_LOW; tzx_output_wave(buffer, rest_pause_samples); size += rest_pause_samples; } return size; }
static int tzx_cas_handle_block( int16_t **buffer, const uint8_t *bytes, int pause, int data_size, int pilot, int pilot_length, int sync1, int sync2, int bit0, int bit1, int bits_in_last_byte ) { int pilot_samples = tcycles_to_samplecount(pilot); int sync1_samples = tcycles_to_samplecount(sync1); int sync2_samples = tcycles_to_samplecount(sync2); int bit0_samples = tcycles_to_samplecount(bit0); int bit1_samples = tcycles_to_samplecount(bit1); int data_index; int size = 0; /* Uncomment this to include into error.log a fully detailed analysis of each block */ // LOG_FORMATS("tzx_cas_block_size: pilot_length = %d, pilot_samples = %d, sync1_samples = %d, sync2_samples = %d, bit0_samples = %d, bit1_samples = %d\n", pilot_length, pilot_samples, sync1_samples, sync2_samples, bit0_samples, bit1_samples); /* PILOT */ for ( ; pilot_length > 0; pilot_length--) { tzx_output_wave(buffer, pilot_samples); size += pilot_samples; toggle_wave_data(); } /* SYNC1 */ if (sync1_samples > 0) { tzx_output_wave(buffer, sync1_samples); size += sync1_samples; toggle_wave_data(); } /* SYNC2 */ if (sync2_samples > 0) { tzx_output_wave(buffer, sync2_samples); size += sync2_samples; toggle_wave_data(); } /* data */ for (data_index = 0; data_index < data_size; data_index++) { uint8_t byte = bytes[data_index]; int bits_to_go = (data_index == (data_size - 1)) ? bits_in_last_byte : 8; for ( ; bits_to_go > 0; byte <<= 1, bits_to_go--) { int bit_samples = (byte & 0x80) ? bit1_samples : bit0_samples; tzx_output_wave(buffer, bit_samples); size += bit_samples; toggle_wave_data(); tzx_output_wave(buffer, bit_samples); size += bit_samples; toggle_wave_data(); } } /* pause */ int start_pause_samples = millisec_to_samplecount(1); tzx_output_wave(buffer, start_pause_samples); size += start_pause_samples; if (pause > 0) { int rest_pause_samples = millisec_to_samplecount(pause - 1); wave_data = WAVE_LOW; tzx_output_wave(buffer, rest_pause_samples); size += rest_pause_samples; } return size; }