1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-02 20:30:00 +00:00

Made an attempt quickly to implement parsing of the Commodore .TAP file format.

This commit is contained in:
Thomas Harte 2016-06-25 16:09:32 -04:00
parent e9bf9034e3
commit ee19417ded
4 changed files with 148 additions and 0 deletions

View File

@ -320,6 +320,7 @@
4BC751B61D157EB3006C31D9 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B51D157EB3006C31D9 /* MOS6522Bridge.mm */; };
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; };
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; };
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */; };
@ -701,6 +702,8 @@
4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = "<group>"; };
4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = "<group>"; };
4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommodoreTAP.cpp; sourceTree = "<group>"; };
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CommodoreTAP.hpp; sourceTree = "<group>"; };
4BC9DF441D044FCA00F44158 /* ROMImages */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ROMImages; path = ../../../../ROMImages; sourceTree = "<group>"; };
4BC9DF4D1D04691600F44158 /* 6560.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6560.cpp; sourceTree = "<group>"; };
4BC9DF4E1D04691600F44158 /* 6560.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6560.hpp; sourceTree = "<group>"; };
@ -900,6 +903,8 @@
4B69FB451C4D950F00B5F0AA /* libz.tbd */,
4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */,
4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */,
4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */,
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */,
);
path = Formats;
sourceTree = "<group>";
@ -1793,6 +1798,7 @@
4BC3B7521CD1956900F86E85 /* OutputShader.cpp in Sources */,
4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */,
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */,
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */,
);

View File

@ -88,6 +88,18 @@
<key>NSDocumentClass</key>
<string>$(PRODUCT_MODULE_NAME).Vic20Document</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tap</string>
</array>
<key>CFBundleTypeName</key>
<string>Vic-20 Tape Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>NSDocumentClass</key>
<string>Vic20Document</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>

View File

@ -0,0 +1,91 @@
//
// CommodoreTAP.cpp
// Clock Signal
//
// Created by Thomas Harte on 25/06/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#include "CommodoreTAP.hpp"
#include <cstdio>
#include <cstring>
using namespace Storage;
CommodoreTAP::CommodoreTAP(const char *file_name)
{
_file = fopen(file_name, "rb");
if(!_file)
throw ErrorNotCommodoreTAP;
// read and check the file signature
char signature[12];
if(fread(signature, 1, 12, _file) != 12)
throw ErrorNotCommodoreTAP;
if(memcmp(signature, "C64-TAPE-RAW", 12))
throw ErrorNotCommodoreTAP;
// check the file version
int version = fgetc(_file);
switch(version)
{
case 0: _updated_layout = false; break;
case 1: _updated_layout = true; break;
default: throw ErrorNotCommodoreTAP;
}
// skip reserved bytes
fseek(_file, 3, SEEK_CUR);
// read file size
_file_size = (uint32_t)fgetc(_file);
_file_size |= (uint32_t)(fgetc(_file) << 8);
_file_size |= (uint32_t)(fgetc(_file) << 16);
_file_size |= (uint32_t)(fgetc(_file) << 24);
// set up for pulse output at the PAL clock rate, with each high and
// low being half of whatever length values will be read; pretend that
// a high pulse has just been distributed to imply that the next thing
// that needs to happen is a length check
_current_pulse.length.clock_rate = 985248 * 2;
_current_pulse.type = Pulse::High;
}
CommodoreTAP::~CommodoreTAP()
{
fclose(_file);
}
void CommodoreTAP::reset()
{
fseek(_file, 0x14, SEEK_SET);
_current_pulse.type = Pulse::High;
}
CommodoreTAP::Pulse CommodoreTAP::get_next_pulse()
{
if(_current_pulse.type == Pulse::High)
{
uint32_t next_length;
uint8_t next_byte = (uint8_t)fgetc(_file);
if(!_updated_layout || next_byte > 0)
{
next_length = (uint32_t)next_byte << 3;
}
else
{
next_length = (uint32_t)fgetc(_file);
next_length |= (uint32_t)(fgetc(_file) << 8);
next_length |= (uint32_t)(fgetc(_file) << 16);
}
_current_pulse.length.length = next_length;
_current_pulse.type = Pulse::Low;
}
else
_current_pulse.type = Pulse::High;
return _current_pulse;
}

View File

@ -0,0 +1,39 @@
//
// CommodoreTAP.hpp
// Clock Signal
//
// Created by Thomas Harte on 25/06/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#ifndef CommodoreTAP_hpp
#define CommodoreTAP_hpp
#include "../Tape.hpp"
#include <stdint.h>
namespace Storage {
class CommodoreTAP: public Tape {
public:
CommodoreTAP(const char *file_name);
~CommodoreTAP();
Pulse get_next_pulse();
void reset();
enum {
ErrorNotCommodoreTAP
};
private:
FILE *_file;
bool _updated_layout;
uint32_t _file_size;
Pulse _current_pulse;
};
}
#endif /* CommodoreTAP_hpp */