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;
|
_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)
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user