From 2779f0e5690067dfc379ffee47fa9316cc12609c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 18 Jan 2016 15:46:41 -0600 Subject: [PATCH] Statred working on support for at least the most fundamental file format. --- .../Clock Signal.xcodeproj/project.pbxproj | 39 ++++++++++++++++++- .../Documents/ElectronDocument.swift | 11 ++++++ OSBindings/Mac/Clock Signal/Info.plist | 21 +++++++++- .../Mac/Clock Signal/Wrappers/AudioQueue.m | 16 ++++++-- Storage/Tape/Formats/TapeUEF.cpp | 9 +++++ Storage/Tape/Formats/TapeUEF.hpp | 22 +++++++++++ Storage/Tape/Tape.cpp | 16 ++++++++ Storage/Tape/Tape.hpp | 39 +++++++++++++++++++ 8 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 Storage/Tape/Formats/TapeUEF.cpp create mode 100644 Storage/Tape/Formats/TapeUEF.hpp create mode 100644 Storage/Tape/Tape.cpp create mode 100644 Storage/Tape/Tape.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index dfb6aa1f9..5b7f842c8 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; }; 4B55CE5D1C3B7D6F0093A61B /* CSCathodeRayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSCathodeRayView.m */; }; 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */; }; + 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */; }; + 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; }; 4B92EACA1B7C112B00246143 /* TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* TimingTests.swift */; }; 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 */; }; @@ -355,6 +357,10 @@ 4B55CE5B1C3B7D6F0093A61B /* CSCathodeRayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSCathodeRayView.h; sourceTree = ""; }; 4B55CE5C1C3B7D6F0093A61B /* CSCathodeRayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSCathodeRayView.m; sourceTree = ""; }; 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MachineDocument.swift; sourceTree = ""; }; + 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tape.cpp; sourceTree = ""; }; + 4B69FB3C1C4D908A00B5F0AA /* Tape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tape.hpp; sourceTree = ""; }; + 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TapeUEF.cpp; sourceTree = ""; }; + 4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TapeUEF.hpp; sourceTree = ""; }; 4B92EAC91B7C112B00246143 /* TimingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimingTests.swift; sourceTree = ""; }; 4BAE587D1C447B7A005B9AF0 /* KeyCodes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyCodes.h; sourceTree = ""; }; 4BB297DF1B587D8200A49093 /* Clock SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Clock SignalTests-Bridging-Header.h"; sourceTree = ""; }; @@ -768,6 +774,34 @@ path = Views; sourceTree = ""; }; + 4B69FB391C4D908A00B5F0AA /* Storage */ = { + isa = PBXGroup; + children = ( + 4B69FB3A1C4D908A00B5F0AA /* Tape */, + ); + name = Storage; + path = ../../Storage; + sourceTree = ""; + }; + 4B69FB3A1C4D908A00B5F0AA /* Tape */ = { + isa = PBXGroup; + children = ( + 4B69FB411C4D941400B5F0AA /* Formats */, + 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */, + 4B69FB3C1C4D908A00B5F0AA /* Tape.hpp */, + ); + path = Tape; + sourceTree = ""; + }; + 4B69FB411C4D941400B5F0AA /* Formats */ = { + isa = PBXGroup; + children = ( + 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */, + 4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */, + ); + path = Formats; + sourceTree = ""; + }; 4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */ = { isa = PBXGroup; children = ( @@ -1049,8 +1083,9 @@ 4BB73EDC1B587CA500552FC2 /* Machines */, 4B366DFD1B5C165F0026627B /* Outputs */, 4BB73EDD1B587CA500552FC2 /* Processors */, - 4B2409591C45DF85004DA684 /* SignalProcessing */, 4BB73E9F1B587A5100552FC2 /* Products */, + 4B2409591C45DF85004DA684 /* SignalProcessing */, + 4B69FB391C4D908A00B5F0AA /* Storage */, ); sourceTree = ""; }; @@ -1554,9 +1589,11 @@ 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, 4B0EBFB81C487F2F00A11F35 /* AudioQueue.m in Sources */, 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */, + 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */, 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */, 4B55CE4E1C3B3BDA0093A61B /* CSMachine.mm in Sources */, 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */, + 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, 4B55CE5D1C3B7D6F0093A61B /* CSCathodeRayView.m in Sources */, 4B366DFC1B5C165A0026627B /* CRT.cpp in Sources */, 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */, diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift index 9c54ab8b1..75e42624a 100644 --- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift @@ -35,6 +35,17 @@ class ElectronDocument: MachineDocument { return "ElectronDocument" } + override func readFromURL(url: NSURL, ofType typeName: String) throws { + print(url) + print(typeName) + switch typeName { + default: + let fileWrapper = try NSFileWrapper(URL: url, options: NSFileWrapperReadingOptions(rawValue: 0)) + try self.readFromFileWrapper(fileWrapper, ofType: typeName) + break; + } + } + override func readFromData(data: NSData, ofType typeName: String) throws { electron.setROM(data, slot: 15) } diff --git a/OSBindings/Mac/Clock Signal/Info.plist b/OSBindings/Mac/Clock Signal/Info.plist index af40ec174..d761ab5d5 100644 --- a/OSBindings/Mac/Clock Signal/Info.plist +++ b/OSBindings/Mac/Clock Signal/Info.plist @@ -35,7 +35,9 @@ CFBundleTypeName Electron/BBC Tape Image CFBundleTypeRole - Editor + Viewer + LSItemContentTypes + LSTypeIsPackage 0 NSDocumentClass @@ -49,6 +51,23 @@ CFBundleTypeName Electron/BBC ROM Image CFBundleTypeRole + Editor + LSItemContentTypes + + LSTypeIsPackage + 0 + NSDocumentClass + $(PRODUCT_MODULE_NAME).ElectronDocument + + + CFBundleTypeExtensions + + uef + uef.gz + + CFBundleTypeName + Electron/BBC UEF Image + CFBundleTypeRole Viewer LSTypeIsPackage 0 diff --git a/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m b/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m index c762dfc38..ccbcf7712 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m +++ b/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m @@ -10,7 +10,7 @@ @import AudioToolbox; #define AudioQueueNumAudioBuffers 3 -#define AudioQueueStreamLength 2048 +#define AudioQueueStreamLength 32768 #define AudioQueueBufferLength 512 enum { @@ -25,6 +25,10 @@ enum { unsigned int _audioStreamReadPosition, _audioStreamWritePosition; int16_t _audioStream[AudioQueueStreamLength]; NSConditionLock *_writeLock; + +#ifdef DEBUG_INPUT + NSFileHandle * +#endif } @@ -37,7 +41,9 @@ enum { const unsigned int writeLead = _audioStreamWritePosition - _audioStreamReadPosition; const size_t audioDataSampleSize = buffer->mAudioDataByteSize / sizeof(int16_t); - if(writeLead >= audioDataSampleSize*2) + + // TODO: if write lead is too great, skip some audio + if(writeLead >= audioDataSampleSize) { size_t samplesBeforeOverflow = AudioQueueStreamLength - (_audioStreamReadPosition % AudioQueueStreamLength); if(audioDataSampleSize <= samplesBeforeOverflow) @@ -125,6 +131,10 @@ static void audioOutputCallback( - (void)dealloc { + int c = AudioQueueNumAudioBuffers; + while(c--) + AudioQueueFreeBuffer(_audioQueue, _audioBuffers[c]); + if(_audioQueue) AudioQueueDispose(_audioQueue, NO); } @@ -149,7 +159,7 @@ static void audioOutputCallback( - (NSInteger)writeLockCondition { - return ((_audioStreamWritePosition - _audioStreamReadPosition) < AudioQueueStreamLength) ? AudioQueueCanWrite : AudioQueueWait; + return ((_audioStreamWritePosition - _audioStreamReadPosition) < (AudioQueueStreamLength - AudioQueueBufferLength)) ? AudioQueueCanWrite : AudioQueueWait; } @end diff --git a/Storage/Tape/Formats/TapeUEF.cpp b/Storage/Tape/Formats/TapeUEF.cpp new file mode 100644 index 000000000..c724a8c15 --- /dev/null +++ b/Storage/Tape/Formats/TapeUEF.cpp @@ -0,0 +1,9 @@ +// +// TapeUEF.cpp +// Clock Signal +// +// Created by Thomas Harte on 18/01/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "TapeUEF.hpp" diff --git a/Storage/Tape/Formats/TapeUEF.hpp b/Storage/Tape/Formats/TapeUEF.hpp new file mode 100644 index 000000000..5cdf7869e --- /dev/null +++ b/Storage/Tape/Formats/TapeUEF.hpp @@ -0,0 +1,22 @@ +// +// TapeUEF.hpp +// Clock Signal +// +// Created by Thomas Harte on 18/01/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef TapeUEF_hpp +#define TapeUEF_hpp + +#include "../Tape.hpp" + +class UEF : public Storage::Tape { + public: + UEF(const char *file_name); + Cycle get_next_cycle(); + + private: +}; + +#endif /* TapeUEF_hpp */ diff --git a/Storage/Tape/Tape.cpp b/Storage/Tape/Tape.cpp new file mode 100644 index 000000000..e90165245 --- /dev/null +++ b/Storage/Tape/Tape.cpp @@ -0,0 +1,16 @@ +// +// Tape.cpp +// Clock Signal +// +// Created by Thomas Harte on 18/01/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "Tape.hpp" + +using namespace Storage; + +void Tape::seek(Tape::Time seek_time) +{ + // TODO: as best we can +} diff --git a/Storage/Tape/Tape.hpp b/Storage/Tape/Tape.hpp new file mode 100644 index 000000000..022bec740 --- /dev/null +++ b/Storage/Tape/Tape.hpp @@ -0,0 +1,39 @@ +// +// Tape.hpp +// Clock Signal +// +// Created by Thomas Harte on 18/01/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef Tape_hpp +#define Tape_hpp + +#include + +namespace Storage { + +class Tape { + public: + + struct Time { + unsigned int length, clock_rate; + }; + + struct Cycle { + enum { + High, Low, Zero + } type; + Time length; + }; + + virtual Cycle get_next_cycle() = 0; + virtual void reset() = 0; + + virtual void seek(Time seek_time); +}; + +} + + +#endif /* Tape_hpp */