1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-19 08:31:11 +00:00

Working towards HQ UEF support: fixed bug whereby writing to tape output would reset input pulse stepper; added support for chunk 0116 and approximate support for 0113.

This commit is contained in:
Thomas Harte 2016-02-20 22:03:14 -05:00
parent 3754cf4bce
commit ec3cccbb0d
3 changed files with 52 additions and 8 deletions

View File

@ -690,9 +690,9 @@ inline void Tape::get_next_tape_pulse()
{ {
_time_into_pulse = 0; _time_into_pulse = 0;
_current_pulse = _tape->get_next_pulse(); _current_pulse = _tape->get_next_pulse();
if(_pulse_stepper == nullptr || _current_pulse.length.clock_rate != _pulse_stepper->get_output_rate()) if(_input_pulse_stepper == nullptr || _current_pulse.length.clock_rate != _input_pulse_stepper->get_output_rate())
{ {
_pulse_stepper = std::unique_ptr<SignalProcessing::Stepper>(new SignalProcessing::Stepper(_current_pulse.length.clock_rate, 2000000)); _input_pulse_stepper = std::unique_ptr<SignalProcessing::Stepper>(new SignalProcessing::Stepper(_current_pulse.length.clock_rate, 2000000));
} }
} }
@ -762,7 +762,7 @@ inline void Tape::set_is_in_input_mode(bool is_in_input_mode)
inline void Tape::set_counter(uint8_t value) inline void Tape::set_counter(uint8_t value)
{ {
_pulse_stepper = std::unique_ptr<SignalProcessing::Stepper>(new SignalProcessing::Stepper(1200, 2000000)); _output_pulse_stepper = std::unique_ptr<SignalProcessing::Stepper>(new SignalProcessing::Stepper(1200, 2000000));
} }
inline void Tape::set_data_register(uint8_t value) inline void Tape::set_data_register(uint8_t value)
@ -786,7 +786,7 @@ inline void Tape::run_for_cycles(unsigned int number_of_cycles)
{ {
while(number_of_cycles--) while(number_of_cycles--)
{ {
_time_into_pulse += (unsigned int)_pulse_stepper->step(); _time_into_pulse += (unsigned int)_input_pulse_stepper->step();
if(_time_into_pulse == _current_pulse.length.length) if(_time_into_pulse == _current_pulse.length.length)
{ {
get_next_tape_pulse(); get_next_tape_pulse();
@ -826,7 +826,7 @@ inline void Tape::run_for_cycles(unsigned int number_of_cycles)
{ {
while(number_of_cycles--) while(number_of_cycles--)
{ {
if(_pulse_stepper->step()) if(_output_pulse_stepper->step())
{ {
_output_bits_remaining--; _output_bits_remaining--;
if(!_output_bits_remaining) if(!_output_bits_remaining)

View File

@ -91,7 +91,8 @@ class Tape {
std::shared_ptr<Storage::Tape> _tape; std::shared_ptr<Storage::Tape> _tape;
Storage::Tape::Pulse _current_pulse; Storage::Tape::Pulse _current_pulse;
std::unique_ptr<SignalProcessing::Stepper> _pulse_stepper; std::unique_ptr<SignalProcessing::Stepper> _input_pulse_stepper;
std::unique_ptr<SignalProcessing::Stepper> _output_pulse_stepper;
uint32_t _time_into_pulse; uint32_t _time_into_pulse;
bool _is_running; bool _is_running;

View File

@ -8,6 +8,38 @@
#include "TapeUEF.hpp" #include "TapeUEF.hpp"
#include <string.h> #include <string.h>
#include <math.h>
static float gzgetfloat(gzFile file)
{
uint8_t bytes[4];
bytes[0] = (uint8_t)gzgetc(file);
bytes[1] = (uint8_t)gzgetc(file);
bytes[2] = (uint8_t)gzgetc(file);
bytes[3] = (uint8_t)gzgetc(file);
/* assume a four byte array named Float exists, where Float[0]
was the first byte read from the UEF, Float[1] the second, etc */
/* decode mantissa */
int mantissa;
mantissa = bytes[0] | (bytes[1] << 8) | ((bytes[2]&0x7f)|0x80) << 16;
float result = (float)mantissa;
result = (float)ldexp(result, -23);
/* decode exponent */
int exponent;
exponent = ((bytes[2]&0x80) >> 7) | (bytes[3]&0x7f) << 1;
exponent -= 127;
result = (float)ldexp(result, exponent);
/* flip sign if necessary */
if(bytes[3]&0x80)
result = -result;
return result;
}
Storage::UEF::UEF(const char *file_name) : Storage::UEF::UEF(const char *file_name) :
_chunk_id(0), _chunk_length(0), _chunk_position(0), _chunk_id(0), _chunk_length(0), _chunk_position(0),
@ -117,18 +149,24 @@ void Storage::UEF::find_next_tape_chunk()
continue; continue;
} }
printf("Deal with %04x?\n", _chunk_id);
switch(_chunk_id) switch(_chunk_id)
{ {
case 0x0100: case 0x0102: // implicit and explicit bit patterns case 0x0100: case 0x0102: // implicit and explicit bit patterns
return; return;
case 0x0112: case 0x0112: // integer gap
_chunk_duration.length = (uint16_t)gzgetc(_file); _chunk_duration.length = (uint16_t)gzgetc(_file);
_chunk_duration.length |= (uint16_t)(gzgetc(_file) << 8); _chunk_duration.length |= (uint16_t)(gzgetc(_file) << 8);
_chunk_duration.clock_rate = _time_base; _chunk_duration.clock_rate = _time_base;
return; return;
case 0x0116: // gaps case 0x0116: // floating point gap
{
float length = gzgetfloat(_file);
_chunk_duration.length = (unsigned int)(length * 4000000);
_chunk_duration.clock_rate = 4000000;
}
return; return;
case 0x0110: // carrier tone case 0x0110: // carrier tone
@ -144,6 +182,11 @@ void Storage::UEF::find_next_tape_chunk()
break; break;
case 0x113: // change of base rate case 0x113: // change of base rate
{
// TODO: something smarter than just converting this to an int
float new_time_base = gzgetfloat(_file);
_time_base = (unsigned int)roundf(new_time_base);
}
break; break;
default: default: