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:
parent
3437781abd
commit
84ba4e2900
@ -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> {
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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>";
|
||||||
|
@ -7,3 +7,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Speaker.hpp"
|
#include "Speaker.hpp"
|
||||||
|
|
||||||
|
using namespace Speaker;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
46
SignalProcessing/Stepper.hpp
Normal file
46
SignalProcessing/Stepper.hpp
Normal 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 */
|
Loading…
Reference in New Issue
Block a user