mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 18:30:21 +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
|
||||
{
|
||||
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
|
||||
|
||||
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);
|
||||
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_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)
|
||||
{
|
||||
_input_level = new_input_level;
|
||||
|
@ -213,7 +213,7 @@ class SerialPort : public ::Commodore::Serial::Port {
|
||||
std::weak_ptr<UserPortVIA> _userPortVIA;
|
||||
};
|
||||
|
||||
class Tape: public Storage::TapePlayer {
|
||||
class Tape: public Storage::Tape::TapePlayer {
|
||||
public:
|
||||
Tape();
|
||||
|
||||
@ -232,7 +232,7 @@ class Tape: public Storage::TapePlayer {
|
||||
|
||||
private:
|
||||
Delegate *_delegate;
|
||||
virtual void process_input_pulse(Storage::Tape::Pulse pulse);
|
||||
virtual void process_input_pulse(Storage::Tape::Tape::Pulse pulse);
|
||||
bool _input_level;
|
||||
};
|
||||
|
||||
@ -261,7 +261,7 @@ class Machine:
|
||||
|
||||
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_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_key_state(Key key, bool isPressed) { _keyboardVIA->set_key_state(key, isPressed); }
|
||||
|
@ -458,7 +458,7 @@ void Machine::synchronise()
|
||||
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);
|
||||
}
|
||||
@ -971,14 +971,14 @@ inline uint8_t Tape::get_data_register()
|
||||
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[1] = _crossings[2];
|
||||
_crossings[2] = _crossings[3];
|
||||
|
||||
_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;
|
||||
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,
|
||||
};
|
||||
|
||||
class Tape: public Storage::TapePlayer {
|
||||
class Tape: public Storage::Tape::TapePlayer {
|
||||
public:
|
||||
Tape();
|
||||
|
||||
@ -86,7 +86,7 @@ class Tape: public Storage::TapePlayer {
|
||||
inline void set_is_in_input_mode(bool is_in_input_mode);
|
||||
|
||||
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 get_next_tape_pulse();
|
||||
|
||||
@ -145,7 +145,7 @@ class Machine:
|
||||
Machine();
|
||||
|
||||
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 clear_all_keys();
|
||||
|
@ -41,7 +41,7 @@
|
||||
- (BOOL)openUEFAtURL:(NSURL *)URL {
|
||||
@synchronized(self) {
|
||||
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);
|
||||
return YES;
|
||||
} catch(...) {
|
||||
|
@ -49,7 +49,7 @@ using namespace Commodore::Vic20;
|
||||
- (BOOL)openTAPAtURL:(NSURL *)URL {
|
||||
@synchronized(self) {
|
||||
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);
|
||||
return YES;
|
||||
} 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
|
||||
// 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::Tape>> tapes;
|
||||
std::list<std::shared_ptr<Storage::Tape::Tape>> tapes;
|
||||
TargetPlatformType potential_platforms = 0;
|
||||
|
||||
#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 {
|
||||
tapes.emplace_back(new Storage::TapePRG(file_name));
|
||||
tapes.emplace_back(new Storage::Tape::PRG(file_name));
|
||||
potential_platforms |= (TargetPlatformType)TargetPlatform::Commodore;
|
||||
} catch(...) {}
|
||||
}
|
||||
@ -89,8 +89,8 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
||||
{
|
||||
}
|
||||
|
||||
Format("tap", tapes, CommodoreTAP, TargetPlatform::Commodore) // TAP
|
||||
Format("uef", tapes, TapeUEF, TargetPlatform::Acorn) // UEF (tape)
|
||||
Format("tap", tapes, Tape::CommodoreTAP, TargetPlatform::Commodore) // TAP
|
||||
Format("uef", tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape)
|
||||
|
||||
#undef Format
|
||||
|
||||
|
@ -53,7 +53,7 @@ struct Target {
|
||||
} loadingMethod;
|
||||
|
||||
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?
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <cstring>
|
||||
|
||||
using namespace Storage;
|
||||
using namespace Tape;
|
||||
|
||||
CommodoreTAP::CommodoreTAP(const char *file_name)
|
||||
{
|
||||
@ -64,7 +65,7 @@ void CommodoreTAP::reset()
|
||||
_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)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
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.
|
||||
@ -43,6 +44,7 @@ class CommodoreTAP: public Tape {
|
||||
Pulse _current_pulse;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CommodoreTAP_hpp */
|
||||
|
@ -47,8 +47,9 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
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;
|
||||
stat(file_name, &file_stats);
|
||||
@ -69,12 +70,12 @@ TapePRG::TapePRG(const char *file_name) : _file(nullptr), _bitPhase(3), _filePha
|
||||
throw ErrorBadFormat;
|
||||
}
|
||||
|
||||
TapePRG::~TapePRG()
|
||||
PRG::~PRG()
|
||||
{
|
||||
if(_file) fclose(_file);
|
||||
}
|
||||
|
||||
Tape::Pulse TapePRG::get_next_pulse()
|
||||
Storage::Tape::Tape::Pulse PRG::get_next_pulse()
|
||||
{
|
||||
// these are all microseconds per pole
|
||||
static const unsigned int leader_zero_length = 179;
|
||||
@ -87,7 +88,7 @@ Tape::Pulse TapePRG::get_next_pulse()
|
||||
|
||||
Tape::Pulse pulse;
|
||||
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)
|
||||
{
|
||||
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 WordMarker: pulse.length.length = (_bitPhase&2) ? one_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;
|
||||
}
|
||||
|
||||
void TapePRG::reset()
|
||||
void PRG::reset()
|
||||
{
|
||||
_bitPhase = 3;
|
||||
fseek(_file, 2, SEEK_SET);
|
||||
@ -109,7 +110,7 @@ void TapePRG::reset()
|
||||
_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 countdown_bytes = 9;
|
||||
|
@ -6,18 +6,19 @@
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef TapePRG_hpp
|
||||
#define TapePRG_hpp
|
||||
#ifndef Storage_Tape_PRG_hpp
|
||||
#define Storage_Tape_PRG_hpp
|
||||
|
||||
#include "../Tape.hpp"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Storage {
|
||||
namespace Tape {
|
||||
|
||||
/*!
|
||||
Provides a @c Tape containing a .PRG, which is a direct local file.
|
||||
*/
|
||||
class TapePRG: public Tape {
|
||||
class PRG: public Tape {
|
||||
public:
|
||||
/*!
|
||||
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.
|
||||
@throws ErrorBadFormat if this file could not be opened and recognised as the specified type.
|
||||
*/
|
||||
TapePRG(const char *file_name);
|
||||
~TapePRG();
|
||||
PRG(const char *file_name);
|
||||
~PRG();
|
||||
|
||||
enum {
|
||||
ErrorBadFormat
|
||||
@ -64,6 +65,7 @@ class TapePRG: public Tape {
|
||||
uint8_t _copy_mask;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* T64_hpp */
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <math.h>
|
||||
|
||||
using namespace Storage;
|
||||
using namespace Tape;
|
||||
|
||||
static float gzgetfloat(gzFile file)
|
||||
{
|
||||
@ -43,7 +44,7 @@ static float gzgetfloat(gzFile file)
|
||||
return result;
|
||||
}
|
||||
|
||||
TapeUEF::TapeUEF(const char *file_name) :
|
||||
UEF::UEF(const char *file_name) :
|
||||
_chunk_id(0), _chunk_length(0), _chunk_position(0),
|
||||
_time_base(1200)
|
||||
{
|
||||
@ -69,17 +70,17 @@ TapeUEF::TapeUEF(const char *file_name) :
|
||||
find_next_tape_chunk();
|
||||
}
|
||||
|
||||
TapeUEF::~TapeUEF()
|
||||
UEF::~UEF()
|
||||
{
|
||||
gzclose(_file);
|
||||
}
|
||||
|
||||
void TapeUEF::reset()
|
||||
void UEF::reset()
|
||||
{
|
||||
gzseek(_file, 12, SEEK_SET);
|
||||
}
|
||||
|
||||
Tape::Pulse TapeUEF::get_next_pulse()
|
||||
Storage::Tape::Tape::Pulse UEF::get_next_pulse()
|
||||
{
|
||||
Pulse next_pulse;
|
||||
|
||||
@ -147,7 +148,7 @@ Tape::Pulse TapeUEF::get_next_pulse()
|
||||
return next_pulse;
|
||||
}
|
||||
|
||||
void TapeUEF::find_next_tape_chunk()
|
||||
void UEF::find_next_tape_chunk()
|
||||
{
|
||||
int reset_count = 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)
|
||||
{
|
||||
@ -252,7 +253,7 @@ bool TapeUEF::chunk_is_finished()
|
||||
}
|
||||
}
|
||||
|
||||
bool TapeUEF::get_next_bit()
|
||||
bool UEF::get_next_bit()
|
||||
{
|
||||
switch(_chunk_id)
|
||||
{
|
||||
|
@ -14,19 +14,20 @@
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Storage {
|
||||
namespace Tape {
|
||||
|
||||
/*!
|
||||
Provides a @c Tape containing a UEF tape image, a slightly-convoluted description of pulses.
|
||||
*/
|
||||
class TapeUEF : public Tape {
|
||||
class UEF : public Tape {
|
||||
public:
|
||||
/*!
|
||||
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.
|
||||
*/
|
||||
TapeUEF(const char *file_name);
|
||||
~TapeUEF();
|
||||
UEF(const char *file_name);
|
||||
~UEF();
|
||||
|
||||
enum {
|
||||
ErrorNotUEF
|
||||
@ -72,6 +73,7 @@ class TapeUEF : public Tape {
|
||||
bool chunk_is_finished();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TapeUEF_hpp */
|
||||
|
@ -10,8 +10,9 @@
|
||||
#include "../../NumberTheory/Factors.hpp"
|
||||
|
||||
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
|
||||
}
|
||||
@ -20,7 +21,7 @@ TapePlayer::TapePlayer(unsigned int 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;
|
||||
reset_timer();
|
||||
@ -41,7 +42,7 @@ void TapePlayer::get_next_pulse()
|
||||
{
|
||||
_current_pulse.length.length = 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);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "../TimedEventLoop.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Tape {
|
||||
|
||||
/*!
|
||||
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:
|
||||
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();
|
||||
|
||||
void run_for_cycles(int number_of_cycles);
|
||||
@ -64,10 +65,11 @@ class TapePlayer: public TimedEventLoop {
|
||||
private:
|
||||
inline void get_next_pulse();
|
||||
|
||||
std::shared_ptr<Storage::Tape> _tape;
|
||||
std::shared_ptr<Storage::Tape::Tape> _tape;
|
||||
Tape::Pulse _current_pulse;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Tape_hpp */
|
||||
|
Loading…
Reference in New Issue
Block a user