mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-13 07:30:21 +00:00
Sketched out the generic interface for a disk, documenting it and the tape interface while I'm here.
This commit is contained in:
parent
cf83258eaf
commit
9e3d6b762b
@ -42,6 +42,7 @@
|
||||
4B73C71A1D036BD90074D992 /* Vic20Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B73C7191D036BD90074D992 /* Vic20Document.swift */; };
|
||||
4B73C71D1D036C030074D992 /* Vic20Document.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B73C71B1D036C030074D992 /* Vic20Document.xib */; };
|
||||
4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */; };
|
||||
4BAB62AD1D3272D200DF5BA0 /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */; };
|
||||
4BB298EE1B587D8400A49093 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */; };
|
||||
4BB298EF1B587D8400A49093 /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E11B587D8300A49093 /* AllSuiteA.bin */; };
|
||||
4BB298F11B587D8400A49093 /* start in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E51B587D8300A49093 /* start */; };
|
||||
@ -415,6 +416,9 @@
|
||||
4B73C7191D036BD90074D992 /* Vic20Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vic20Document.swift; sourceTree = "<group>"; };
|
||||
4B73C71C1D036C030074D992 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Vic20Document.xib"; sourceTree = SOURCE_ROOT; };
|
||||
4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6502TimingTests.swift; sourceTree = "<group>"; };
|
||||
4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Disk.cpp; sourceTree = "<group>"; };
|
||||
4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Disk.hpp; sourceTree = "<group>"; };
|
||||
4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Storage.hpp; sourceTree = "<group>"; };
|
||||
4BB297E01B587D8300A49093 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = "<group>"; };
|
||||
4BB297E11B587D8300A49093 /* AllSuiteA.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = AllSuiteA.bin; sourceTree = "<group>"; };
|
||||
4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = "<group>"; };
|
||||
@ -941,7 +945,9 @@
|
||||
4B69FB391C4D908A00B5F0AA /* Storage */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4BAB62AA1D3272D200DF5BA0 /* Disk */,
|
||||
4B69FB3A1C4D908A00B5F0AA /* Tape */,
|
||||
4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */,
|
||||
);
|
||||
name = Storage;
|
||||
path = ../../Storage;
|
||||
@ -969,6 +975,15 @@
|
||||
path = Formats;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4BAB62AA1D3272D200DF5BA0 /* Disk */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */,
|
||||
4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */,
|
||||
);
|
||||
path = Disk;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1818,6 +1833,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4BAB62AD1D3272D200DF5BA0 /* Disk.cpp in Sources */,
|
||||
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */,
|
||||
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */,
|
||||
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
|
||||
|
9
Storage/Disk/Disk.cpp
Normal file
9
Storage/Disk/Disk.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// Disk.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/07/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Disk.hpp"
|
66
Storage/Disk/Disk.hpp
Normal file
66
Storage/Disk/Disk.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// Disk.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/07/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Disk_hpp
|
||||
#define Disk_hpp
|
||||
|
||||
#include <memory>
|
||||
#include "../Storage.hpp"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
/*!
|
||||
Models a single track on a disk as a series of events, each event being of arbitrary length
|
||||
and resulting in either a flux transition or the sensing of an index hole.
|
||||
|
||||
Subclasses should implement @c get_next_event.
|
||||
*/
|
||||
class Track {
|
||||
public:
|
||||
struct Event {
|
||||
enum {
|
||||
IndexHole, FluxTransition
|
||||
} type;
|
||||
Time length;
|
||||
};
|
||||
|
||||
virtual Event get_next_event() = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
Models a disk as a collection of tracks, providing a range of possible track positions and allowing
|
||||
a point sampling of the track beneath any of those positions (if any).
|
||||
|
||||
The intention is not that tracks necessarily be evenly spaced; a head_position_count of 3 wih track
|
||||
A appearing in positions 0 and 1, and track B appearing in position 2 is an appropriate use of this API
|
||||
if it matches the media.
|
||||
|
||||
The track returned is point sampled only; if a particular disk drive has a sufficiently large head to
|
||||
pick up multiple tracks at once then the drive responsible for asking for multiple tracks and for
|
||||
merging the results.
|
||||
*/
|
||||
class Disk {
|
||||
public:
|
||||
|
||||
/*!
|
||||
Returns the number of discrete positions that this disk uses to model its complete surface area.
|
||||
|
||||
This is not necessarily a track count. There is no implicit guarantee that every position will
|
||||
return a distinct track, or — if the media is holeless — will return any track at all.
|
||||
*/
|
||||
virtual unsigned int get_head_position_count() = 0;
|
||||
|
||||
/*!
|
||||
Returns the @c Track at @c position if there are any detectable events there; returns @c nullptr otherwise.
|
||||
*/
|
||||
virtual std::shared_ptr<Track> get_track_at_position(unsigned int position) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Disk_hpp */
|
20
Storage/Storage.hpp
Normal file
20
Storage/Storage.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Storage.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/07/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Storage_hpp
|
||||
#define Storage_hpp
|
||||
|
||||
namespace Storage {
|
||||
|
||||
struct Time {
|
||||
unsigned int length, clock_rate;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Storage_h */
|
@ -10,7 +10,7 @@
|
||||
|
||||
using namespace Storage;
|
||||
|
||||
void Tape::seek(Tape::Time seek_time)
|
||||
void Tape::seek(Time seek_time)
|
||||
{
|
||||
// TODO: as best we can
|
||||
}
|
||||
|
@ -11,15 +11,23 @@
|
||||
|
||||
#include <memory>
|
||||
#include "../../SignalProcessing/Stepper.hpp"
|
||||
#include "../Storage.hpp"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
/*!
|
||||
Models a tape as a sequence of pulses, each pulse being of arbitrary length and described
|
||||
by their relationship with zero:
|
||||
- high pulses exit from zero upward before returning to it;
|
||||
- low pulses exit from zero downward before returning to it;
|
||||
- zero pulses run along zero.
|
||||
|
||||
Subclasses should implement at least @c get_next_pulse and @c reset to provide a serial feeding
|
||||
of pulses and the ability to return to the start of the feed. They may also implement @c seek if
|
||||
a better implementation than a linear search from the @c reset time can be implemented.
|
||||
*/
|
||||
class Tape {
|
||||
public:
|
||||
struct Time {
|
||||
unsigned int length, clock_rate;
|
||||
};
|
||||
|
||||
struct Pulse {
|
||||
enum {
|
||||
High, Low, Zero
|
||||
@ -30,9 +38,16 @@ class Tape {
|
||||
virtual Pulse get_next_pulse() = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
virtual void seek(Time seek_time);
|
||||
virtual void seek(Time seek_time); // TODO
|
||||
};
|
||||
|
||||
/*!
|
||||
Provides a helper for: (i) retaining a reference to a tape; and (ii) running the tape at a certain
|
||||
input clock rate.
|
||||
|
||||
Will call @c process_input_pulse instantaneously upon reaching *the end* of a pulse. Therefore a subclass
|
||||
can decode pulses into data within process_input_pulse, using the supplied pulse's @c length and @c type.
|
||||
*/
|
||||
class TapePlayer {
|
||||
public:
|
||||
TapePlayer(unsigned int input_clock_rate);
|
||||
|
Loading…
x
Reference in New Issue
Block a user