mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-25 17:29:40 +00:00
Attempted to introduce a lowpass filter to the graphics output, reverted 6502 optimisations as seemingly not working.
This commit is contained in:
parent
5db0f9e2d5
commit
3038704977
@ -35,7 +35,7 @@
|
|||||||
<key>CFBundleTypeName</key>
|
<key>CFBundleTypeName</key>
|
||||||
<string>Electron/BBC Tape Image</string>
|
<string>Electron/BBC Tape Image</string>
|
||||||
<key>CFBundleTypeRole</key>
|
<key>CFBundleTypeRole</key>
|
||||||
<string>Viewer</string>
|
<string>Editor</string>
|
||||||
<key>LSItemContentTypes</key>
|
<key>LSItemContentTypes</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>LSTypeIsPackage</key>
|
<key>LSTypeIsPackage</key>
|
||||||
@ -51,7 +51,7 @@
|
|||||||
<key>CFBundleTypeName</key>
|
<key>CFBundleTypeName</key>
|
||||||
<string>Electron/BBC ROM Image</string>
|
<string>Electron/BBC ROM Image</string>
|
||||||
<key>CFBundleTypeRole</key>
|
<key>CFBundleTypeRole</key>
|
||||||
<string>Editor</string>
|
<string>Viewer</string>
|
||||||
<key>LSItemContentTypes</key>
|
<key>LSItemContentTypes</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>LSTypeIsPackage</key>
|
<key>LSTypeIsPackage</key>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "CRTOpenGL.hpp"
|
#include "CRTOpenGL.hpp"
|
||||||
|
#include "../../../SignalProcessing/FIRFilter.hpp"
|
||||||
|
|
||||||
using namespace Outputs::CRT;
|
using namespace Outputs::CRT;
|
||||||
|
|
||||||
@ -342,6 +343,7 @@ char *OpenGLOutputBuilder::get_output_vertex_shader()
|
|||||||
"uniform float ticksPerFrame;"
|
"uniform float ticksPerFrame;"
|
||||||
"uniform vec2 positionConversion;"
|
"uniform vec2 positionConversion;"
|
||||||
"uniform vec2 scanNormal;"
|
"uniform vec2 scanNormal;"
|
||||||
|
"uniform vec3 filterCoefficients;"
|
||||||
|
|
||||||
"const float shadowMaskMultiple = 600;"
|
"const float shadowMaskMultiple = 600;"
|
||||||
|
|
||||||
@ -355,7 +357,9 @@ char *OpenGLOutputBuilder::get_output_vertex_shader()
|
|||||||
|
|
||||||
"srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);"
|
"srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);"
|
||||||
"float age = (timestampBase - timestamp) / ticksPerFrame;"
|
"float age = (timestampBase - timestamp) / ticksPerFrame;"
|
||||||
"alpha = min(10.0 * exp(-age * 2.0), 1.0);"
|
"vec3 alphas = vec3(10.0 * exp((-age - 0.66) * 2.0), 10.0 * exp(-(age - 0.33) * 2.0), 10.0 * exp(-age * 2.0));"
|
||||||
|
// "alpha = min(10.0 * exp(-age * 2.0), 1.0);"
|
||||||
|
"alpha = dot(alphas, filterCoefficients);"
|
||||||
|
|
||||||
"vec2 floatingPosition = (position / positionConversion) + lateral*scanNormal;"
|
"vec2 floatingPosition = (position / positionConversion) + lateral*scanNormal;"
|
||||||
"vec2 mappedPosition = (floatingPosition - boundsOrigin) / boundsSize;"
|
"vec2 mappedPosition = (floatingPosition - boundsOrigin) / boundsSize;"
|
||||||
@ -499,6 +503,7 @@ void OpenGLOutputBuilder::prepare_rgb_output_shader()
|
|||||||
GLint ticksPerFrameUniform = rgb_shader_program->get_uniform_location("ticksPerFrame");
|
GLint ticksPerFrameUniform = rgb_shader_program->get_uniform_location("ticksPerFrame");
|
||||||
GLint scanNormalUniform = rgb_shader_program->get_uniform_location("scanNormal");
|
GLint scanNormalUniform = rgb_shader_program->get_uniform_location("scanNormal");
|
||||||
GLint positionConversionUniform = rgb_shader_program->get_uniform_location("positionConversion");
|
GLint positionConversionUniform = rgb_shader_program->get_uniform_location("positionConversion");
|
||||||
|
GLint filterCoefficients = rgb_shader_program->get_uniform_location("filterCoefficients");
|
||||||
|
|
||||||
glUniform1i(texIDUniform, first_supplied_buffer_texture_unit);
|
glUniform1i(texIDUniform, first_supplied_buffer_texture_unit);
|
||||||
glUniform1i(shadowMaskTexIDUniform, 1);
|
glUniform1i(shadowMaskTexIDUniform, 1);
|
||||||
@ -506,6 +511,11 @@ void OpenGLOutputBuilder::prepare_rgb_output_shader()
|
|||||||
glUniform1f(ticksPerFrameUniform, (GLfloat)(_cycles_per_line * _height_of_display));
|
glUniform1f(ticksPerFrameUniform, (GLfloat)(_cycles_per_line * _height_of_display));
|
||||||
glUniform2f(positionConversionUniform, _horizontal_scan_period, _vertical_scan_period / (unsigned int)_vertical_period_divider);
|
glUniform2f(positionConversionUniform, _horizontal_scan_period, _vertical_scan_period / (unsigned int)_vertical_period_divider);
|
||||||
|
|
||||||
|
SignalProcessing::FIRFilter filter(3, 3 * 50, 0, 25, SignalProcessing::FIRFilter::DefaultAttenuation);
|
||||||
|
float coefficients[3];
|
||||||
|
filter.get_coefficients(coefficients);
|
||||||
|
glUniform3fv(filterCoefficients, 1, coefficients);
|
||||||
|
|
||||||
float scan_angle = atan2f(1.0f / (float)_height_of_display, 1.0f);
|
float scan_angle = atan2f(1.0f / (float)_height_of_display, 1.0f);
|
||||||
float scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
|
float scan_normal[] = { -sinf(scan_angle), cosf(scan_angle)};
|
||||||
float multiplier = (float)_cycles_per_line / ((float)_height_of_display * (float)_horizontal_scan_period);
|
float multiplier = (float)_cycles_per_line / ((float)_height_of_display * (float)_horizontal_scan_period);
|
||||||
|
@ -550,13 +550,6 @@ template <class T> class Processor {
|
|||||||
// to date in this stack frame only); which saves some complicated addressing
|
// to date in this stack frame only); which saves some complicated addressing
|
||||||
unsigned int scheduleProgramsReadPointer = _scheduleProgramsReadPointer;
|
unsigned int scheduleProgramsReadPointer = _scheduleProgramsReadPointer;
|
||||||
unsigned int scheduleProgramProgramCounter = _scheduleProgramProgramCounter;
|
unsigned int scheduleProgramProgramCounter = _scheduleProgramProgramCounter;
|
||||||
uint8_t operand = _operand;
|
|
||||||
uint8_t operation = _operation;
|
|
||||||
RegisterPair address = _address;
|
|
||||||
RegisterPair nextAddress = _nextAddress;
|
|
||||||
BusOperation nextBusOperation = _nextBusOperation;
|
|
||||||
uint16_t busAddress = _busAddress;
|
|
||||||
uint8_t *busValue = _busValue;
|
|
||||||
|
|
||||||
#define checkSchedule(op) \
|
#define checkSchedule(op) \
|
||||||
if(!_scheduledPrograms[scheduleProgramsReadPointer]) {\
|
if(!_scheduledPrograms[scheduleProgramsReadPointer]) {\
|
||||||
@ -580,25 +573,25 @@ template <class T> class Processor {
|
|||||||
while(number_of_cycles > 0) {
|
while(number_of_cycles > 0) {
|
||||||
|
|
||||||
while (_ready_is_active && number_of_cycles > 0) {
|
while (_ready_is_active && number_of_cycles > 0) {
|
||||||
number_of_cycles -= static_cast<T *>(this)->perform_bus_operation(BusOperation::Ready, busAddress, busValue);
|
number_of_cycles -= static_cast<T *>(this)->perform_bus_operation(BusOperation::Ready, _busAddress, _busValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!_ready_is_active && number_of_cycles > 0) {
|
while (!_ready_is_active && number_of_cycles > 0) {
|
||||||
|
|
||||||
if (nextBusOperation != BusOperation::None) {
|
if (_nextBusOperation != BusOperation::None) {
|
||||||
_irq_request_history[0] = _irq_request_history[1];
|
_irq_request_history[0] = _irq_request_history[1];
|
||||||
_irq_request_history[1] = _irq_line_is_enabled && !_interruptFlag;
|
_irq_request_history[1] = _irq_line_is_enabled && !_interruptFlag;
|
||||||
number_of_cycles -= static_cast<T *>(this)->perform_bus_operation(nextBusOperation, busAddress, busValue);
|
number_of_cycles -= static_cast<T *>(this)->perform_bus_operation(_nextBusOperation, _busAddress, _busValue);
|
||||||
nextBusOperation = BusOperation::None;
|
_nextBusOperation = BusOperation::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MicroOp cycle = program[scheduleProgramProgramCounter];
|
const MicroOp cycle = program[scheduleProgramProgramCounter];
|
||||||
scheduleProgramProgramCounter++;
|
scheduleProgramProgramCounter++;
|
||||||
|
|
||||||
#define read_op(val, addr) nextBusOperation = BusOperation::ReadOpcode; busAddress = addr; busValue = &val
|
#define read_op(val, addr) _nextBusOperation = BusOperation::ReadOpcode; _busAddress = addr; _busValue = &val
|
||||||
#define read_mem(val, addr) nextBusOperation = BusOperation::Read; busAddress = addr; busValue = &val
|
#define read_mem(val, addr) _nextBusOperation = BusOperation::Read; _busAddress = addr; _busValue = &val
|
||||||
#define throwaway_read(addr) nextBusOperation = BusOperation::Read; busAddress = addr; busValue = &throwaway_target
|
#define throwaway_read(addr) _nextBusOperation = BusOperation::Read; _busAddress = addr; _busValue = &throwaway_target
|
||||||
#define write_mem(val, addr) nextBusOperation = BusOperation::Write; busAddress = addr; busValue = &val
|
#define write_mem(val, addr) _nextBusOperation = BusOperation::Write; _busAddress = addr; _busValue = &val
|
||||||
|
|
||||||
switch(cycle) {
|
switch(cycle) {
|
||||||
|
|
||||||
@ -607,7 +600,7 @@ template <class T> class Processor {
|
|||||||
case CycleFetchOperation: {
|
case CycleFetchOperation: {
|
||||||
_lastOperationPC = _pc;
|
_lastOperationPC = _pc;
|
||||||
_pc.full++;
|
_pc.full++;
|
||||||
read_op(operation, _lastOperationPC.full);
|
read_op(_operation, _lastOperationPC.full);
|
||||||
|
|
||||||
// static int last_cycles_left_to_run = 0;
|
// static int last_cycles_left_to_run = 0;
|
||||||
// static bool printed_map[256] = {false};
|
// static bool printed_map[256] = {false};
|
||||||
@ -622,11 +615,11 @@ template <class T> class Processor {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CycleFetchOperand:
|
case CycleFetchOperand:
|
||||||
read_mem(operand, _pc.full);
|
read_mem(_operand, _pc.full);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationDecodeOperation:
|
case OperationDecodeOperation:
|
||||||
decode_operation(operation);
|
decode_operation(_operation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationMoveToNextProgram:
|
case OperationMoveToNextProgram:
|
||||||
@ -646,7 +639,7 @@ template <class T> class Processor {
|
|||||||
case CycleIncPCPushPCH: _pc.full++; // deliberate fallthrough
|
case CycleIncPCPushPCH: _pc.full++; // deliberate fallthrough
|
||||||
case CyclePushPCH: push(_pc.bytes.high); break;
|
case CyclePushPCH: push(_pc.bytes.high); break;
|
||||||
case CyclePushPCL: push(_pc.bytes.low); break;
|
case CyclePushPCL: push(_pc.bytes.low); break;
|
||||||
case CyclePushOperand: push(operand); break;
|
case CyclePushOperand: push(_operand); break;
|
||||||
case CyclePushA: push(_a); break;
|
case CyclePushA: push(_a); break;
|
||||||
|
|
||||||
#undef push
|
#undef push
|
||||||
@ -662,15 +655,15 @@ template <class T> class Processor {
|
|||||||
case CyclePullPCL: _s++; read_mem(_pc.bytes.low, _s | 0x100); break;
|
case CyclePullPCL: _s++; read_mem(_pc.bytes.low, _s | 0x100); break;
|
||||||
case CyclePullPCH: _s++; read_mem(_pc.bytes.high, _s | 0x100); break;
|
case CyclePullPCH: _s++; read_mem(_pc.bytes.high, _s | 0x100); break;
|
||||||
case CyclePullA: _s++; read_mem(_a, _s | 0x100); break;
|
case CyclePullA: _s++; read_mem(_a, _s | 0x100); break;
|
||||||
case CyclePullOperand: _s++; read_mem(operand, _s | 0x100); break;
|
case CyclePullOperand: _s++; read_mem(_operand, _s | 0x100); break;
|
||||||
case OperationSetFlagsFromOperand: set_flags(operand); break;
|
case OperationSetFlagsFromOperand: set_flags(_operand); break;
|
||||||
case OperationSetOperandFromFlagsWithBRKSet: operand = get_flags() | Flag::Break; break;
|
case OperationSetOperandFromFlagsWithBRKSet: _operand = get_flags() | Flag::Break; break;
|
||||||
case OperationSetOperandFromFlags: operand = get_flags(); break;
|
case OperationSetOperandFromFlags: _operand = get_flags(); break;
|
||||||
case OperationSetFlagsFromA: _zeroResult = _negativeResult = _a; break;
|
case OperationSetFlagsFromA: _zeroResult = _negativeResult = _a; break;
|
||||||
|
|
||||||
case CycleIncrementPCAndReadStack: _pc.full++; throwaway_read(_s | 0x100); break;
|
case CycleIncrementPCAndReadStack: _pc.full++; throwaway_read(_s | 0x100); break;
|
||||||
case CycleReadPCLFromAddress: read_mem(_pc.bytes.low, address.full); break;
|
case CycleReadPCLFromAddress: read_mem(_pc.bytes.low, _address.full); break;
|
||||||
case CycleReadPCHFromAddress: address.bytes.low++; read_mem(_pc.bytes.high, address.full); break;
|
case CycleReadPCHFromAddress: _address.bytes.low++; read_mem(_pc.bytes.high, _address.full); break;
|
||||||
|
|
||||||
case CycleReadAndIncrementPC: {
|
case CycleReadAndIncrementPC: {
|
||||||
uint16_t oldPC = _pc.full;
|
uint16_t oldPC = _pc.full;
|
||||||
@ -693,45 +686,45 @@ template <class T> class Processor {
|
|||||||
|
|
||||||
#pragma mark - Bitwise
|
#pragma mark - Bitwise
|
||||||
|
|
||||||
case OperationORA: _a |= operand; _negativeResult = _zeroResult = _a; break;
|
case OperationORA: _a |= _operand; _negativeResult = _zeroResult = _a; break;
|
||||||
case OperationAND: _a &= operand; _negativeResult = _zeroResult = _a; break;
|
case OperationAND: _a &= _operand; _negativeResult = _zeroResult = _a; break;
|
||||||
case OperationEOR: _a ^= operand; _negativeResult = _zeroResult = _a; break;
|
case OperationEOR: _a ^= _operand; _negativeResult = _zeroResult = _a; break;
|
||||||
|
|
||||||
#pragma mark - Load and Store
|
#pragma mark - Load and Store
|
||||||
|
|
||||||
case OperationLDA: _a = _negativeResult = _zeroResult = operand; break;
|
case OperationLDA: _a = _negativeResult = _zeroResult = _operand; break;
|
||||||
case OperationLDX: _x = _negativeResult = _zeroResult = operand; break;
|
case OperationLDX: _x = _negativeResult = _zeroResult = _operand; break;
|
||||||
case OperationLDY: _y = _negativeResult = _zeroResult = operand; break;
|
case OperationLDY: _y = _negativeResult = _zeroResult = _operand; break;
|
||||||
case OperationLAX: _a = _x = _negativeResult = _zeroResult = operand; break;
|
case OperationLAX: _a = _x = _negativeResult = _zeroResult = _operand; break;
|
||||||
|
|
||||||
case OperationSTA: operand = _a; break;
|
case OperationSTA: _operand = _a; break;
|
||||||
case OperationSTX: operand = _x; break;
|
case OperationSTX: _operand = _x; break;
|
||||||
case OperationSTY: operand = _y; break;
|
case OperationSTY: _operand = _y; break;
|
||||||
case OperationSAX: operand = _a & _x; break;
|
case OperationSAX: _operand = _a & _x; break;
|
||||||
case OperationSHA: operand = _a & _x & (address.bytes.high+1); break;
|
case OperationSHA: _operand = _a & _x & (_address.bytes.high+1); break;
|
||||||
case OperationSHX: operand = _x & (address.bytes.high+1); break;
|
case OperationSHX: _operand = _x & (_address.bytes.high+1); break;
|
||||||
case OperationSHY: operand = _y & (address.bytes.high+1); break;
|
case OperationSHY: _operand = _y & (_address.bytes.high+1); break;
|
||||||
case OperationSHS: _s = _a & _x; operand = _s & (address.bytes.high+1); break;
|
case OperationSHS: _s = _a & _x; _operand = _s & (_address.bytes.high+1); break;
|
||||||
|
|
||||||
case OperationLXA:
|
case OperationLXA:
|
||||||
_a = _x = (_a | 0xee) & operand;
|
_a = _x = (_a | 0xee) & _operand;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#pragma mark - Compare
|
#pragma mark - Compare
|
||||||
|
|
||||||
case OperationCMP: {
|
case OperationCMP: {
|
||||||
const uint16_t temp16 = _a - operand;
|
const uint16_t temp16 = _a - _operand;
|
||||||
_negativeResult = _zeroResult = (uint8_t)temp16;
|
_negativeResult = _zeroResult = (uint8_t)temp16;
|
||||||
_carryFlag = ((~temp16) >> 8)&1;
|
_carryFlag = ((~temp16) >> 8)&1;
|
||||||
} break;
|
} break;
|
||||||
case OperationCPX: {
|
case OperationCPX: {
|
||||||
const uint16_t temp16 = _x - operand;
|
const uint16_t temp16 = _x - _operand;
|
||||||
_negativeResult = _zeroResult = (uint8_t)temp16;
|
_negativeResult = _zeroResult = (uint8_t)temp16;
|
||||||
_carryFlag = ((~temp16) >> 8)&1;
|
_carryFlag = ((~temp16) >> 8)&1;
|
||||||
} break;
|
} break;
|
||||||
case OperationCPY: {
|
case OperationCPY: {
|
||||||
const uint16_t temp16 = _y - operand;
|
const uint16_t temp16 = _y - _operand;
|
||||||
_negativeResult = _zeroResult = (uint8_t)temp16;
|
_negativeResult = _zeroResult = (uint8_t)temp16;
|
||||||
_carryFlag = ((~temp16) >> 8)&1;
|
_carryFlag = ((~temp16) >> 8)&1;
|
||||||
} break;
|
} break;
|
||||||
@ -739,27 +732,27 @@ template <class T> class Processor {
|
|||||||
#pragma mark - BIT
|
#pragma mark - BIT
|
||||||
|
|
||||||
case OperationBIT:
|
case OperationBIT:
|
||||||
_zeroResult = operand & _a;
|
_zeroResult = _operand & _a;
|
||||||
_negativeResult = operand;
|
_negativeResult = _operand;
|
||||||
_overflowFlag = operand&Flag::Overflow;
|
_overflowFlag = _operand&Flag::Overflow;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#pragma mark ADC/SBC (and INS)
|
#pragma mark ADC/SBC (and INS)
|
||||||
|
|
||||||
case OperationINS:
|
case OperationINS:
|
||||||
operand++; // deliberate fallthrough
|
_operand++; // deliberate fallthrough
|
||||||
case OperationSBC:
|
case OperationSBC:
|
||||||
if(_decimalFlag) {
|
if(_decimalFlag) {
|
||||||
const uint16_t notCarry = _carryFlag ^ 0x1;
|
const uint16_t notCarry = _carryFlag ^ 0x1;
|
||||||
const uint16_t decimalResult = (uint16_t)_a - (uint16_t)operand - notCarry;
|
const uint16_t decimalResult = (uint16_t)_a - (uint16_t)_operand - notCarry;
|
||||||
uint16_t temp16;
|
uint16_t temp16;
|
||||||
|
|
||||||
temp16 = (_a&0xf) - (operand&0xf) - notCarry;
|
temp16 = (_a&0xf) - (_operand&0xf) - notCarry;
|
||||||
if(temp16 > 0xf) temp16 -= 0x6;
|
if(temp16 > 0xf) temp16 -= 0x6;
|
||||||
temp16 = (temp16&0x0f) | ((temp16 > 0x0f) ? 0xfff0 : 0x00);
|
temp16 = (temp16&0x0f) | ((temp16 > 0x0f) ? 0xfff0 : 0x00);
|
||||||
temp16 += (_a&0xf0) - (operand&0xf0);
|
temp16 += (_a&0xf0) - (_operand&0xf0);
|
||||||
|
|
||||||
_overflowFlag = ( ( (decimalResult^_a)&(~decimalResult^operand) )&0x80) >> 1;
|
_overflowFlag = ( ( (decimalResult^_a)&(~decimalResult^_operand) )&0x80) >> 1;
|
||||||
_negativeResult = (uint8_t)temp16;
|
_negativeResult = (uint8_t)temp16;
|
||||||
_zeroResult = (uint8_t)decimalResult;
|
_zeroResult = (uint8_t)decimalResult;
|
||||||
|
|
||||||
@ -769,20 +762,20 @@ template <class T> class Processor {
|
|||||||
_a = (uint8_t)temp16;
|
_a = (uint8_t)temp16;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
operand = ~operand;
|
_operand = ~_operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
// deliberate fallthrough
|
// deliberate fallthrough
|
||||||
case OperationADC:
|
case OperationADC:
|
||||||
if(_decimalFlag) {
|
if(_decimalFlag) {
|
||||||
const uint16_t decimalResult = (uint16_t)_a + (uint16_t)operand + (uint16_t)_carryFlag;
|
const uint16_t decimalResult = (uint16_t)_a + (uint16_t)_operand + (uint16_t)_carryFlag;
|
||||||
uint16_t temp16;
|
uint16_t temp16;
|
||||||
|
|
||||||
temp16 = (_a&0xf) + (operand&0xf) + _carryFlag;
|
temp16 = (_a&0xf) + (_operand&0xf) + _carryFlag;
|
||||||
if(temp16 > 0x9) temp16 += 0x6;
|
if(temp16 > 0x9) temp16 += 0x6;
|
||||||
temp16 = (temp16&0x0f) + ((temp16 > 0x0f) ? 0x10 : 0x00) + (_a&0xf0) + (operand&0xf0);
|
temp16 = (temp16&0x0f) + ((temp16 > 0x0f) ? 0x10 : 0x00) + (_a&0xf0) + (_operand&0xf0);
|
||||||
|
|
||||||
_overflowFlag = (( (decimalResult^_a)&(decimalResult^operand) )&0x80) >> 1;
|
_overflowFlag = (( (decimalResult^_a)&(decimalResult^_operand) )&0x80) >> 1;
|
||||||
_negativeResult = (uint8_t)temp16;
|
_negativeResult = (uint8_t)temp16;
|
||||||
_zeroResult = (uint8_t)decimalResult;
|
_zeroResult = (uint8_t)decimalResult;
|
||||||
|
|
||||||
@ -791,79 +784,79 @@ template <class T> class Processor {
|
|||||||
_carryFlag = (temp16 > 0xff) ? Flag::Carry : 0;
|
_carryFlag = (temp16 > 0xff) ? Flag::Carry : 0;
|
||||||
_a = (uint8_t)temp16;
|
_a = (uint8_t)temp16;
|
||||||
} else {
|
} else {
|
||||||
const uint16_t decimalResult = (uint16_t)_a + (uint16_t)operand + (uint16_t)_carryFlag;
|
const uint16_t decimalResult = (uint16_t)_a + (uint16_t)_operand + (uint16_t)_carryFlag;
|
||||||
_overflowFlag = (( (decimalResult^_a)&(decimalResult^operand) )&0x80) >> 1;
|
_overflowFlag = (( (decimalResult^_a)&(decimalResult^_operand) )&0x80) >> 1;
|
||||||
_negativeResult = _zeroResult = _a = (uint8_t)decimalResult;
|
_negativeResult = _zeroResult = _a = (uint8_t)decimalResult;
|
||||||
_carryFlag = (decimalResult >> 8)&1;
|
_carryFlag = (decimalResult >> 8)&1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix up in case this was INS
|
// fix up in case this was INS
|
||||||
if(cycle == OperationINS) operand = ~operand;
|
if(cycle == OperationINS) _operand = ~_operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#pragma mark - Shifts and Rolls
|
#pragma mark - Shifts and Rolls
|
||||||
|
|
||||||
case OperationASL:
|
case OperationASL:
|
||||||
_carryFlag = operand >> 7;
|
_carryFlag = _operand >> 7;
|
||||||
operand <<= 1;
|
_operand <<= 1;
|
||||||
_negativeResult = _zeroResult = operand;
|
_negativeResult = _zeroResult = _operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationASO:
|
case OperationASO:
|
||||||
_carryFlag = operand >> 7;
|
_carryFlag = _operand >> 7;
|
||||||
operand <<= 1;
|
_operand <<= 1;
|
||||||
_a |= operand;
|
_a |= _operand;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationROL: {
|
case OperationROL: {
|
||||||
const uint8_t temp8 = (uint8_t)((operand << 1) | _carryFlag);
|
const uint8_t temp8 = (uint8_t)((_operand << 1) | _carryFlag);
|
||||||
_carryFlag = operand >> 7;
|
_carryFlag = _operand >> 7;
|
||||||
operand = _negativeResult = _zeroResult = temp8;
|
_operand = _negativeResult = _zeroResult = temp8;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OperationRLA: {
|
case OperationRLA: {
|
||||||
const uint8_t temp8 = (uint8_t)((operand << 1) | _carryFlag);
|
const uint8_t temp8 = (uint8_t)((_operand << 1) | _carryFlag);
|
||||||
_carryFlag = operand >> 7;
|
_carryFlag = _operand >> 7;
|
||||||
operand = temp8;
|
_operand = temp8;
|
||||||
_a &= operand;
|
_a &= _operand;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OperationLSR:
|
case OperationLSR:
|
||||||
_carryFlag = operand & 1;
|
_carryFlag = _operand & 1;
|
||||||
operand >>= 1;
|
_operand >>= 1;
|
||||||
_negativeResult = _zeroResult = operand;
|
_negativeResult = _zeroResult = _operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationLSE:
|
case OperationLSE:
|
||||||
_carryFlag = operand & 1;
|
_carryFlag = _operand & 1;
|
||||||
operand >>= 1;
|
_operand >>= 1;
|
||||||
_a ^= operand;
|
_a ^= _operand;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationASR:
|
case OperationASR:
|
||||||
_a &= operand;
|
_a &= _operand;
|
||||||
_carryFlag = _a & 1;
|
_carryFlag = _a & 1;
|
||||||
_a >>= 1;
|
_a >>= 1;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationROR: {
|
case OperationROR: {
|
||||||
const uint8_t temp8 = (uint8_t)((operand >> 1) | (_carryFlag << 7));
|
const uint8_t temp8 = (uint8_t)((_operand >> 1) | (_carryFlag << 7));
|
||||||
_carryFlag = operand & 1;
|
_carryFlag = _operand & 1;
|
||||||
operand = _negativeResult = _zeroResult = temp8;
|
_operand = _negativeResult = _zeroResult = temp8;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OperationRRA: {
|
case OperationRRA: {
|
||||||
const uint8_t temp8 = (uint8_t)((operand >> 1) | (_carryFlag << 7));
|
const uint8_t temp8 = (uint8_t)((_operand >> 1) | (_carryFlag << 7));
|
||||||
_carryFlag = operand & 1;
|
_carryFlag = _operand & 1;
|
||||||
operand = temp8;
|
_operand = temp8;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OperationDecrementOperand: operand--; break;
|
case OperationDecrementOperand: _operand--; break;
|
||||||
case OperationIncrementOperand: operand++; break;
|
case OperationIncrementOperand: _operand++; break;
|
||||||
|
|
||||||
case OperationCLC: _carryFlag = 0; break;
|
case OperationCLC: _carryFlag = 0; break;
|
||||||
case OperationCLI: _interruptFlag = 0; break;
|
case OperationCLI: _interruptFlag = 0; break;
|
||||||
@ -874,112 +867,112 @@ template <class T> class Processor {
|
|||||||
case OperationSEI: _interruptFlag = Flag::Interrupt; break;
|
case OperationSEI: _interruptFlag = Flag::Interrupt; break;
|
||||||
case OperationSED: _decimalFlag = Flag::Decimal; break;
|
case OperationSED: _decimalFlag = Flag::Decimal; break;
|
||||||
|
|
||||||
case OperationINC: operand++; _negativeResult = _zeroResult = operand; break;
|
case OperationINC: _operand++; _negativeResult = _zeroResult = _operand; break;
|
||||||
case OperationDEC: operand--; _negativeResult = _zeroResult = operand; break;
|
case OperationDEC: _operand--; _negativeResult = _zeroResult = _operand; break;
|
||||||
case OperationINX: _x++; _negativeResult = _zeroResult = _x; break;
|
case OperationINX: _x++; _negativeResult = _zeroResult = _x; break;
|
||||||
case OperationDEX: _x--; _negativeResult = _zeroResult = _x; break;
|
case OperationDEX: _x--; _negativeResult = _zeroResult = _x; break;
|
||||||
case OperationINY: _y++; _negativeResult = _zeroResult = _y; break;
|
case OperationINY: _y++; _negativeResult = _zeroResult = _y; break;
|
||||||
case OperationDEY: _y--; _negativeResult = _zeroResult = _y; break;
|
case OperationDEY: _y--; _negativeResult = _zeroResult = _y; break;
|
||||||
|
|
||||||
case OperationANE:
|
case OperationANE:
|
||||||
_a = (_a | 0xee) & operand & _x;
|
_a = (_a | 0xee) & _operand & _x;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationANC:
|
case OperationANC:
|
||||||
_a &= operand;
|
_a &= _operand;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
_carryFlag = _a >> 7;
|
_carryFlag = _a >> 7;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationLAS:
|
case OperationLAS:
|
||||||
_a = _x = _s = _s & operand;
|
_a = _x = _s = _s & _operand;
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#pragma mark - Addressing Mode Work
|
#pragma mark - Addressing Mode Work
|
||||||
|
|
||||||
case CycleAddXToAddressLow:
|
case CycleAddXToAddressLow:
|
||||||
nextAddress.full = address.full + _x;
|
_nextAddress.full = _address.full + _x;
|
||||||
address.bytes.low = nextAddress.bytes.low;
|
_address.bytes.low = _nextAddress.bytes.low;
|
||||||
if (address.bytes.high != nextAddress.bytes.high) {
|
if (_address.bytes.high != _nextAddress.bytes.high) {
|
||||||
throwaway_read(address.full);
|
throwaway_read(_address.full);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CycleAddXToAddressLowRead:
|
case CycleAddXToAddressLowRead:
|
||||||
nextAddress.full = address.full + _x;
|
_nextAddress.full = _address.full + _x;
|
||||||
address.bytes.low = nextAddress.bytes.low;
|
_address.bytes.low = _nextAddress.bytes.low;
|
||||||
throwaway_read(address.full);
|
throwaway_read(_address.full);
|
||||||
break;
|
break;
|
||||||
case CycleAddYToAddressLow:
|
case CycleAddYToAddressLow:
|
||||||
nextAddress.full = address.full + _y;
|
_nextAddress.full = _address.full + _y;
|
||||||
address.bytes.low = nextAddress.bytes.low;
|
_address.bytes.low = _nextAddress.bytes.low;
|
||||||
if (address.bytes.high != nextAddress.bytes.high) {
|
if (_address.bytes.high != _nextAddress.bytes.high) {
|
||||||
throwaway_read(address.full);
|
throwaway_read(_address.full);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CycleAddYToAddressLowRead:
|
case CycleAddYToAddressLowRead:
|
||||||
nextAddress.full = address.full + _y;
|
_nextAddress.full = _address.full + _y;
|
||||||
address.bytes.low = nextAddress.bytes.low;
|
_address.bytes.low = _nextAddress.bytes.low;
|
||||||
throwaway_read(address.full);
|
throwaway_read(_address.full);
|
||||||
break;
|
break;
|
||||||
case OperationCorrectAddressHigh:
|
case OperationCorrectAddressHigh:
|
||||||
address.full = nextAddress.full;
|
_address.full = _nextAddress.full;
|
||||||
break;
|
break;
|
||||||
case CycleIncrementPCFetchAddressLowFromOperand:
|
case CycleIncrementPCFetchAddressLowFromOperand:
|
||||||
_pc.full++;
|
_pc.full++;
|
||||||
read_mem(address.bytes.low, operand);
|
read_mem(_address.bytes.low, _operand);
|
||||||
break;
|
break;
|
||||||
case CycleAddXToOperandFetchAddressLow:
|
case CycleAddXToOperandFetchAddressLow:
|
||||||
operand += _x;
|
_operand += _x;
|
||||||
read_mem(address.bytes.low, operand);
|
read_mem(_address.bytes.low, _operand);
|
||||||
break;
|
break;
|
||||||
case CycleIncrementOperandFetchAddressHigh:
|
case CycleIncrementOperandFetchAddressHigh:
|
||||||
operand++;
|
_operand++;
|
||||||
read_mem(address.bytes.high, operand);
|
read_mem(_address.bytes.high, _operand);
|
||||||
break;
|
break;
|
||||||
case CycleIncrementPCReadPCHLoadPCL: // deliberate fallthrough
|
case CycleIncrementPCReadPCHLoadPCL: // deliberate fallthrough
|
||||||
_pc.full++;
|
_pc.full++;
|
||||||
case CycleReadPCHLoadPCL: {
|
case CycleReadPCHLoadPCL: {
|
||||||
uint16_t oldPC = _pc.full;
|
uint16_t oldPC = _pc.full;
|
||||||
_pc.bytes.low = operand;
|
_pc.bytes.low = _operand;
|
||||||
read_mem(_pc.bytes.high, oldPC);
|
read_mem(_pc.bytes.high, oldPC);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CycleReadAddressHLoadAddressL:
|
case CycleReadAddressHLoadAddressL:
|
||||||
address.bytes.low = operand; _pc.full++;
|
_address.bytes.low = _operand; _pc.full++;
|
||||||
read_mem(address.bytes.high, _pc.full);
|
read_mem(_address.bytes.high, _pc.full);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CycleLoadAddressAbsolute: {
|
case CycleLoadAddressAbsolute: {
|
||||||
uint16_t nextPC = _pc.full+1;
|
uint16_t nextPC = _pc.full+1;
|
||||||
_pc.full += 2;
|
_pc.full += 2;
|
||||||
address.bytes.low = operand;
|
_address.bytes.low = _operand;
|
||||||
read_mem(address.bytes.high, nextPC);
|
read_mem(_address.bytes.high, nextPC);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OperationLoadAddressZeroPage:
|
case OperationLoadAddressZeroPage:
|
||||||
_pc.full++;
|
_pc.full++;
|
||||||
address.full = operand;
|
_address.full = _operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CycleLoadAddessZeroX:
|
case CycleLoadAddessZeroX:
|
||||||
_pc.full++;
|
_pc.full++;
|
||||||
address.full = (operand + _x)&0xff;
|
_address.full = (_operand + _x)&0xff;
|
||||||
throwaway_read(operand);
|
throwaway_read(_operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CycleLoadAddessZeroY:
|
case CycleLoadAddessZeroY:
|
||||||
_pc.full++;
|
_pc.full++;
|
||||||
address.full = (operand + _y)&0xff;
|
_address.full = (_operand + _y)&0xff;
|
||||||
throwaway_read(operand);
|
throwaway_read(_operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperationIncrementPC: _pc.full++; break;
|
case OperationIncrementPC: _pc.full++; break;
|
||||||
case CycleFetchOperandFromAddress: read_mem(operand, address.full); break;
|
case CycleFetchOperandFromAddress: read_mem(_operand, _address.full); break;
|
||||||
case CycleWriteOperandToAddress: write_mem(operand, address.full); break;
|
case CycleWriteOperandToAddress: write_mem(_operand, _address.full); break;
|
||||||
case OperationCopyOperandFromA: operand = _a; break;
|
case OperationCopyOperandFromA: _operand = _a; break;
|
||||||
case OperationCopyOperandToA: _a = operand; break;
|
case OperationCopyOperandToA: _a = _operand; break;
|
||||||
|
|
||||||
#pragma mark - Branching
|
#pragma mark - Branching
|
||||||
|
|
||||||
@ -995,11 +988,11 @@ template <class T> class Processor {
|
|||||||
case OperationBEQ: BRA(!_zeroResult); break;
|
case OperationBEQ: BRA(!_zeroResult); break;
|
||||||
|
|
||||||
case CycleAddSignedOperandToPC:
|
case CycleAddSignedOperandToPC:
|
||||||
nextAddress.full = (uint16_t)(_pc.full + (int8_t)operand);
|
_nextAddress.full = (uint16_t)(_pc.full + (int8_t)_operand);
|
||||||
_pc.bytes.low = nextAddress.bytes.low;
|
_pc.bytes.low = _nextAddress.bytes.low;
|
||||||
if(nextAddress.bytes.high != _pc.bytes.high) {
|
if(_nextAddress.bytes.high != _pc.bytes.high) {
|
||||||
uint16_t halfUpdatedPc = _pc.full;
|
uint16_t halfUpdatedPc = _pc.full;
|
||||||
_pc.full = nextAddress.full;
|
_pc.full = _nextAddress.full;
|
||||||
throwaway_read(halfUpdatedPc);
|
throwaway_read(halfUpdatedPc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1017,7 +1010,7 @@ template <class T> class Processor {
|
|||||||
|
|
||||||
case OperationARR:
|
case OperationARR:
|
||||||
if(_decimalFlag) {
|
if(_decimalFlag) {
|
||||||
_a &= operand;
|
_a &= _operand;
|
||||||
uint8_t unshiftedA = _a;
|
uint8_t unshiftedA = _a;
|
||||||
_a = (uint8_t)((_a >> 1) | (_carryFlag << 7));
|
_a = (uint8_t)((_a >> 1) | (_carryFlag << 7));
|
||||||
_zeroResult = _negativeResult = _a;
|
_zeroResult = _negativeResult = _a;
|
||||||
@ -1029,7 +1022,7 @@ template <class T> class Processor {
|
|||||||
if (_carryFlag) _a += 0x60;
|
if (_carryFlag) _a += 0x60;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_a &= operand;
|
_a &= _operand;
|
||||||
_a = (uint8_t)((_a >> 1) | (_carryFlag << 7));
|
_a = (uint8_t)((_a >> 1) | (_carryFlag << 7));
|
||||||
_negativeResult = _zeroResult = _a;
|
_negativeResult = _zeroResult = _a;
|
||||||
_carryFlag = (_a >> 6)&1;
|
_carryFlag = (_a >> 6)&1;
|
||||||
@ -1039,14 +1032,14 @@ template <class T> class Processor {
|
|||||||
|
|
||||||
case OperationSBX:
|
case OperationSBX:
|
||||||
_x &= _a;
|
_x &= _a;
|
||||||
uint16_t difference = _x - operand;
|
uint16_t difference = _x - _operand;
|
||||||
_x = (uint8_t)difference;
|
_x = (uint8_t)difference;
|
||||||
_negativeResult = _zeroResult = _x;
|
_negativeResult = _zeroResult = _x;
|
||||||
_carryFlag = ((difference >> 8)&1)^1;
|
_carryFlag = ((difference >> 8)&1)^1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isReadOperation(nextBusOperation) && _ready_line_is_enabled) {
|
if (isReadOperation(_nextBusOperation) && _ready_line_is_enabled) {
|
||||||
_ready_is_active = true;
|
_ready_is_active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1054,13 +1047,6 @@ template <class T> class Processor {
|
|||||||
_cycles_left_to_run = number_of_cycles;
|
_cycles_left_to_run = number_of_cycles;
|
||||||
_scheduleProgramsReadPointer = scheduleProgramsReadPointer;
|
_scheduleProgramsReadPointer = scheduleProgramsReadPointer;
|
||||||
_scheduleProgramProgramCounter = scheduleProgramProgramCounter;
|
_scheduleProgramProgramCounter = scheduleProgramProgramCounter;
|
||||||
_operand = operand;
|
|
||||||
_operation = operation;
|
|
||||||
_address = address;
|
|
||||||
_nextAddress = nextAddress;
|
|
||||||
_nextBusOperation = nextBusOperation;
|
|
||||||
_busAddress = busAddress;
|
|
||||||
_busValue = busValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ using namespace SignalProcessing;
|
|||||||
#define kCSKaiserBesselFilterFixedShift 15
|
#define kCSKaiserBesselFilterFixedShift 15
|
||||||
|
|
||||||
/* ino evaluates the 0th order Bessel function at a */
|
/* ino evaluates the 0th order Bessel function at a */
|
||||||
static float csfilter_ino(float a)
|
float FIRFilter::ino(float a)
|
||||||
{
|
{
|
||||||
float d = 0.0f;
|
float d = 0.0f;
|
||||||
float ds = 1.0f;
|
float ds = 1.0f;
|
||||||
@ -54,7 +54,8 @@ static float csfilter_ino(float a)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void csfilter_setIdealisedFilterResponse(short *filterCoefficients, float *A, float attenuation, unsigned int numberOfTaps)
|
//static void csfilter_setIdealisedFilterResponse(short *filterCoefficients, float *A, float attenuation, unsigned int numberOfTaps)
|
||||||
|
void FIRFilter::coefficients_for_idealised_filter_response(short *filterCoefficients, float *A, float attenuation, unsigned int numberOfTaps)
|
||||||
{
|
{
|
||||||
/* calculate alpha, which is the Kaiser-Bessel window shape factor */
|
/* calculate alpha, which is the Kaiser-Bessel window shape factor */
|
||||||
float a; // to take the place of alpha in the normal derivation
|
float a; // to take the place of alpha in the normal derivation
|
||||||
@ -73,13 +74,13 @@ static void csfilter_setIdealisedFilterResponse(short *filterCoefficients, float
|
|||||||
|
|
||||||
/* work out the right hand side of the filter coefficients */
|
/* work out the right hand side of the filter coefficients */
|
||||||
unsigned int Np = (numberOfTaps - 1) / 2;
|
unsigned int Np = (numberOfTaps - 1) / 2;
|
||||||
float I0 = csfilter_ino(a);
|
float I0 = ino(a);
|
||||||
float NpSquared = (float)(Np * Np);
|
float NpSquared = (float)(Np * Np);
|
||||||
for(unsigned int i = 0; i <= Np; i++)
|
for(unsigned int i = 0; i <= Np; i++)
|
||||||
{
|
{
|
||||||
filterCoefficientsFloat[Np + i] =
|
filterCoefficientsFloat[Np + i] =
|
||||||
A[i] *
|
A[i] *
|
||||||
csfilter_ino(a * sqrtf(1.0f - ((float)(i * i) / NpSquared) )) /
|
ino(a * sqrtf(1.0f - ((float)(i * i) / NpSquared) )) /
|
||||||
I0;
|
I0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,14 @@ static void csfilter_setIdealisedFilterResponse(short *filterCoefficients, float
|
|||||||
delete[] filterCoefficientsFloat;
|
delete[] filterCoefficientsFloat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FIRFilter::get_coefficients(float *coefficients)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < number_of_taps_; i++)
|
||||||
|
{
|
||||||
|
coefficients[i] = (float)filter_coefficients_[i] / kCSKaiserBesselFilterFixedMultiplier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FIRFilter::FIRFilter(unsigned int number_of_taps, unsigned int input_sample_rate, float low_frequency, float high_frequency, float attenuation)
|
FIRFilter::FIRFilter(unsigned int number_of_taps, unsigned int input_sample_rate, float low_frequency, float high_frequency, float attenuation)
|
||||||
{
|
{
|
||||||
// we must be asked to filter based on an odd number of
|
// we must be asked to filter based on an odd number of
|
||||||
@ -136,7 +145,7 @@ FIRFilter::FIRFilter(unsigned int number_of_taps, unsigned int input_sample_rate
|
|||||||
) / iPi;
|
) / iPi;
|
||||||
}
|
}
|
||||||
|
|
||||||
csfilter_setIdealisedFilterResponse(filter_coefficients_, A, attenuation, number_of_taps_);
|
FIRFilter::coefficients_for_idealised_filter_response(filter_coefficients_, A, attenuation, number_of_taps_);
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
delete[] A;
|
delete[] A;
|
||||||
|
@ -42,7 +42,7 @@ class FIRFilter {
|
|||||||
@param input_sample_rate The sampling rate of the input signal.
|
@param input_sample_rate The sampling rate of the input signal.
|
||||||
@param low_frequency The lowest frequency of signal to retain in the output.
|
@param low_frequency The lowest frequency of signal to retain in the output.
|
||||||
@param high_frequency The highest frequency of signal to retain in the output.
|
@param high_frequency The highest frequency of signal to retain in the output.
|
||||||
@param attenuation The attenuation of the output.
|
@param attenuation The attenuation of the discarded frequencies.
|
||||||
*/
|
*/
|
||||||
FIRFilter(unsigned int number_of_taps, unsigned int input_sample_rate, float low_frequency, float high_frequency, float attenuation);
|
FIRFilter(unsigned int number_of_taps, unsigned int input_sample_rate, float low_frequency, float high_frequency, float attenuation);
|
||||||
|
|
||||||
@ -73,9 +73,19 @@ class FIRFilter {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline unsigned int get_number_of_taps()
|
||||||
|
{
|
||||||
|
return number_of_taps_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_coefficients(float *coefficients);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
short *filter_coefficients_;
|
short *filter_coefficients_;
|
||||||
unsigned int number_of_taps_;
|
unsigned int number_of_taps_;
|
||||||
|
|
||||||
|
static void coefficients_for_idealised_filter_response(short *filterCoefficients, float *A, float attenuation, unsigned int numberOfTaps);
|
||||||
|
static float ino(float a);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user