1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Started taking further steps towards CSW support; reading the ZLib documentation is next.

This commit is contained in:
Thomas Harte 2017-07-11 22:41:10 -04:00
parent 368bff1a82
commit 33eadb5549
3 changed files with 73 additions and 0 deletions

View File

@ -12,8 +12,68 @@ using namespace Storage::Tape;
CSW::CSW(const char *file_name) : CSW::CSW(const char *file_name) :
Storage::FileHolder(file_name) { Storage::FileHolder(file_name) {
if(file_stats_.st_size < 0x20) throw ErrorNotCSW;
// Check signature.
char identifier[22];
char signature[] = "Compressed Square Wave";
fread(identifier, 1, 22, file_);
if(memcmp(identifier, signature, strlen(signature))) throw ErrorNotCSW;
// Check terminating byte.
if(fgetc(file_) != 0x1a) throw ErrorNotCSW;
// Get version file number.
uint8_t major_version = (uint8_t)fgetc(file_);
uint8_t minor_version = (uint8_t)fgetc(file_);
// Reject if this is an unknown version.
if(major_version > 2 || !major_version || minor_version > 1) throw ErrorNotCSW;
// The header now diverges based on version.
if(major_version == 1) {
pulse_.length.clock_rate = fgetc16le();
if(fgetc(file_) != 1) throw ErrorNotCSW;
compression_type_ = RLE;
pulse_.type = (fgetc(file_) & 1) ? Pulse::High : Pulse::Low;
fseek(file_, 0x20, SEEK_SET);
} else {
pulse_.length.clock_rate = fgetc32le();
number_of_waves_ = fgetc32le();
switch(fgetc(file_)) {
case 1: compression_type_ = RLE; break;
case 2: compression_type_ = ZRLE; break;
default: throw ErrorNotCSW;
}
pulse_.type = (fgetc(file_) & 1) ? Pulse::High : Pulse::Low;
uint8_t extension_length = (uint8_t)fgetc(file_);
if(file_stats_.st_size < 0x34 + extension_length) throw ErrorNotCSW;
fseek(file_, 0x34 + extension_length, SEEK_SET);
}
if(compression_type_ == ZRLE) {
inflation_stream_.zalloc = Z_NULL;
inflation_stream_.zfree = Z_NULL;
inflation_stream_.opaque = Z_NULL;
inflation_stream_.avail_in = 0;
inflation_stream_.next_in = Z_NULL;
int result = inflateInit(&inflation_stream_);
if(result != Z_OK) throw ErrorNotCSW;
}
} }
CSW::~CSW() {
if(compression_type_ == ZRLE) {
inflateEnd(&inflation_stream_);
}
}
bool CSW::is_at_end() { bool CSW::is_at_end() {
return true; return true;
} }

View File

@ -12,6 +12,8 @@
#include "../Tape.hpp" #include "../Tape.hpp"
#include "../../FileHolder.hpp" #include "../../FileHolder.hpp"
#include <zlib.h>
namespace Storage { namespace Storage {
namespace Tape { namespace Tape {
@ -26,6 +28,7 @@ class CSW: public Tape, public Storage::FileHolder {
@throws ErrorNotCSW if this file could not be opened and recognised as a valid CSW file. @throws ErrorNotCSW if this file could not be opened and recognised as a valid CSW file.
*/ */
CSW(const char *file_name); CSW(const char *file_name);
~CSW();
enum { enum {
ErrorNotCSW ErrorNotCSW
@ -37,6 +40,14 @@ class CSW: public Tape, public Storage::FileHolder {
private: private:
void virtual_reset(); void virtual_reset();
Pulse virtual_get_next_pulse(); Pulse virtual_get_next_pulse();
Pulse pulse_;
enum CompressionType {
RLE,
ZRLE
} compression_type_;
uint32_t number_of_waves_;
z_stream inflation_stream_;
}; };
} }

View File

@ -58,6 +58,8 @@ class Tape {
/// Advances or reverses the tape to the last time before or at @c time from which a pulse starts. /// Advances or reverses the tape to the last time before or at @c time from which a pulse starts.
virtual void seek(Time &time); virtual void seek(Time &time);
virtual ~Tape() {};
private: private:
Time current_time_, next_time_; Time current_time_, next_time_;