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:
parent
3754cf4bce
commit
ec3cccbb0d
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user