mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-02 19:54:35 +00:00
Made an attempt quickly to implement parsing of the Commodore .TAP file format.
This commit is contained in:
parent
e9bf9034e3
commit
ee19417ded
@ -320,6 +320,7 @@
|
|||||||
4BC751B61D157EB3006C31D9 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B51D157EB3006C31D9 /* MOS6522Bridge.mm */; };
|
4BC751B61D157EB3006C31D9 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B51D157EB3006C31D9 /* MOS6522Bridge.mm */; };
|
||||||
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
||||||
4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; };
|
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 */; };
|
4BC9DF451D044FCA00F44158 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; };
|
||||||
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
|
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; };
|
||||||
4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */; };
|
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>"; };
|
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>"; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
4BC9DF4E1D04691600F44158 /* 6560.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6560.hpp; sourceTree = "<group>"; };
|
||||||
@ -900,6 +903,8 @@
|
|||||||
4B69FB451C4D950F00B5F0AA /* libz.tbd */,
|
4B69FB451C4D950F00B5F0AA /* libz.tbd */,
|
||||||
4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */,
|
4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */,
|
||||||
4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */,
|
4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */,
|
||||||
|
4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */,
|
||||||
|
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */,
|
||||||
);
|
);
|
||||||
path = Formats;
|
path = Formats;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1793,6 +1798,7 @@
|
|||||||
4BC3B7521CD1956900F86E85 /* OutputShader.cpp in Sources */,
|
4BC3B7521CD1956900F86E85 /* OutputShader.cpp in Sources */,
|
||||||
4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */,
|
4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */,
|
||||||
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
|
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
|
||||||
|
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */,
|
||||||
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
|
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
|
||||||
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */,
|
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
@ -88,6 +88,18 @@
|
|||||||
<key>NSDocumentClass</key>
|
<key>NSDocumentClass</key>
|
||||||
<string>$(PRODUCT_MODULE_NAME).Vic20Document</string>
|
<string>$(PRODUCT_MODULE_NAME).Vic20Document</string>
|
||||||
</dict>
|
</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>
|
</array>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
91
Storage/Tape/Formats/CommodoreTAP.cpp
Normal file
91
Storage/Tape/Formats/CommodoreTAP.cpp
Normal 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;
|
||||||
|
}
|
39
Storage/Tape/Formats/CommodoreTAP.hpp
Normal file
39
Storage/Tape/Formats/CommodoreTAP.hpp
Normal 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 */
|
Loading…
Reference in New Issue
Block a user