1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-15 20:31:36 +00:00

Eliminated plain pointer passing for object types.

This commit is contained in:
Thomas Harte 2016-07-04 19:33:55 -04:00
parent 6dbf16210b
commit 88964ceac0
9 changed files with 39 additions and 36 deletions

View File

@ -12,6 +12,7 @@ using namespace MOS;
MOS6560::MOS6560() : MOS6560::MOS6560() :
_crt(new Outputs::CRT::CRT(65*4, 4, Outputs::CRT::NTSC60, 1)), _crt(new Outputs::CRT::CRT(65*4, 4, Outputs::CRT::NTSC60, 1)),
_speaker(new Speaker),
_horizontal_counter(0), _horizontal_counter(0),
_vertical_counter(0), _vertical_counter(0),
_cycles_since_speaker_update(0), _cycles_since_speaker_update(0),
@ -34,7 +35,7 @@ MOS6560::MOS6560() :
// show only the centre // show only the centre
_crt->set_visible_area(_crt->get_rect_for_area(16, 237, 11*4, 55*4, 4.0f / 3.0f)); _crt->set_visible_area(_crt->get_rect_for_area(16, 237, 11*4, 55*4, 4.0f / 3.0f));
_speaker.set_input_rate(255681.75); // assuming NTSC; clock rate / 4 _speaker->set_input_rate(255681.75); // assuming NTSC; clock rate / 4
} }
void MOS6560::set_output_mode(OutputMode output_mode) void MOS6560::set_output_mode(OutputMode output_mode)
@ -119,13 +120,13 @@ void MOS6560::set_register(int address, uint8_t value)
case 0xc: case 0xc:
case 0xd: case 0xd:
update_audio(); update_audio();
_speaker.set_control(address - 0xa, value); _speaker->set_control(address - 0xa, value);
break; break;
case 0xe: case 0xe:
update_audio(); update_audio();
_registers.auxiliary_colour = _colours[value >> 4]; _registers.auxiliary_colour = _colours[value >> 4];
_speaker.set_volume(value & 0xf); _speaker->set_volume(value & 0xf);
break; break;
case 0xf: case 0xf:
@ -361,7 +362,7 @@ void MOS6560::set_graphics_value(uint8_t value, uint8_t colour_value)
void MOS6560::update_audio() void MOS6560::update_audio()
{ {
_speaker.run_for_cycles(_cycles_since_speaker_update >> 2); _speaker->run_for_cycles(_cycles_since_speaker_update >> 2);
_cycles_since_speaker_update &= 3; _cycles_since_speaker_update &= 3;
} }

View File

@ -25,8 +25,8 @@ namespace MOS {
class MOS6560 { class MOS6560 {
public: public:
MOS6560(); MOS6560();
Outputs::CRT::CRT *get_crt() { return _crt.get(); } std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _crt; }
Outputs::Speaker *get_speaker() { return &_speaker; } std::shared_ptr<Outputs::Speaker> get_speaker() { return _speaker; }
enum OutputMode { enum OutputMode {
PAL, NTSC PAL, NTSC
@ -63,7 +63,7 @@ class MOS6560 {
uint8_t get_register(int address); uint8_t get_register(int address);
private: private:
std::unique_ptr<Outputs::CRT::CRT> _crt; std::shared_ptr<Outputs::CRT::CRT> _crt;
// audio state // audio state
class Speaker: public ::Outputs::Filter<Speaker> { class Speaker: public ::Outputs::Filter<Speaker> {
@ -81,7 +81,8 @@ class MOS6560 {
unsigned int _shift_registers[4]; unsigned int _shift_registers[4];
uint8_t _control_registers[4]; uint8_t _control_registers[4];
uint8_t _volume; uint8_t _volume;
} _speaker; };
std::shared_ptr<Speaker> _speaker;
unsigned int _cycles_since_speaker_update; unsigned int _cycles_since_speaker_update;
void update_audio(); void update_audio();

View File

@ -56,7 +56,8 @@ Machine::Machine() :
void Machine::setup_output(float aspect_ratio) void Machine::setup_output(float aspect_ratio)
{ {
_crt = new Outputs::CRT::CRT(228, 1, 263, Outputs::CRT::ColourSpace::YIQ, 228, 1, 1); _speaker.reset(new Speaker);
_crt.reset(new Outputs::CRT::CRT(228, 1, 263, Outputs::CRT::ColourSpace::YIQ, 228, 1, 1));
_crt->set_output_device(Outputs::CRT::Television); _crt->set_output_device(Outputs::CRT::Television);
// this is the NTSC phase offset function; see below for PAL // this is the NTSC phase offset function; see below for PAL
@ -70,7 +71,7 @@ void Machine::setup_output(float aspect_ratio)
"float phaseOffset = 6.283185308 * float(iPhase - 1u) / 13.0;" "float phaseOffset = 6.283185308 * float(iPhase - 1u) / 13.0;"
"return mix(float(y) / 14.0, step(1, iPhase) * cos(phase + phaseOffset), amplitude);" "return mix(float(y) / 14.0, step(1, iPhase) * cos(phase + phaseOffset), amplitude);"
"}"); "}");
_speaker.set_input_rate((float)(get_clock_rate() / 38.0)); _speaker->set_input_rate((float)(get_clock_rate() / 38.0));
} }
void Machine::switch_region() void Machine::switch_region()
@ -92,15 +93,14 @@ void Machine::switch_region()
_crt->set_new_timing(228, 312, Outputs::CRT::ColourSpace::YUV, 228, 1); _crt->set_new_timing(228, 312, Outputs::CRT::ColourSpace::YUV, 228, 1);
_is_pal_region = true; _is_pal_region = true;
_speaker.set_input_rate((float)(get_clock_rate() / 38.0)); _speaker->set_input_rate((float)(get_clock_rate() / 38.0));
if(delegate) delegate->machine_did_change_clock_rate(this); if(delegate) delegate->machine_did_change_clock_rate(this);
} }
void Machine::close_output() void Machine::close_output()
{ {
delete _crt; _crt.reset();
_crt = nullptr;
} }
Machine::~Machine() Machine::~Machine()
@ -598,17 +598,17 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
case 0x15: case 0x16: case 0x15: case 0x16:
update_audio(); update_audio();
_speaker.set_control(decodedAddress - 0x15, *value); _speaker->set_control(decodedAddress - 0x15, *value);
break; break;
case 0x17: case 0x18: case 0x17: case 0x18:
update_audio(); update_audio();
_speaker.set_divider(decodedAddress - 0x17, *value); _speaker->set_divider(decodedAddress - 0x17, *value);
break; break;
case 0x19: case 0x1a: case 0x19: case 0x1a:
update_audio(); update_audio();
_speaker.set_volume(decodedAddress - 0x19, *value); _speaker->set_volume(decodedAddress - 0x19, *value);
break; break;
case 0x1c: case 0x1c:
@ -781,7 +781,7 @@ void Machine::update_audio()
// logged_time = time_now; // logged_time = time_now;
// } // }
_speaker.run_for_cycles(audio_cycles); _speaker->run_for_cycles(audio_cycles);
_cycles_since_speaker_update %= 114; _cycles_since_speaker_update %= 114;
} }

View File

@ -92,8 +92,8 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine {
// to satisfy CRTMachine::Machine // to satisfy CRTMachine::Machine
virtual void setup_output(float aspect_ratio); virtual void setup_output(float aspect_ratio);
virtual void close_output(); virtual void close_output();
virtual Outputs::CRT::CRT *get_crt() { return _crt; } virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _crt; }
virtual Outputs::Speaker *get_speaker() { return &_speaker; } virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return _speaker; }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
virtual double get_clock_rate(); virtual double get_clock_rate();
// TODO: different rate for PAL // TODO: different rate for PAL
@ -197,8 +197,8 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine {
void update_timers(int mask); void update_timers(int mask);
// outputs // outputs
Outputs::CRT::CRT *_crt; std::shared_ptr<Outputs::CRT::CRT> _crt;
Speaker _speaker; std::shared_ptr<Speaker> _speaker;
// current mode // current mode
bool _is_pal_region; bool _is_pal_region;

View File

@ -24,8 +24,8 @@ class Machine {
virtual void setup_output(float aspect_ratio) = 0; virtual void setup_output(float aspect_ratio) = 0;
virtual void close_output() = 0; virtual void close_output() = 0;
virtual Outputs::CRT::CRT *get_crt() = 0; virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() = 0;
virtual Outputs::Speaker *get_speaker() = 0; virtual std::shared_ptr<Outputs::Speaker> get_speaker() = 0;
virtual void run_for_cycles(int number_of_cycles) = 0; virtual void run_for_cycles(int number_of_cycles) = 0;

View File

@ -59,6 +59,7 @@ Machine::Machine() :
void Machine::setup_output(float aspect_ratio) void Machine::setup_output(float aspect_ratio)
{ {
_speaker.reset(new Speaker);
_crt.reset(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1)); _crt.reset(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1));
_crt->set_rgb_sampling_function( _crt->set_rgb_sampling_function(
"vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" "vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)"
@ -74,7 +75,7 @@ void Machine::setup_output(float aspect_ratio)
// The maximum output frequency is 62500Hz and all other permitted output frequencies are integral divisions of that; // The maximum output frequency is 62500Hz and all other permitted output frequencies are integral divisions of that;
// however setting the speaker on or off can happen on any 2Mhz cycle, and probably (?) takes effect immediately. So // however setting the speaker on or off can happen on any 2Mhz cycle, and probably (?) takes effect immediately. So
// run the speaker at a 2000000Hz input rate, at least for the time being. // run the speaker at a 2000000Hz input rate, at least for the time being.
_speaker.set_input_rate(2000000 / clock_rate_audio_divider); _speaker->set_input_rate(2000000 / clock_rate_audio_divider);
} }
void Machine::close_output() void Machine::close_output()
@ -201,7 +202,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
if(!isReadOperation(operation)) if(!isReadOperation(operation))
{ {
update_audio(); update_audio();
_speaker.set_divider(*value); _speaker->set_divider(*value);
_tape.set_counter(*value); _tape.set_counter(*value);
} }
break; break;
@ -227,10 +228,10 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
// update speaker mode // update speaker mode
bool new_speaker_is_enabled = (*value & 6) == 2; bool new_speaker_is_enabled = (*value & 6) == 2;
if(new_speaker_is_enabled != _speaker.get_is_enabled()) if(new_speaker_is_enabled != _speaker->get_is_enabled())
{ {
update_audio(); update_audio();
_speaker.set_is_enabled(new_speaker_is_enabled); _speaker->set_is_enabled(new_speaker_is_enabled);
_tape.set_is_enabled(!new_speaker_is_enabled); _tape.set_is_enabled(!new_speaker_is_enabled);
} }
@ -508,7 +509,7 @@ inline void Machine::update_audio()
{ {
unsigned int difference = _frameCycles - _audioOutputPosition; unsigned int difference = _frameCycles - _audioOutputPosition;
_audioOutputPosition = _frameCycles; _audioOutputPosition = _frameCycles;
_speaker.run_for_cycles(difference / clock_rate_audio_divider); _speaker->run_for_cycles(difference / clock_rate_audio_divider);
_audioOutputPositionError = difference % clock_rate_audio_divider; _audioOutputPositionError = difference % clock_rate_audio_divider;
} }

View File

@ -159,8 +159,8 @@ class Machine:
// to satisfy CRTMachine::Machine // to satisfy CRTMachine::Machine
virtual void setup_output(float aspect_ratio); virtual void setup_output(float aspect_ratio);
virtual void close_output(); virtual void close_output();
virtual Outputs::CRT::CRT *get_crt() { return _crt.get(); } virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _crt; }
virtual Outputs::Speaker *get_speaker() { return &_speaker; } virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return _speaker; }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
virtual double get_clock_rate() { return 2000000; } virtual double get_clock_rate() { return 2000000; }
@ -227,8 +227,8 @@ class Machine:
bool _fast_load_is_in_data; bool _fast_load_is_in_data;
// Outputs // Outputs
std::unique_ptr<Outputs::CRT::CRT> _crt; std::shared_ptr<Outputs::CRT::CRT> _crt;
Speaker _speaker; std::shared_ptr<Speaker> _speaker;
}; };
} }

View File

@ -168,8 +168,8 @@ class Machine:
// to satisfy CRTMachine::Machine // to satisfy CRTMachine::Machine
virtual void setup_output(float aspect_ratio); virtual void setup_output(float aspect_ratio);
virtual void close_output() {} virtual void close_output() {}
virtual Outputs::CRT::CRT *get_crt() { return _mos6560->get_crt(); } virtual std::shared_ptr<Outputs::CRT::CRT> get_crt() { return _mos6560->get_crt(); }
virtual Outputs::Speaker *get_speaker() { return _mos6560->get_speaker(); } virtual std::shared_ptr<Outputs::Speaker> get_speaker() { return _mos6560->get_speaker(); }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); } virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
virtual double get_clock_rate() { return 1022727; } virtual double get_clock_rate() { return 1022727; }
// TODO: or 1108405 for PAL; see http://www.antimon.org/dl/c64/code/stable.txt // TODO: or 1108405 for PAL; see http://www.antimon.org/dl/c64/code/stable.txt

View File

@ -63,7 +63,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate {
- (float)idealSamplingRateFromRange:(NSRange)range { - (float)idealSamplingRateFromRange:(NSRange)range {
@synchronized(self) { @synchronized(self) {
Outputs::Speaker *speaker = self.machine->get_speaker(); std::shared_ptr<Outputs::Speaker> speaker = self.machine->get_speaker();
if(speaker) if(speaker)
{ {
return speaker->get_ideal_clock_rate_in_range((float)range.location, (float)(range.location + range.length)); return speaker->get_ideal_clock_rate_in_range((float)range.location, (float)(range.location + range.length));
@ -80,7 +80,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate {
- (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(float)sampleRate bufferSize:(NSUInteger)bufferSize { - (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(float)sampleRate bufferSize:(NSUInteger)bufferSize {
@synchronized(self) { @synchronized(self) {
Outputs::Speaker *speaker = self.machine->get_speaker(); std::shared_ptr<Outputs::Speaker> speaker = self.machine->get_speaker();
if(speaker) if(speaker)
{ {
speaker->set_output_rate(sampleRate, (int)bufferSize); speaker->set_output_rate(sampleRate, (int)bufferSize);