mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-01 10:05:55 +00:00
Gave tapes their own namespace.
This commit is contained in:
parent
8c333059a8
commit
c0402d0c2b
@ -262,14 +262,14 @@ void Machine::set_prg(const char *file_name, size_t length, const uint8_t *data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_tape(std::shared_ptr<Storage::Tape>(new Storage::TapePRG(file_name)));
|
set_tape(std::shared_ptr<Storage::Tape::Tape>(new Storage::Tape::PRG(file_name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mar - Tape
|
#pragma mar - Tape
|
||||||
|
|
||||||
void Machine::set_tape(std::shared_ptr<Storage::Tape> tape)
|
void Machine::set_tape(std::shared_ptr<Storage::Tape::Tape> tape)
|
||||||
{
|
{
|
||||||
_tape.set_tape(tape);
|
_tape.set_tape(tape);
|
||||||
if(_should_automatically_load_media) set_typer_for_string("LOAD\nRUN\n");
|
if(_should_automatically_load_media) set_typer_for_string("LOAD\nRUN\n");
|
||||||
@ -422,9 +422,9 @@ Tape::Tape() : TapePlayer(1022727) {}
|
|||||||
void Tape::set_motor_control(bool enabled) {}
|
void Tape::set_motor_control(bool enabled) {}
|
||||||
void Tape::set_tape_output(bool set) {}
|
void Tape::set_tape_output(bool set) {}
|
||||||
|
|
||||||
void Tape::process_input_pulse(Storage::Tape::Pulse pulse)
|
void Tape::process_input_pulse(Storage::Tape::PRG::Pulse pulse)
|
||||||
{
|
{
|
||||||
bool new_input_level = pulse.type == Storage::Tape::Pulse::Low;
|
bool new_input_level = pulse.type == Storage::Tape::PRG::Pulse::Low;
|
||||||
if(_input_level != new_input_level)
|
if(_input_level != new_input_level)
|
||||||
{
|
{
|
||||||
_input_level = new_input_level;
|
_input_level = new_input_level;
|
||||||
|
@ -213,7 +213,7 @@ class SerialPort : public ::Commodore::Serial::Port {
|
|||||||
std::weak_ptr<UserPortVIA> _userPortVIA;
|
std::weak_ptr<UserPortVIA> _userPortVIA;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Tape: public Storage::TapePlayer {
|
class Tape: public Storage::Tape::TapePlayer {
|
||||||
public:
|
public:
|
||||||
Tape();
|
Tape();
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ class Tape: public Storage::TapePlayer {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Delegate *_delegate;
|
Delegate *_delegate;
|
||||||
virtual void process_input_pulse(Storage::Tape::Pulse pulse);
|
virtual void process_input_pulse(Storage::Tape::Tape::Pulse pulse);
|
||||||
bool _input_level;
|
bool _input_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ class Machine:
|
|||||||
|
|
||||||
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
|
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
|
||||||
void set_prg(const char *file_name, size_t length, const uint8_t *data);
|
void set_prg(const char *file_name, size_t length, const uint8_t *data);
|
||||||
void set_tape(std::shared_ptr<Storage::Tape> tape);
|
void set_tape(std::shared_ptr<Storage::Tape::Tape> tape);
|
||||||
void set_disk(std::shared_ptr<Storage::Disk> disk);
|
void set_disk(std::shared_ptr<Storage::Disk> disk);
|
||||||
|
|
||||||
void set_key_state(Key key, bool isPressed) { _keyboardVIA->set_key_state(key, isPressed); }
|
void set_key_state(Key key, bool isPressed) { _keyboardVIA->set_key_state(key, isPressed); }
|
||||||
|
@ -458,7 +458,7 @@ void Machine::synchronise()
|
|||||||
update_audio();
|
update_audio();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Machine::set_tape(std::shared_ptr<Storage::Tape> tape)
|
void Machine::set_tape(std::shared_ptr<Storage::Tape::Tape> tape)
|
||||||
{
|
{
|
||||||
_tape.set_tape(tape);
|
_tape.set_tape(tape);
|
||||||
}
|
}
|
||||||
@ -971,14 +971,14 @@ inline uint8_t Tape::get_data_register()
|
|||||||
return (uint8_t)(_data_register >> 2);
|
return (uint8_t)(_data_register >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Tape::process_input_pulse(Storage::Tape::Pulse pulse)
|
inline void Tape::process_input_pulse(Storage::Tape::Tape::Pulse pulse)
|
||||||
{
|
{
|
||||||
_crossings[0] = _crossings[1];
|
_crossings[0] = _crossings[1];
|
||||||
_crossings[1] = _crossings[2];
|
_crossings[1] = _crossings[2];
|
||||||
_crossings[2] = _crossings[3];
|
_crossings[2] = _crossings[3];
|
||||||
|
|
||||||
_crossings[3] = Tape::Unrecognised;
|
_crossings[3] = Tape::Unrecognised;
|
||||||
if(pulse.type != Storage::Tape::Pulse::Zero)
|
if(pulse.type != Storage::Tape::Tape::Pulse::Zero)
|
||||||
{
|
{
|
||||||
float pulse_length = (float)pulse.length.length / (float)pulse.length.clock_rate;
|
float pulse_length = (float)pulse.length.length / (float)pulse.length.clock_rate;
|
||||||
if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) _crossings[3] = Tape::Short;
|
if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) _crossings[3] = Tape::Short;
|
||||||
|
@ -62,7 +62,7 @@ enum Key: uint16_t {
|
|||||||
TerminateSequence = 0, NotMapped = 0xfffe,
|
TerminateSequence = 0, NotMapped = 0xfffe,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Tape: public Storage::TapePlayer {
|
class Tape: public Storage::Tape::TapePlayer {
|
||||||
public:
|
public:
|
||||||
Tape();
|
Tape();
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ class Tape: public Storage::TapePlayer {
|
|||||||
inline void set_is_in_input_mode(bool is_in_input_mode);
|
inline void set_is_in_input_mode(bool is_in_input_mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void process_input_pulse(Storage::Tape::Pulse pulse);
|
void process_input_pulse(Storage::Tape::Tape::Pulse pulse);
|
||||||
inline void push_tape_bit(uint16_t bit);
|
inline void push_tape_bit(uint16_t bit);
|
||||||
inline void get_next_tape_pulse();
|
inline void get_next_tape_pulse();
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ class Machine:
|
|||||||
Machine();
|
Machine();
|
||||||
|
|
||||||
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
|
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
|
||||||
void set_tape(std::shared_ptr<Storage::Tape> tape);
|
void set_tape(std::shared_ptr<Storage::Tape::Tape> tape);
|
||||||
|
|
||||||
void set_key_state(Key key, bool isPressed);
|
void set_key_state(Key key, bool isPressed);
|
||||||
void clear_all_keys();
|
void clear_all_keys();
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
- (BOOL)openUEFAtURL:(NSURL *)URL {
|
- (BOOL)openUEFAtURL:(NSURL *)URL {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
try {
|
try {
|
||||||
std::shared_ptr<Storage::TapeUEF> tape(new Storage::TapeUEF([URL fileSystemRepresentation]));
|
std::shared_ptr<Storage::Tape::UEF> tape(new Storage::Tape::UEF([URL fileSystemRepresentation]));
|
||||||
_electron.set_tape(tape);
|
_electron.set_tape(tape);
|
||||||
return YES;
|
return YES;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
@ -49,7 +49,7 @@ using namespace Commodore::Vic20;
|
|||||||
- (BOOL)openTAPAtURL:(NSURL *)URL {
|
- (BOOL)openTAPAtURL:(NSURL *)URL {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
try {
|
try {
|
||||||
std::shared_ptr<Storage::CommodoreTAP> tape(new Storage::CommodoreTAP([URL fileSystemRepresentation]));
|
std::shared_ptr<Storage::Tape::CommodoreTAP> tape(new Storage::Tape::CommodoreTAP([URL fileSystemRepresentation]));
|
||||||
_vic20.set_tape(tape);
|
_vic20.set_tape(tape);
|
||||||
return YES;
|
return YES;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
@ -49,7 +49,7 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
|||||||
// Collect all disks, tapes and ROMs as can be extrapolated from this file, forming the
|
// Collect all disks, tapes and ROMs as can be extrapolated from this file, forming the
|
||||||
// union of all platforms this file might be a target for.
|
// union of all platforms this file might be a target for.
|
||||||
std::list<std::shared_ptr<Storage::Disk>> disks;
|
std::list<std::shared_ptr<Storage::Disk>> disks;
|
||||||
std::list<std::shared_ptr<Storage::Tape>> tapes;
|
std::list<std::shared_ptr<Storage::Tape::Tape>> tapes;
|
||||||
TargetPlatformType potential_platforms = 0;
|
TargetPlatformType potential_platforms = 0;
|
||||||
|
|
||||||
#define Format(extension, list, class, platforms) \
|
#define Format(extension, list, class, platforms) \
|
||||||
@ -79,7 +79,7 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
|||||||
{
|
{
|
||||||
// try instantiating as a ROM; failing that accept as a tape
|
// try instantiating as a ROM; failing that accept as a tape
|
||||||
try {
|
try {
|
||||||
tapes.emplace_back(new Storage::TapePRG(file_name));
|
tapes.emplace_back(new Storage::Tape::PRG(file_name));
|
||||||
potential_platforms |= (TargetPlatformType)TargetPlatform::Commodore;
|
potential_platforms |= (TargetPlatformType)TargetPlatform::Commodore;
|
||||||
} catch(...) {}
|
} catch(...) {}
|
||||||
}
|
}
|
||||||
@ -89,8 +89,8 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Format("tap", tapes, CommodoreTAP, TargetPlatform::Commodore) // TAP
|
Format("tap", tapes, Tape::CommodoreTAP, TargetPlatform::Commodore) // TAP
|
||||||
Format("uef", tapes, TapeUEF, TargetPlatform::Acorn) // UEF (tape)
|
Format("uef", tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape)
|
||||||
|
|
||||||
#undef Format
|
#undef Format
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ struct Target {
|
|||||||
} loadingMethod;
|
} loadingMethod;
|
||||||
|
|
||||||
std::list<std::shared_ptr<Storage::Disk>> disks;
|
std::list<std::shared_ptr<Storage::Disk>> disks;
|
||||||
std::list<std::shared_ptr<Storage::Tape>> tapes;
|
std::list<std::shared_ptr<Storage::Tape::Tape>> tapes;
|
||||||
// TODO: ROMs. Probably can't model as raw data, but then how to handle bus complexities?
|
// TODO: ROMs. Probably can't model as raw data, but then how to handle bus complexities?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace Storage;
|
using namespace Storage;
|
||||||
|
using namespace Tape;
|
||||||
|
|
||||||
CommodoreTAP::CommodoreTAP(const char *file_name)
|
CommodoreTAP::CommodoreTAP(const char *file_name)
|
||||||
{
|
{
|
||||||
@ -64,7 +65,7 @@ void CommodoreTAP::reset()
|
|||||||
_current_pulse.type = Pulse::High;
|
_current_pulse.type = Pulse::High;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tape::Pulse CommodoreTAP::get_next_pulse()
|
Storage::Tape::Tape::Pulse CommodoreTAP::get_next_pulse()
|
||||||
{
|
{
|
||||||
if(_current_pulse.type == Pulse::High)
|
if(_current_pulse.type == Pulse::High)
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
namespace Tape {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Provides a @c Tape containing a Commodore-format tape image, which is simply a timed list of downward-going zero crossings.
|
Provides a @c Tape containing a Commodore-format tape image, which is simply a timed list of downward-going zero crossings.
|
||||||
@ -43,6 +44,7 @@ class CommodoreTAP: public Tape {
|
|||||||
Pulse _current_pulse;
|
Pulse _current_pulse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CommodoreTAP_hpp */
|
#endif /* CommodoreTAP_hpp */
|
||||||
|
@ -47,8 +47,9 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
using namespace Storage;
|
using namespace Storage;
|
||||||
|
using namespace Tape;
|
||||||
|
|
||||||
TapePRG::TapePRG(const char *file_name) : _file(nullptr), _bitPhase(3), _filePhase(FilePhaseLeadIn), _phaseOffset(0), _copy_mask(0x80)
|
PRG::PRG(const char *file_name) : _file(nullptr), _bitPhase(3), _filePhase(FilePhaseLeadIn), _phaseOffset(0), _copy_mask(0x80)
|
||||||
{
|
{
|
||||||
struct stat file_stats;
|
struct stat file_stats;
|
||||||
stat(file_name, &file_stats);
|
stat(file_name, &file_stats);
|
||||||
@ -69,12 +70,12 @@ TapePRG::TapePRG(const char *file_name) : _file(nullptr), _bitPhase(3), _filePha
|
|||||||
throw ErrorBadFormat;
|
throw ErrorBadFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
TapePRG::~TapePRG()
|
PRG::~PRG()
|
||||||
{
|
{
|
||||||
if(_file) fclose(_file);
|
if(_file) fclose(_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tape::Pulse TapePRG::get_next_pulse()
|
Storage::Tape::Tape::Pulse PRG::get_next_pulse()
|
||||||
{
|
{
|
||||||
// these are all microseconds per pole
|
// these are all microseconds per pole
|
||||||
static const unsigned int leader_zero_length = 179;
|
static const unsigned int leader_zero_length = 179;
|
||||||
@ -87,7 +88,7 @@ Tape::Pulse TapePRG::get_next_pulse()
|
|||||||
|
|
||||||
Tape::Pulse pulse;
|
Tape::Pulse pulse;
|
||||||
pulse.length.clock_rate = 1000000;
|
pulse.length.clock_rate = 1000000;
|
||||||
pulse.type = (_bitPhase&1) ? Pulse::High : Pulse::Low;
|
pulse.type = (_bitPhase&1) ? Tape::Pulse::High : Tape::Pulse::Low;
|
||||||
switch(_outputToken)
|
switch(_outputToken)
|
||||||
{
|
{
|
||||||
case Leader: pulse.length.length = leader_zero_length; break;
|
case Leader: pulse.length.length = leader_zero_length; break;
|
||||||
@ -95,12 +96,12 @@ Tape::Pulse TapePRG::get_next_pulse()
|
|||||||
case One: pulse.length.length = (_bitPhase&2) ? zero_length : one_length; break;
|
case One: pulse.length.length = (_bitPhase&2) ? zero_length : one_length; break;
|
||||||
case WordMarker: pulse.length.length = (_bitPhase&2) ? one_length : marker_length; break;
|
case WordMarker: pulse.length.length = (_bitPhase&2) ? one_length : marker_length; break;
|
||||||
case EndOfBlock: pulse.length.length = (_bitPhase&2) ? zero_length : marker_length; break;
|
case EndOfBlock: pulse.length.length = (_bitPhase&2) ? zero_length : marker_length; break;
|
||||||
case Silence: pulse.type = Pulse::Zero; pulse.length.length = 5000; break;
|
case Silence: pulse.type = Tape::Pulse::Zero; pulse.length.length = 5000; break;
|
||||||
}
|
}
|
||||||
return pulse;
|
return pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TapePRG::reset()
|
void PRG::reset()
|
||||||
{
|
{
|
||||||
_bitPhase = 3;
|
_bitPhase = 3;
|
||||||
fseek(_file, 2, SEEK_SET);
|
fseek(_file, 2, SEEK_SET);
|
||||||
@ -109,7 +110,7 @@ void TapePRG::reset()
|
|||||||
_copy_mask = 0x80;
|
_copy_mask = 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TapePRG::get_next_output_token()
|
void PRG::get_next_output_token()
|
||||||
{
|
{
|
||||||
static const int block_length = 192; // not counting the checksum
|
static const int block_length = 192; // not counting the checksum
|
||||||
static const int countdown_bytes = 9;
|
static const int countdown_bytes = 9;
|
||||||
|
@ -6,18 +6,19 @@
|
|||||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef TapePRG_hpp
|
#ifndef Storage_Tape_PRG_hpp
|
||||||
#define TapePRG_hpp
|
#define Storage_Tape_PRG_hpp
|
||||||
|
|
||||||
#include "../Tape.hpp"
|
#include "../Tape.hpp"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
namespace Tape {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Provides a @c Tape containing a .PRG, which is a direct local file.
|
Provides a @c Tape containing a .PRG, which is a direct local file.
|
||||||
*/
|
*/
|
||||||
class TapePRG: public Tape {
|
class PRG: public Tape {
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
Constructs a @c T64 containing content from the file with name @c file_name, of type @c type.
|
Constructs a @c T64 containing content from the file with name @c file_name, of type @c type.
|
||||||
@ -26,8 +27,8 @@ class TapePRG: public Tape {
|
|||||||
@param type The type of data the file should contain.
|
@param type The type of data the file should contain.
|
||||||
@throws ErrorBadFormat if this file could not be opened and recognised as the specified type.
|
@throws ErrorBadFormat if this file could not be opened and recognised as the specified type.
|
||||||
*/
|
*/
|
||||||
TapePRG(const char *file_name);
|
PRG(const char *file_name);
|
||||||
~TapePRG();
|
~PRG();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ErrorBadFormat
|
ErrorBadFormat
|
||||||
@ -64,6 +65,7 @@ class TapePRG: public Tape {
|
|||||||
uint8_t _copy_mask;
|
uint8_t _copy_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* T64_hpp */
|
#endif /* T64_hpp */
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
using namespace Storage;
|
using namespace Storage;
|
||||||
|
using namespace Tape;
|
||||||
|
|
||||||
static float gzgetfloat(gzFile file)
|
static float gzgetfloat(gzFile file)
|
||||||
{
|
{
|
||||||
@ -43,7 +44,7 @@ static float gzgetfloat(gzFile file)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TapeUEF::TapeUEF(const char *file_name) :
|
UEF::UEF(const char *file_name) :
|
||||||
_chunk_id(0), _chunk_length(0), _chunk_position(0),
|
_chunk_id(0), _chunk_length(0), _chunk_position(0),
|
||||||
_time_base(1200)
|
_time_base(1200)
|
||||||
{
|
{
|
||||||
@ -69,17 +70,17 @@ TapeUEF::TapeUEF(const char *file_name) :
|
|||||||
find_next_tape_chunk();
|
find_next_tape_chunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
TapeUEF::~TapeUEF()
|
UEF::~UEF()
|
||||||
{
|
{
|
||||||
gzclose(_file);
|
gzclose(_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TapeUEF::reset()
|
void UEF::reset()
|
||||||
{
|
{
|
||||||
gzseek(_file, 12, SEEK_SET);
|
gzseek(_file, 12, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tape::Pulse TapeUEF::get_next_pulse()
|
Storage::Tape::Tape::Pulse UEF::get_next_pulse()
|
||||||
{
|
{
|
||||||
Pulse next_pulse;
|
Pulse next_pulse;
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ Tape::Pulse TapeUEF::get_next_pulse()
|
|||||||
return next_pulse;
|
return next_pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TapeUEF::find_next_tape_chunk()
|
void UEF::find_next_tape_chunk()
|
||||||
{
|
{
|
||||||
int reset_count = 0;
|
int reset_count = 0;
|
||||||
_chunk_position = 0;
|
_chunk_position = 0;
|
||||||
@ -236,7 +237,7 @@ void TapeUEF::find_next_tape_chunk()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TapeUEF::chunk_is_finished()
|
bool UEF::chunk_is_finished()
|
||||||
{
|
{
|
||||||
switch(_chunk_id)
|
switch(_chunk_id)
|
||||||
{
|
{
|
||||||
@ -252,7 +253,7 @@ bool TapeUEF::chunk_is_finished()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TapeUEF::get_next_bit()
|
bool UEF::get_next_bit()
|
||||||
{
|
{
|
||||||
switch(_chunk_id)
|
switch(_chunk_id)
|
||||||
{
|
{
|
||||||
|
@ -14,19 +14,20 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
namespace Tape {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Provides a @c Tape containing a UEF tape image, a slightly-convoluted description of pulses.
|
Provides a @c Tape containing a UEF tape image, a slightly-convoluted description of pulses.
|
||||||
*/
|
*/
|
||||||
class TapeUEF : public Tape {
|
class UEF : public Tape {
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
Constructs a @c UEF containing content from the file with name @c file_name.
|
Constructs a @c UEF containing content from the file with name @c file_name.
|
||||||
|
|
||||||
@throws ErrorNotUEF if this file could not be opened and recognised as a valid UEF.
|
@throws ErrorNotUEF if this file could not be opened and recognised as a valid UEF.
|
||||||
*/
|
*/
|
||||||
TapeUEF(const char *file_name);
|
UEF(const char *file_name);
|
||||||
~TapeUEF();
|
~UEF();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ErrorNotUEF
|
ErrorNotUEF
|
||||||
@ -72,6 +73,7 @@ class TapeUEF : public Tape {
|
|||||||
bool chunk_is_finished();
|
bool chunk_is_finished();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TapeUEF_hpp */
|
#endif /* TapeUEF_hpp */
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
#include "../../NumberTheory/Factors.hpp"
|
#include "../../NumberTheory/Factors.hpp"
|
||||||
|
|
||||||
using namespace Storage;
|
using namespace Storage;
|
||||||
|
using namespace Tape;
|
||||||
|
|
||||||
void Tape::seek(Time seek_time)
|
void Storage::Tape::Tape::seek(Time seek_time)
|
||||||
{
|
{
|
||||||
// TODO: as best we can
|
// TODO: as best we can
|
||||||
}
|
}
|
||||||
@ -20,7 +21,7 @@ TapePlayer::TapePlayer(unsigned int input_clock_rate) :
|
|||||||
TimedEventLoop(input_clock_rate)
|
TimedEventLoop(input_clock_rate)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void TapePlayer::set_tape(std::shared_ptr<Storage::Tape> tape)
|
void TapePlayer::set_tape(std::shared_ptr<Storage::Tape::Tape> tape)
|
||||||
{
|
{
|
||||||
_tape = tape;
|
_tape = tape;
|
||||||
reset_timer();
|
reset_timer();
|
||||||
@ -41,7 +42,7 @@ void TapePlayer::get_next_pulse()
|
|||||||
{
|
{
|
||||||
_current_pulse.length.length = 1;
|
_current_pulse.length.length = 1;
|
||||||
_current_pulse.length.clock_rate = 1;
|
_current_pulse.length.clock_rate = 1;
|
||||||
_current_pulse.type = Storage::Tape::Pulse::Zero;
|
_current_pulse.type = Tape::Pulse::Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_next_event_time_interval(_current_pulse.length);
|
set_next_event_time_interval(_current_pulse.length);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "../TimedEventLoop.hpp"
|
#include "../TimedEventLoop.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
namespace Tape {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Models a tape as a sequence of pulses, each pulse being of arbitrary length and described
|
Models a tape as a sequence of pulses, each pulse being of arbitrary length and described
|
||||||
@ -51,7 +52,7 @@ class TapePlayer: public TimedEventLoop {
|
|||||||
public:
|
public:
|
||||||
TapePlayer(unsigned int input_clock_rate);
|
TapePlayer(unsigned int input_clock_rate);
|
||||||
|
|
||||||
void set_tape(std::shared_ptr<Storage::Tape> tape);
|
void set_tape(std::shared_ptr<Storage::Tape::Tape> tape);
|
||||||
bool has_tape();
|
bool has_tape();
|
||||||
|
|
||||||
void run_for_cycles(int number_of_cycles);
|
void run_for_cycles(int number_of_cycles);
|
||||||
@ -64,10 +65,11 @@ class TapePlayer: public TimedEventLoop {
|
|||||||
private:
|
private:
|
||||||
inline void get_next_pulse();
|
inline void get_next_pulse();
|
||||||
|
|
||||||
std::shared_ptr<Storage::Tape> _tape;
|
std::shared_ptr<Storage::Tape::Tape> _tape;
|
||||||
Tape::Pulse _current_pulse;
|
Tape::Pulse _current_pulse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Tape_hpp */
|
#endif /* Tape_hpp */
|
||||||
|
Loading…
Reference in New Issue
Block a user