mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Spotted that pilot and data segments have different encodings — of course! — and attempted to adapt.
This commit is contained in:
parent
b63971caf7
commit
fa617eac6b
@ -71,6 +71,49 @@ class FileHolder {
|
||||
*/
|
||||
void ensure_file_is_at_least_length(long length);
|
||||
|
||||
class BitStream {
|
||||
public:
|
||||
BitStream(FILE *f, bool lsb_first) :
|
||||
file_(f),
|
||||
lsb_first_(lsb_first),
|
||||
next_value_(0),
|
||||
bits_remaining_(0) {}
|
||||
|
||||
uint8_t get_bits(int q) {
|
||||
uint8_t result = 0;
|
||||
while(q--) {
|
||||
result = (uint8_t)((result << 1) | get_bit());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
FILE *file_;
|
||||
bool lsb_first_;
|
||||
uint8_t next_value_;
|
||||
int bits_remaining_;
|
||||
|
||||
uint8_t get_bit() {
|
||||
if(!bits_remaining_) {
|
||||
bits_remaining_ = 8;
|
||||
next_value_ = (uint8_t)fgetc(file_);
|
||||
}
|
||||
|
||||
uint8_t bit;
|
||||
if(lsb_first_) {
|
||||
bit = next_value_ & 1;
|
||||
next_value_ >>= 1;
|
||||
} else {
|
||||
bit = next_value_ >> 7;
|
||||
next_value_ <<= 1;
|
||||
}
|
||||
|
||||
bits_remaining_--;
|
||||
|
||||
return bit;
|
||||
}
|
||||
};
|
||||
|
||||
FILE *file_;
|
||||
struct stat file_stats_;
|
||||
bool is_read_only_;
|
||||
|
@ -77,12 +77,12 @@ void TZX::get_generalised_data_block() {
|
||||
uint8_t maximum_pulses_per_data_symbol = (uint8_t)fgetc(file_);
|
||||
uint8_t symbols_in_data_table = (uint8_t)fgetc(file_);
|
||||
|
||||
get_generalised_segment(total_pilot_symbols, maximum_pulses_per_pilot_symbol, symbols_in_pilot_table);
|
||||
get_generalised_segment(total_data_symbols, maximum_pulses_per_data_symbol, symbols_in_data_table);
|
||||
get_generalised_segment(total_pilot_symbols, maximum_pulses_per_pilot_symbol, symbols_in_pilot_table, false);
|
||||
get_generalised_segment(total_data_symbols, maximum_pulses_per_data_symbol, symbols_in_data_table, true);
|
||||
emplace_back(Tape::Pulse::Zero, Storage::Time((unsigned int)pause_after_block, 1000u));
|
||||
}
|
||||
|
||||
void TZX::get_generalised_segment(uint32_t output_symbols, uint8_t max_pulses_per_symbol, uint8_t number_of_symbols) {
|
||||
void TZX::get_generalised_segment(uint32_t output_symbols, uint8_t max_pulses_per_symbol, uint8_t number_of_symbols, bool is_data) {
|
||||
if(!output_symbols) return;
|
||||
|
||||
// Construct the symbol table.
|
||||
@ -97,27 +97,48 @@ void TZX::get_generalised_segment(uint32_t output_symbols, uint8_t max_pulses_pe
|
||||
for(int ic = 0; ic < max_pulses_per_symbol; ic++) {
|
||||
symbol.pulse_lengths.push_back(fgetc16le());
|
||||
}
|
||||
symbol_table.push_back(symbol);
|
||||
}
|
||||
|
||||
// Hence produce the output.
|
||||
BitStream stream(file_, false);
|
||||
int base = 2;
|
||||
int bits = 1;
|
||||
while(base < number_of_symbols) {
|
||||
base <<= 1;
|
||||
bits++;
|
||||
}
|
||||
for(int c = 0; c < output_symbols; c++) {
|
||||
uint8_t symbol_value = (uint8_t)fgetc(file_);
|
||||
uint8_t symbol_value;
|
||||
int count;
|
||||
if(is_data) {
|
||||
symbol_value = stream.get_bits(bits);
|
||||
count = 1;
|
||||
} else {
|
||||
symbol_value = (uint8_t)fgetc(file_);
|
||||
count = fgetc16le();
|
||||
}
|
||||
if(symbol_value > number_of_symbols) {
|
||||
continue;
|
||||
}
|
||||
Symbol &symbol = symbol_table[symbol_value];
|
||||
|
||||
// Mutate initial output level.
|
||||
switch(symbol.flags & 3) {
|
||||
case 0: break;
|
||||
case 1: is_high_ ^= true; break;
|
||||
case 2: is_high_ = true; break;
|
||||
case 3: is_high_ = false; break;
|
||||
}
|
||||
while(count--) {
|
||||
// Mutate initial output level.
|
||||
switch(symbol.flags & 3) {
|
||||
case 0: break;
|
||||
case 1: is_high_ ^= true; break;
|
||||
case 2: is_high_ = true; break;
|
||||
case 3: is_high_ = false; break;
|
||||
}
|
||||
|
||||
// Output waves.
|
||||
for(auto length : symbol.pulse_lengths) {
|
||||
if(!length) break;
|
||||
// Output waves.
|
||||
for(auto length : symbol.pulse_lengths) {
|
||||
if(!length) break;
|
||||
|
||||
is_high_ ^= true;
|
||||
emplace_back(is_high_ ? Tape::Pulse::High : Tape::Pulse::Low, Storage::Time((unsigned int)length, StandardTZXClock));
|
||||
is_high_ ^= true;
|
||||
emplace_back(is_high_ ? Tape::Pulse::High : Tape::Pulse::Low, Storage::Time((unsigned int)length, StandardTZXClock));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class TZX: public PulseQueuedTape, public Storage::FileHolder {
|
||||
bool is_high_;
|
||||
|
||||
void get_generalised_data_block();
|
||||
void get_generalised_segment(uint32_t output_symbols, uint8_t max_pulses_per_symbol, uint8_t number_of_symbols);
|
||||
void get_generalised_segment(uint32_t output_symbols, uint8_t max_pulses_per_symbol, uint8_t number_of_symbols, bool is_data);
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user