1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-16 18:30:32 +00:00

Bumped the speaker up to the full namespace, since Tape lives there to avoid delegation complexity. Turned the CRT into something the Electron statically owns, fixing a memory leak by simplifying.

This commit is contained in:
Thomas Harte 2016-01-23 17:45:06 -05:00
parent 20cab08f8f
commit cd97617a8a
2 changed files with 45 additions and 53 deletions

View File

@ -25,11 +25,11 @@ Machine::Machine() :
_displayOutputPosition(0),
_audioOutputPosition(0),
_audioOutputPositionError(0),
_currentOutputLine(0)
_currentOutputLine(0),
_crt(Outputs::CRT(crt_cycles_per_line, 312, 1, 1))
{
memset(_keyStates, 0, sizeof(_keyStates));
memset(_palette, 0xf, sizeof(_palette));
_crt = new Outputs::CRT(crt_cycles_per_line, 312, 1, 1);
_interruptStatus = 0x02;
for(int c = 0; c < 16; c++)
memset(_roms[c], 0xff, 16384);
@ -367,8 +367,8 @@ inline void Machine::update_display()
{
for(int c = 0; c < lines_of_hsync; c++)
{
_crt->output_sync(119 * crt_cycles_multiplier);
_crt->output_blank(9 * crt_cycles_multiplier);
_crt.output_sync(119 * crt_cycles_multiplier);
_crt.output_blank(9 * crt_cycles_multiplier);
}
_displayOutputPosition = end_of_hsync;
}
@ -381,7 +381,7 @@ inline void Machine::update_display()
// all lines then start with 9 cycles of sync
if(!line_position)
{
_crt->output_sync(9 * crt_cycles_multiplier);
_crt.output_sync(9 * crt_cycles_multiplier);
_displayOutputPosition += 9;
}
else
@ -395,7 +395,7 @@ inline void Machine::update_display()
{
if(line_position == 9)
{
_crt->output_blank(119 * crt_cycles_multiplier);
_crt.output_blank(119 * crt_cycles_multiplier);
_displayOutputPosition += 119;
}
}
@ -404,7 +404,7 @@ inline void Machine::update_display()
// there are then 15 cycles of blank, 80 cycles of pixels, and 24 further cycles of blank
if(line_position == 9)
{
_crt->output_blank(15 * crt_cycles_multiplier);
_crt.output_blank(15 * crt_cycles_multiplier);
_displayOutputPosition += 15;
switch(_screenMode)
@ -414,8 +414,8 @@ inline void Machine::update_display()
case 2: case 5: _currentOutputDivider = 4; break;
}
_crt->allocate_write_area(80 * crt_cycles_multiplier / _currentOutputDivider);
_currentLine = _writePointer = (uint8_t *)_crt->get_write_target_for_buffer(0);
_crt.allocate_write_area(80 * crt_cycles_multiplier / _currentOutputDivider);
_currentLine = _writePointer = (uint8_t *)_crt.get_write_target_for_buffer(0);
if(current_line == first_graphics_line)
_startLineAddress = _startScreenAddress;
@ -435,10 +435,10 @@ inline void Machine::update_display()
}
if(newDivider != _currentOutputDivider)
{
_crt->output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider * crt_cycles_multiplier), _currentOutputDivider);
_crt.output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider * crt_cycles_multiplier), _currentOutputDivider);
_currentOutputDivider = newDivider;
_crt->allocate_write_area((int)((104 - (unsigned int)line_position) * crt_cycles_multiplier / _currentOutputDivider));
_currentLine = _writePointer = (uint8_t *)_crt->get_write_target_for_buffer(0);
_crt.allocate_write_area((int)((104 - (unsigned int)line_position) * crt_cycles_multiplier / _currentOutputDivider));
_currentLine = _writePointer = (uint8_t *)_crt.get_write_target_for_buffer(0);
}
@ -510,6 +510,8 @@ inline void Machine::update_display()
}
}
#undef GetNextPixels
if(line_position == 104)
{
_currentOutputLine++;
@ -521,10 +523,10 @@ inline void Machine::update_display()
_startLineAddress++;
if(_writePointer)
_crt->output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider), _currentOutputDivider);
_crt.output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider), _currentOutputDivider);
else
_crt->output_data(80 * crt_cycles_multiplier, _currentOutputDivider);
_crt->output_blank(24 * crt_cycles_multiplier);
_crt.output_data(80 * crt_cycles_multiplier, _currentOutputDivider);
_crt.output_blank(24 * crt_cycles_multiplier);
_displayOutputPosition += 24;
_currentLine = nullptr;
}
@ -559,7 +561,11 @@ void Machine::set_key_state(Key key, bool isPressed)
}
}
void Machine::Speaker::get_samples(unsigned int number_of_samples, int16_t *target)
/*
Speaker
*/
void Speaker::get_samples(unsigned int number_of_samples, int16_t *target)
{
if(!_is_enabled)
{
@ -568,12 +574,11 @@ void Machine::Speaker::get_samples(unsigned int number_of_samples, int16_t *targ
else
{
*target = _output_level;
// fwrite(target, sizeof(int16_t), 1, rawStream);
}
skip_samples(number_of_samples);
}
void Machine::Speaker::skip_samples(unsigned int number_of_samples)
void Speaker::skip_samples(unsigned int number_of_samples)
{
while(number_of_samples--)
{
@ -586,27 +591,17 @@ void Machine::Speaker::skip_samples(unsigned int number_of_samples)
}
}
void Machine::Speaker::set_divider(uint8_t divider)
void Speaker::set_divider(uint8_t divider)
{
_divider = divider;
}
void Machine::Speaker::set_is_enabled(bool is_enabled)
void Speaker::set_is_enabled(bool is_enabled)
{
_is_enabled = is_enabled;
_counter = 0;
}
Machine::Speaker::Speaker() : _counter(0), _divider(0x32), _is_enabled(false), _output_level(0)
{
// rawStream = fopen("/Users/thomasharte/Desktop/sound.rom", "wb");
}
Machine::Speaker::~Speaker()
{
// fclose(rawStream);
}
/*
Tape
*/

View File

@ -106,6 +106,23 @@ class Tape {
} _crossings[4];
};
class Speaker: public ::Outputs::Filter<Speaker> {
public:
void set_divider(uint8_t divider);
void set_is_enabled(bool is_enabled);
inline bool get_is_enabled() { return _is_enabled; }
void get_samples(unsigned int number_of_samples, int16_t *target);
void skip_samples(unsigned int number_of_samples);
private:
unsigned int _counter;
uint8_t _divider;
bool _is_enabled;
int16_t _output_level;
};
/*!
@abstract Represents an Acorn Electron.
@ -126,7 +143,7 @@ class Machine: public CPU6502::Processor<Machine>, Tape::Delegate {
void set_key_state(Key key, bool isPressed);
Outputs::CRT *get_crt() { return _crt; }
Outputs::CRT *get_crt() { return &_crt; }
Outputs::Speaker *get_speaker() { return &_speaker; }
const char *get_signal_decoder();
@ -165,28 +182,8 @@ class Machine: public CPU6502::Processor<Machine>, Tape::Delegate {
Tape _tape;
// Outputs.
Outputs::CRT *_crt;
class Speaker: public ::Outputs::Filter<Speaker> {
public:
void set_divider(uint8_t divider);
void set_is_enabled(bool is_enabled);
inline bool get_is_enabled() { return _is_enabled; }
void get_samples(unsigned int number_of_samples, int16_t *target);
void skip_samples(unsigned int number_of_samples);
Speaker();
~Speaker();
private:
unsigned int _counter;
uint8_t _divider;
bool _is_enabled;
int16_t _output_level;
} _speaker;
Outputs::CRT _crt;
Speaker _speaker;
};
}