1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Introduced a compile-time configurable audio divider, set it arbitrarily to '8' for now. Discovered why my graphics aren't centred and added a TODO.

This commit is contained in:
Thomas Harte 2016-04-13 22:31:59 -04:00
parent 026ce0255f
commit 6a17c2992d
3 changed files with 15 additions and 11 deletions

View File

@ -31,6 +31,8 @@ namespace {
static const unsigned int real_time_clock_interrupt_1 = 16704;
static const unsigned int real_time_clock_interrupt_2 = 56704;
static const unsigned int clock_rate_audio_divider = 8;
}
#define graphics_line(v) ((((v) >> 7) - first_graphics_line + field_divider_line) % field_divider_line)
@ -42,7 +44,6 @@ Machine::Machine() :
_frameCycles(0),
_displayOutputPosition(0),
_audioOutputPosition(0),
_audioOutputPositionError(0),
_current_pixel_line(-1),
_use_fast_tape_hack(false),
_crt(nullptr)
@ -65,13 +66,15 @@ void Machine::setup_output(float aspect_ratio)
"texValue >>= 4 - (int(icoordinate.x * 8) & 4);"
"return vec3( uvec3(texValue) & uvec3(4u, 2u, 1u));"
"}");
_crt->set_output_device(Outputs::CRT::Television);
_crt->set_visible_area(_crt->get_rect_for_area(first_graphics_line - 3, 256, first_graphics_cycle * crt_cycles_multiplier, 80 * crt_cycles_multiplier, 4.0f / 3.0f));
_crt->set_output_device(Outputs::CRT::Monitor);
// TODO: as implied below, I've introduced a clock's latency into the graphics pipeline somehow. Investigate.
_crt->set_visible_area(_crt->get_rect_for_area(first_graphics_line - 3, 256, (first_graphics_cycle+1) * crt_cycles_multiplier, 80 * crt_cycles_multiplier, 4.0f / 3.0f));
// 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
// run the speaker at a 2000000Hz input rate, at least for the time being.
_speaker.set_input_rate(2000000);
_speaker.set_input_rate(2000000 / clock_rate_audio_divider);
}
unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value)
@ -495,9 +498,10 @@ inline void Machine::evaluate_interrupts()
inline void Machine::update_audio()
{
int difference = (int)_frameCycles - _audioOutputPosition;
_speaker.run_for_cycles(difference);
_audioOutputPosition = (int)_frameCycles;
unsigned int difference = _frameCycles - _audioOutputPosition;
_audioOutputPosition = _frameCycles;
_speaker.run_for_cycles(difference / clock_rate_audio_divider);
_audioOutputPositionError = difference % clock_rate_audio_divider;
}
inline void Machine::start_pixel_line()
@ -853,7 +857,7 @@ void Speaker::skip_samples(unsigned int number_of_samples)
void Speaker::set_divider(uint8_t divider)
{
_divider = divider * 32;
_divider = divider * 32 / clock_rate_audio_divider;
}
void Speaker::set_is_enabled(bool is_enabled)

View File

@ -187,7 +187,7 @@ class Machine: public CPU6502::Processor<Machine>, Tape::Delegate {
// Counters related to simultaneous subsystems;
unsigned int _frameCycles, _displayOutputPosition;
int _audioOutputPosition, _audioOutputPositionError;
unsigned int _audioOutputPosition, _audioOutputPositionError;
struct {
uint16_t forty1bpp[256];

View File

@ -72,7 +72,7 @@ class Speaker {
template <class T> class Filter: public Speaker {
public:
void run_for_cycles(int input_cycles)
void run_for_cycles(unsigned int input_cycles)
{
if(_coefficients_are_dirty) update_filter_coefficients();
@ -81,7 +81,7 @@ template <class T> class Filter: public Speaker {
// fill up as much of the input buffer as possible
while(input_cycles)
{
unsigned int cycles_to_read = (unsigned int)std::min(input_cycles, _number_of_taps - _input_buffer_depth);
unsigned int cycles_to_read = (unsigned int)std::min((int)input_cycles, _number_of_taps - _input_buffer_depth);
static_cast<T *>(this)->get_samples(cycles_to_read, &_input_buffer.get()[_input_buffer_depth]);
input_cycles -= cycles_to_read;
_input_buffer_depth += cycles_to_read;