1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Tidied a little, started working towards supporting speaker output.

This commit is contained in:
Thomas Harte 2016-01-12 22:19:56 -05:00
parent 3437781abd
commit 84ba4e2900
5 changed files with 145 additions and 74 deletions

View File

@ -11,6 +11,7 @@
#include "../../Processors/6502/CPU6502.hpp" #include "../../Processors/6502/CPU6502.hpp"
#include "../../Outputs/CRT.hpp" #include "../../Outputs/CRT.hpp"
#include "../../Outputs/Speaker.hpp"
#include <stdint.h> #include <stdint.h>
#include "Atari2600Inputs.h" #include "Atari2600Inputs.h"
@ -38,73 +39,20 @@ enum Interrupt: uint8_t {
}; };
enum Key: uint16_t { enum Key: uint16_t {
KeySpace = 0x0000 | 0x08, KeySpace = 0x0000 | 0x08, KeyCopy = 0x0000 | 0x02, KeyRight = 0x0000 | 0x01,
KeyCopy = 0x0000 | 0x02, KeyDelete = 0x0010 | 0x08, KeyReturn = 0x0010 | 0x04, KeyDown = 0x0010 | 0x02, KeyLeft = 0x0010 | 0x01,
KeyRight = 0x0000 | 0x01, KeyColon = 0x0020 | 0x04, KeyUp = 0x0020 | 0x02, KeyMinus = 0x0020 | 0x01,
KeySlash = 0x0030 | 0x08, KeySemiColon = 0x0030 | 0x04, KeyP = 0x0030 | 0x02, Key0 = 0x0030 | 0x01,
KeyDelete = 0x0010 | 0x08, KeyFullStop = 0x0040 | 0x08, KeyL = 0x0040 | 0x04, KeyO = 0x0040 | 0x02, Key9 = 0x0040 | 0x01,
KeyReturn = 0x0010 | 0x04, KeyComma = 0x0050 | 0x08, KeyK = 0x0050 | 0x04, KeyI = 0x0050 | 0x02, Key8 = 0x0050 | 0x01,
KeyDown = 0x0010 | 0x02, KeyM = 0x0060 | 0x08, KeyJ = 0x0060 | 0x04, KeyU = 0x0060 | 0x02, Key7 = 0x0060 | 0x01,
KeyLeft = 0x0010 | 0x01, KeyN = 0x0070 | 0x08, KeyH = 0x0070 | 0x04, KeyY = 0x0070 | 0x02, Key6 = 0x0070 | 0x01,
KeyB = 0x0080 | 0x08, KeyG = 0x0080 | 0x04, KeyT = 0x0080 | 0x02, Key5 = 0x0080 | 0x01,
KeyColon = 0x0020 | 0x04, KeyV = 0x0090 | 0x08, KeyF = 0x0090 | 0x04, KeyR = 0x0090 | 0x02, Key4 = 0x0090 | 0x01,
KeyUp = 0x0020 | 0x02, KeyC = 0x00a0 | 0x08, KeyD = 0x00a0 | 0x04, KeyE = 0x00a0 | 0x02, Key3 = 0x00a0 | 0x01,
KeyMinus = 0x0020 | 0x01, KeyX = 0x00b0 | 0x08, KeyS = 0x00b0 | 0x04, KeyW = 0x00b0 | 0x02, Key2 = 0x00b0 | 0x01,
KeyZ = 0x00c0 | 0x08, KeyA = 0x00c0 | 0x04, KeyQ = 0x00c0 | 0x02, Key1 = 0x00c0 | 0x01,
KeySlash = 0x0030 | 0x08, KeyShift = 0x00d0 | 0x08, KeyControl = 0x00d0 | 0x04, KeyFunc = 0x00d0 | 0x02, KeyEscape = 0x00d0 | 0x01,
KeySemiColon = 0x0030 | 0x04,
KeyP = 0x0030 | 0x02,
Key0 = 0x0030 | 0x01,
KeyFullStop = 0x0040 | 0x08,
KeyL = 0x0040 | 0x04,
KeyO = 0x0040 | 0x02,
Key9 = 0x0040 | 0x01,
KeyComma = 0x0050 | 0x08,
KeyK = 0x0050 | 0x04,
KeyI = 0x0050 | 0x02,
Key8 = 0x0050 | 0x01,
KeyM = 0x0060 | 0x08,
KeyJ = 0x0060 | 0x04,
KeyU = 0x0060 | 0x02,
Key7 = 0x0060 | 0x01,
KeyN = 0x0070 | 0x08,
KeyH = 0x0070 | 0x04,
KeyY = 0x0070 | 0x02,
Key6 = 0x0070 | 0x01,
KeyB = 0x0080 | 0x08,
KeyG = 0x0080 | 0x04,
KeyT = 0x0080 | 0x02,
Key5 = 0x0080 | 0x01,
KeyV = 0x0090 | 0x08,
KeyF = 0x0090 | 0x04,
KeyR = 0x0090 | 0x02,
Key4 = 0x0090 | 0x01,
KeyC = 0x00a0 | 0x08,
KeyD = 0x00a0 | 0x04,
KeyE = 0x00a0 | 0x02,
Key3 = 0x00a0 | 0x01,
KeyX = 0x00b0 | 0x08,
KeyS = 0x00b0 | 0x04,
KeyW = 0x00b0 | 0x02,
Key2 = 0x00b0 | 0x01,
KeyZ = 0x00c0 | 0x08,
KeyA = 0x00c0 | 0x04,
KeyQ = 0x00c0 | 0x02,
Key1 = 0x00c0 | 0x01,
KeyShift = 0x00d0 | 0x08,
KeyControl = 0x00d0 | 0x04,
KeyFunc = 0x00d0 | 0x02,
KeyEscape = 0x00d0 | 0x01,
KeyBreak = 0xffff KeyBreak = 0xffff
}; };
@ -143,6 +91,9 @@ class Machine: public CPU6502::Processor<Machine> {
inline void update_display(); inline void update_display();
inline void signal_interrupt(Interrupt interrupt); inline void signal_interrupt(Interrupt interrupt);
inline void evaluate_interrupts(); inline void evaluate_interrupts();
class Speaker: public ::Speaker::Filter<Speaker> {
};
}; };
} }

View File

@ -330,6 +330,7 @@
4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = "<group>"; }; 4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = "<group>"; };
4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = "<group>"; }; 4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = "<group>"; };
4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = "<group>"; }; 4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = "<group>"; };
4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = "<group>"; };
4B2632551B631A510082A461 /* CRTFrame.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CRTFrame.h; path = ../../Outputs/CRTFrame.h; sourceTree = "<group>"; }; 4B2632551B631A510082A461 /* CRTFrame.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CRTFrame.h; path = ../../Outputs/CRTFrame.h; sourceTree = "<group>"; };
4B2E2D941C399D1200138695 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ElectronDocument.xib; sourceTree = "<group>"; }; 4B2E2D941C399D1200138695 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ElectronDocument.xib; sourceTree = "<group>"; };
4B2E2D971C3A06EC00138695 /* Atari2600.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atari2600.cpp; sourceTree = "<group>"; }; 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atari2600.cpp; sourceTree = "<group>"; };
@ -686,6 +687,15 @@
name = "Test Binaries"; name = "Test Binaries";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
4B2409591C45DF85004DA684 /* SignalProcessing */ = {
isa = PBXGroup;
children = (
4B24095A1C45DF85004DA684 /* Stepper.hpp */,
);
name = SignalProcessing;
path = ../../SignalProcessing;
sourceTree = "<group>";
};
4B2E2D961C3A06EC00138695 /* Atari2600 */ = { 4B2E2D961C3A06EC00138695 /* Atari2600 */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1028,12 +1038,13 @@
4BB73E951B587A5100552FC2 = { 4BB73E951B587A5100552FC2 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B366DFD1B5C165F0026627B /* Outputs */,
4BB73EDC1B587CA500552FC2 /* Machines */,
4BB73EDD1B587CA500552FC2 /* Processors */,
4BB73EA01B587A5100552FC2 /* Clock Signal */, 4BB73EA01B587A5100552FC2 /* Clock Signal */,
4BB73EB51B587A5100552FC2 /* Clock SignalTests */, 4BB73EB51B587A5100552FC2 /* Clock SignalTests */,
4BB73EC01B587A5100552FC2 /* Clock SignalUITests */, 4BB73EC01B587A5100552FC2 /* Clock SignalUITests */,
4BB73EDC1B587CA500552FC2 /* Machines */,
4B366DFD1B5C165F0026627B /* Outputs */,
4BB73EDD1B587CA500552FC2 /* Processors */,
4B2409591C45DF85004DA684 /* SignalProcessing */,
4BB73E9F1B587A5100552FC2 /* Products */, 4BB73E9F1B587A5100552FC2 /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";

View File

@ -7,3 +7,6 @@
// //
#include "Speaker.hpp" #include "Speaker.hpp"
using namespace Speaker;

View File

@ -10,6 +10,7 @@
#define Speaker_hpp #define Speaker_hpp
#include <stdint.h> #include <stdint.h>
#include "../SignalProcessing/Stepper.hpp"
namespace Speaker { namespace Speaker {
@ -20,11 +21,70 @@ class Delegate {
template <class T> class Filter { template <class T> class Filter {
public: public:
void set_output_rate(int cycles_per_second); void set_output_rate(int cycles_per_second, int buffer_size)
void set_delegate(Delegate *delegate); {
_output_cycles_per_second = cycles_per_second;
if(_buffer_size != buffer_size)
{
delete[] _buffer_in_progress;
_buffer_in_progress = new uint16_t[buffer_size];
_buffer_size = buffer_size;
}
set_needs_updated_filter_coefficients();
}
void set_input_rate(int cycles_per_second); void set_output_quality(int number_of_taps)
void run_for_cycles(int input_cycles); {
_number_of_taps = number_of_taps;
set_needs_updated_filter_coefficients();
}
void set_delegate(Delegate *delegate)
{
_delegate = delegate;
}
void set_input_rate(int cycles_per_second)
{
_input_cycles_per_second = cycles_per_second;
set_needs_updated_filter_coefficients();
}
void run_for_cycles(int input_cycles)
{
if(_coefficients_are_dirty) update_filter_coefficients();
// point sample for now, as a temporary measure
while(input_cycles--)
{
static_cast<T *>(this)->perform_bus_operation();
}
}
private:
uint16_t *_buffer_in_progress;
int _buffer_size;
int _buffer_in_progress_pointer;
int _number_of_taps;
bool _coefficients_are_dirty;
Delegate *_delegate;
SignalProcessing::Stepper *_stepper;
int _input_cycles_per_second, _output_cycles_per_second;
void set_needs_updated_filter_coefficients()
{
_coefficients_are_dirty = true;
}
void update_filter_coefficients()
{
_coefficients_are_dirty = false;
_buffer_in_progress_pointer = 0;
delete[] _stepper;
_stepper = Stepper(_input_cycles_per_second, _output_cycles_per_second);
}
}; };
} }

View File

@ -0,0 +1,46 @@
//
// Stepper.hpp
// Clock Signal
//
// Created by Thomas Harte on 12/01/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#ifndef Stepper_hpp
#define Stepper_hpp
#include <stdint.h>
namespace SignalProcessing {
class Stepper
{
public:
Stepper(uint64_t input_rate, uint64_t output_rate)
{
whole_step_ = output_rate / input_rate;
adjustment_up_ = (int64_t)(output_rate % input_rate) << 1;
adjustment_down_ = (int64_t)input_rate << 1;
}
inline uint64_t update()
{
uint64_t update = whole_step_;
accumulated_error_ += adjustment_up_;
if(accumulated_error_ > 0)
{
update++;
accumulated_error_ -= adjustment_down_;
}
return update;
}
private:
uint64_t whole_step_;
int64_t adjustment_up_, adjustment_down_;
int64_t accumulated_error_;
};
}
#endif /* Stepper_hpp */