1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +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;
_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)
{
_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)
@ -786,7 +786,7 @@ inline void Tape::run_for_cycles(unsigned int 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)
{
get_next_tape_pulse();
@ -826,7 +826,7 @@ inline void Tape::run_for_cycles(unsigned int number_of_cycles)
{
while(number_of_cycles--)
{
if(_pulse_stepper->step())
if(_output_pulse_stepper->step())
{
_output_bits_remaining--;
if(!_output_bits_remaining)

View File

@ -91,7 +91,8 @@ class Tape {
std::shared_ptr<Storage::Tape> _tape;
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;
bool _is_running;

View File

@ -8,6 +8,38 @@
#include "TapeUEF.hpp"
#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) :
_chunk_id(0), _chunk_length(0), _chunk_position(0),
@ -117,18 +149,24 @@ void Storage::UEF::find_next_tape_chunk()
continue;
}
printf("Deal with %04x?\n", _chunk_id);
switch(_chunk_id)
{
case 0x0100: case 0x0102: // implicit and explicit bit patterns
return;
case 0x0112:
case 0x0112: // integer gap
_chunk_duration.length = (uint16_t)gzgetc(_file);
_chunk_duration.length |= (uint16_t)(gzgetc(_file) << 8);
_chunk_duration.clock_rate = _time_base;
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;
case 0x0110: // carrier tone
@ -144,6 +182,11 @@ void Storage::UEF::find_next_tape_chunk()
break;
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;
default: