1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Got a bit higher level in CRT timing specification. Which internally allows it now to infer the colour clock frequency. Which will be helpful momentarily.

This commit is contained in:
Thomas Harte 2016-01-23 18:53:20 -05:00
parent a9e26d7808
commit ace331d4b4
4 changed files with 67 additions and 22 deletions

View File

@ -24,7 +24,7 @@ Machine::Machine() :
_piaDataValue{0xff, 0xff},
_tiaInputValue{0xff, 0xff}
{
_crt = new Outputs::CRT(228, 262, 1, 2);
_crt = new Outputs::CRT(228, Outputs::CRT::DisplayType::NTSC60, 1, 2);
memset(_collisions, 0xff, sizeof(_collisions));
set_reset_line(true);
}
@ -37,7 +37,7 @@ Machine::~Machine()
void Machine::switch_region()
{
_crt->set_new_timing(228, 312);
_crt->set_new_display_type(228, Outputs::CRT::DisplayType::PAL50);
}
void Machine::get_output_pixel(uint8_t *pixel, int offset)

View File

@ -26,7 +26,7 @@ Machine::Machine() :
_audioOutputPosition(0),
_audioOutputPositionError(0),
_currentOutputLine(0),
_crt(Outputs::CRT(crt_cycles_per_line, 312, 1, 1))
_crt(Outputs::CRT(crt_cycles_per_line, Outputs::CRT::DisplayType::PAL50, 1, 1))
{
memset(_keyStates, 0, sizeof(_keyStates));
memset(_palette, 0xf, sizeof(_palette));

View File

@ -25,7 +25,7 @@ static const uint32_t kCRTFixedPointOffset = 0x04000000;
#define kRetraceXMask 0x01
#define kRetraceYMask 0x02
void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display)
void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator)
{
const unsigned int syncCapacityLineChargeThreshold = 3;
const unsigned int millisecondsHorizontalRetraceTime = 7; // source: Dictionary of Video and Television Technology, p. 234
@ -62,9 +62,42 @@ void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_di
_beamWidth[c].x = (uint32_t)((sinf(angle) / halfLineWidth) * kCRTFixedPointRange);
_beamWidth[c].y = (uint32_t)((cosf(angle) / halfLineWidth) * kCRTFixedPointRange);
}
// reset flywheel sync
_expected_next_hsync = _cycles_per_line;
}
CRT::CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int number_of_buffers, ...) :
void CRT::set_new_display_type(unsigned int cycles_per_line, DisplayType displayType)
{
switch(displayType)
{
case DisplayType::PAL50:
set_new_timing(cycles_per_line, 312, 1135, 4);
break;
case DisplayType::NTSC60:
set_new_timing(cycles_per_line, 262, 545, 2);
break;
}
}
void CRT::allocate_buffers(unsigned int number, va_list sizes)
{
// generate buffers for signal storage as requested — format is
// number of buffers, size of buffer 1, size of buffer 2...
const uint16_t bufferWidth = 2048;
const uint16_t bufferHeight = 2048;
for(int frame = 0; frame < sizeof(_frame_builders) / sizeof(*_frame_builders); frame++)
{
va_list va;
va_copy(va, sizes);
_frame_builders[frame] = new CRTFrameBuilder(bufferWidth, bufferHeight, number, va);
va_end(va);
}
_current_frame_builder = _frame_builders[0];
}
CRT::CRT() :
_next_scan(0),
_frames_with_delegate(0),
_frame_read_pointer(0),
@ -74,24 +107,26 @@ CRT::CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned
_is_in_hsync(false),
_is_in_vsync(false),
_rasterPosition({.x = 0, .y = 0})
{}
CRT::CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator, unsigned int number_of_buffers, ...) : CRT()
{
set_new_timing(cycles_per_line, height_of_display);
set_new_timing(cycles_per_line, height_of_display, colour_cycle_numerator, colour_cycle_denominator);
// generate buffers for signal storage as requested — format is
// number of buffers, size of buffer 1, size of buffer 2...
const uint16_t bufferWidth = 2048;
const uint16_t bufferHeight = 2048;
for(int frame = 0; frame < sizeof(_frame_builders) / sizeof(*_frame_builders); frame++)
{
va_list va;
va_start(va, number_of_buffers);
_frame_builders[frame] = new CRTFrameBuilder(bufferWidth, bufferHeight, number_of_buffers, va);
va_end(va);
}
_current_frame_builder = _frame_builders[0];
va_list buffer_sizes;
va_start(buffer_sizes, number_of_buffers);
allocate_buffers(number_of_buffers, buffer_sizes);
va_end(buffer_sizes);
}
// reset flywheel sync
_expected_next_hsync = _cycles_per_line;
CRT::CRT(unsigned int cycles_per_line, DisplayType displayType, unsigned int number_of_buffers, ...) : CRT()
{
set_new_display_type(cycles_per_line, displayType);
va_list buffer_sizes;
va_start(buffer_sizes, number_of_buffers);
allocate_buffers(number_of_buffers, buffer_sizes);
va_end(buffer_sizes);
}
CRT::~CRT()

View File

@ -48,10 +48,17 @@ static const int kCRTNumberOfFrames = 4;
class CRT {
public:
CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int number_of_buffers, ...);
enum DisplayType {
PAL50,
NTSC60
};
CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator, unsigned int number_of_buffers, ...);
CRT(unsigned int cycles_per_line, DisplayType displayType, unsigned int number_of_buffers, ...);
~CRT();
void set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display);
void set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator);
void set_new_display_type(unsigned int cycles_per_line, DisplayType displayType);
/*! Output at the sync level.
@ -105,6 +112,9 @@ class CRT {
uint8_t *get_write_target_for_buffer(int buffer);
private:
CRT();
void allocate_buffers(unsigned int number, va_list sizes);
// the incoming clock lengths will be multiplied by something to give at least 1000
// sample points per line
unsigned int _time_multiplier;