static int ace_handle_tap(INT16 *buffer, const UINT8 *casdata) { int data_pos, sample_count; /* Make sure the file starts with a valid header */ if ( cas_size < 0x1C ) return -1; if ( casdata[0] != 0x1A || casdata[1] != 0x00 ) return -1; data_pos = 0; sample_count = 0; while( data_pos < cas_size ) { UINT16 block_size; int i; /* Handle a block of tape data */ block_size = casdata[data_pos] + ( casdata[data_pos + 1] << 8 ); data_pos += 2; /* Make sure there are enough bytes left */ if ( data_pos > cas_size ) return -1; /* 2 seconds silence */ sample_count += ace_tap_silence( buffer, sample_count, 2 * 44100 ); /* Add pilot tone samples: 4096 for header, 512 for data */ for( i = ( block_size == 0x001A ) ? 4096 : 512; i; i-- ) sample_count += ace_tap_cycle( buffer, sample_count, 27, 27 ); /* Sync samples */ sample_count += ace_tap_cycle( buffer, sample_count, 8, 11 ); /* Output block type identification byte */ sample_count += ace_tap_byte( buffer, sample_count, ( block_size != 0x001A ) ? 0xFF : 0x00 ); /* Data samples */ for ( ; block_size ; data_pos++, block_size-- ) sample_count += ace_tap_byte( buffer, sample_count, casdata[data_pos] ); /* End mark samples */ sample_count += ace_tap_cycle( buffer, sample_count, 12, 57 ); /* 3 seconds silence */ sample_count += ace_tap_silence( buffer, sample_count, 3 * 44100 ); } return sample_count; }
INLINE int ace_tap_byte(INT16 *buffer, int sample_pos, UINT8 data) { int i, samples; samples = 0; for ( i = 0; i < 8; i++ ) { if ( data & 0x80 ) samples += ace_tap_cycle( buffer, sample_pos + samples, 21, 22 ); else samples += ace_tap_cycle( buffer, sample_pos + samples, 10, 11 ); data <<= 1; } return samples; }
static inline int ace_tap_byte(int16_t *buffer, int sample_pos, uint8_t data) { int i, samples; samples = 0; for ( i = 0; i < 8; i++ ) { if ( data & 0x80 ) samples += ace_tap_cycle( buffer, sample_pos + samples, 21, 22 ); else samples += ace_tap_cycle( buffer, sample_pos + samples, 10, 11 ); data <<= 1; } return samples; }