mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +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 "../../Outputs/CRT.hpp"
|
||||
#include "../../Outputs/Speaker.hpp"
|
||||
#include <stdint.h>
|
||||
#include "Atari2600Inputs.h"
|
||||
|
||||
@ -38,73 +39,20 @@ enum Interrupt: uint8_t {
|
||||
};
|
||||
|
||||
enum Key: uint16_t {
|
||||
KeySpace = 0x0000 | 0x08,
|
||||
KeyCopy = 0x0000 | 0x02,
|
||||
KeyRight = 0x0000 | 0x01,
|
||||
|
||||
KeyDelete = 0x0010 | 0x08,
|
||||
KeyReturn = 0x0010 | 0x04,
|
||||
KeyDown = 0x0010 | 0x02,
|
||||
KeyLeft = 0x0010 | 0x01,
|
||||
|
||||
KeyColon = 0x0020 | 0x04,
|
||||
KeyUp = 0x0020 | 0x02,
|
||||
KeyMinus = 0x0020 | 0x01,
|
||||
|
||||
KeySlash = 0x0030 | 0x08,
|
||||
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,
|
||||
KeySpace = 0x0000 | 0x08, KeyCopy = 0x0000 | 0x02, KeyRight = 0x0000 | 0x01,
|
||||
KeyDelete = 0x0010 | 0x08, KeyReturn = 0x0010 | 0x04, KeyDown = 0x0010 | 0x02, KeyLeft = 0x0010 | 0x01,
|
||||
KeyColon = 0x0020 | 0x04, KeyUp = 0x0020 | 0x02, KeyMinus = 0x0020 | 0x01,
|
||||
KeySlash = 0x0030 | 0x08, 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
|
||||
};
|
||||
@ -143,6 +91,9 @@ class Machine: public CPU6502::Processor<Machine> {
|
||||
inline void update_display();
|
||||
inline void signal_interrupt(Interrupt interrupt);
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -686,6 +687,15 @@
|
||||
name = "Test Binaries";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B2409591C45DF85004DA684 /* SignalProcessing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B24095A1C45DF85004DA684 /* Stepper.hpp */,
|
||||
);
|
||||
name = SignalProcessing;
|
||||
path = ../../SignalProcessing;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B2E2D961C3A06EC00138695 /* Atari2600 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1028,12 +1038,13 @@
|
||||
4BB73E951B587A5100552FC2 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B366DFD1B5C165F0026627B /* Outputs */,
|
||||
4BB73EDC1B587CA500552FC2 /* Machines */,
|
||||
4BB73EDD1B587CA500552FC2 /* Processors */,
|
||||
4BB73EA01B587A5100552FC2 /* Clock Signal */,
|
||||
4BB73EB51B587A5100552FC2 /* Clock SignalTests */,
|
||||
4BB73EC01B587A5100552FC2 /* Clock SignalUITests */,
|
||||
4BB73EDC1B587CA500552FC2 /* Machines */,
|
||||
4B366DFD1B5C165F0026627B /* Outputs */,
|
||||
4BB73EDD1B587CA500552FC2 /* Processors */,
|
||||
4B2409591C45DF85004DA684 /* SignalProcessing */,
|
||||
4BB73E9F1B587A5100552FC2 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
|
@ -7,3 +7,6 @@
|
||||
//
|
||||
|
||||
#include "Speaker.hpp"
|
||||
|
||||
using namespace Speaker;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define Speaker_hpp
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../SignalProcessing/Stepper.hpp"
|
||||
|
||||
namespace Speaker {
|
||||
|
||||
@ -20,11 +21,70 @@ class Delegate {
|
||||
|
||||
template <class T> class Filter {
|
||||
public:
|
||||
void set_output_rate(int cycles_per_second);
|
||||
void set_delegate(Delegate *delegate);
|
||||
void set_output_rate(int cycles_per_second, int buffer_size)
|
||||
{
|
||||
_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 run_for_cycles(int input_cycles);
|
||||
void set_output_quality(int number_of_taps)
|
||||
{
|
||||
_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