1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Implemented some portion of 0114; ensured I'm safely skipping chunks in all cases.

This commit is contained in:
Thomas Harte 2016-02-20 22:18:00 -05:00
parent ec3cccbb0d
commit f7fc7cb932
2 changed files with 28 additions and 3 deletions

View File

@ -63,6 +63,7 @@ Storage::UEF::UEF(const char *file_name) :
throw ErrorNotUEF; throw ErrorNotUEF;
} }
_start_of_next_chunk = gztell(_file);
find_next_tape_chunk(); find_next_tape_chunk();
} }
@ -104,6 +105,7 @@ Storage::Tape::Pulse Storage::UEF::get_next_pulse()
_bit_position = (_bit_position+1)&(_current_bit ? 3 : 1); _bit_position = (_bit_position+1)&(_current_bit ? 3 : 1);
} break; } break;
case 0x0114:
case 0x0110: case 0x0110:
next_pulse.type = (_bit_position&1) ? Pulse::High : Pulse::Low; next_pulse.type = (_bit_position&1) ? Pulse::High : Pulse::Low;
next_pulse.length.length = 1; next_pulse.length.length = 1;
@ -130,8 +132,11 @@ void Storage::UEF::find_next_tape_chunk()
_chunk_position = 0; _chunk_position = 0;
_bit_position = 0; _bit_position = 0;
while(1) while(1)
{ {
gzseek(_file, _start_of_next_chunk, SEEK_SET);
// read chunk ID // read chunk ID
_chunk_id = (uint16_t)gzgetc(_file); _chunk_id = (uint16_t)gzgetc(_file);
_chunk_id |= (uint16_t)(gzgetc(_file) << 8); _chunk_id |= (uint16_t)(gzgetc(_file) << 8);
@ -141,6 +146,8 @@ void Storage::UEF::find_next_tape_chunk()
_chunk_length |= (uint32_t)(gzgetc(_file) << 16); _chunk_length |= (uint32_t)(gzgetc(_file) << 16);
_chunk_length |= (uint32_t)(gzgetc(_file) << 24); _chunk_length |= (uint32_t)(gzgetc(_file) << 24);
_start_of_next_chunk = gztell(_file) + _chunk_length;
if(gzeof(_file)) if(gzeof(_file))
{ {
reset_count++; reset_count++;
@ -174,11 +181,23 @@ void Storage::UEF::find_next_tape_chunk()
_chunk_duration.length |= (uint16_t)(gzgetc(_file) << 8); _chunk_duration.length |= (uint16_t)(gzgetc(_file) << 8);
gzseek(_file, _chunk_length - 2, SEEK_CUR); gzseek(_file, _chunk_length - 2, SEEK_CUR);
return; return;
case 0x0111: // carrier tone with dummy byte // case 0x0111: // carrier tone with dummy byte
// TODO: read lengths // TODO: read lengths
return; // return;
case 0x0114: // security cycles case 0x0114: // security cycles
// TODO: read number, Ps and Ws // read number of cycles
_chunk_duration.length = (uint32_t)gzgetc(_file);
_chunk_duration.length |= (uint32_t)gzgetc(_file) << 8;
_chunk_duration.length |= (uint32_t)gzgetc(_file) << 16;
// Ps and Ws
_first_is_pulse = gzgetc(_file) == 'P';
_last_is_pulse = gzgetc(_file) == 'P';
if(_first_is_pulse)
_bit_position ^= 1;
// TODO: last is pulse
break; break;
case 0x113: // change of base rate case 0x113: // change of base rate
@ -202,6 +221,7 @@ bool Storage::UEF::chunk_is_finished()
{ {
case 0x0100: return (_chunk_position / 10) == _chunk_length; case 0x0100: return (_chunk_position / 10) == _chunk_length;
case 0x0102: return (_chunk_position / 8) == _chunk_length; case 0x0102: return (_chunk_position / 8) == _chunk_length;
case 0x0114:
case 0x0110: return _chunk_position == _chunk_duration.length; case 0x0110: return _chunk_position == _chunk_duration.length;
case 0x0112: case 0x0112:
@ -231,6 +251,7 @@ bool Storage::UEF::get_next_bit()
} }
break; break;
case 0x0114:
case 0x0102: case 0x0102:
{ {
uint32_t bit_position = _chunk_position%8; uint32_t bit_position = _chunk_position%8;

View File

@ -30,6 +30,7 @@ class UEF : public Tape {
private: private:
gzFile _file; gzFile _file;
unsigned int _time_base; unsigned int _time_base;
z_off_t _start_of_next_chunk;
uint16_t _chunk_id; uint16_t _chunk_id;
uint32_t _chunk_length; uint32_t _chunk_length;
@ -42,6 +43,9 @@ class UEF : public Tape {
Time _chunk_duration; Time _chunk_duration;
bool _first_is_pulse;
bool _last_is_pulse;
void find_next_tape_chunk(); void find_next_tape_chunk();
bool get_next_bit(); bool get_next_bit();
bool chunk_is_finished(); bool chunk_is_finished();