mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-11 04:28:58 +00:00
Got back to a stable image, at least when staying in a mode. Which is what I was trying to fix. Hmmm.
This commit is contained in:
parent
dce1649fc5
commit
1954f7bcbd
@ -38,7 +38,7 @@ Machine::Machine() :
|
|||||||
"float texValue = texture(texID, coordinate).r;"
|
"float texValue = texture(texID, coordinate).r;"
|
||||||
"return vec3(step(4.0/256.0, mod(texValue, 8.0/256.0)), step(2.0/256.0, mod(texValue, 4.0/256.0)), step(1.0/256.0, mod(texValue, 2.0/256.0)));"
|
"return vec3(step(4.0/256.0, mod(texValue, 8.0/256.0)), step(2.0/256.0, mod(texValue, 4.0/256.0)), step(1.0/256.0, mod(texValue, 2.0/256.0)));"
|
||||||
"}");
|
"}");
|
||||||
_crt->set_visible_area(Outputs::Rect(0.23108f, 0.0f, 0.8125f, 0.98f)); //1875
|
// _crt->set_visible_area(Outputs::Rect(0.23108f, 0.0f, 0.8125f, 0.98f)); //1875
|
||||||
|
|
||||||
memset(_key_states, 0, sizeof(_key_states));
|
memset(_key_states, 0, sizeof(_key_states));
|
||||||
memset(_palette, 0xf, sizeof(_palette));
|
memset(_palette, 0xf, sizeof(_palette));
|
||||||
@ -388,16 +388,67 @@ inline void Machine::reset_pixel_output()
|
|||||||
_startLineAddress = _startScreenAddress;
|
_startLineAddress = _startScreenAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Machine::output_pixels(int number_of_pixels)
|
inline void Machine::output_pixels(int start_x, int number_of_pixels)
|
||||||
{
|
{
|
||||||
if(number_of_pixels)
|
if(number_of_pixels)
|
||||||
{
|
{
|
||||||
_crt->output_blank((unsigned int)number_of_pixels * crt_cycles_multiplier);
|
unsigned int newDivider = 0;
|
||||||
|
switch(_screen_mode)
|
||||||
|
{
|
||||||
|
case 0: case 3: newDivider = 1; break;
|
||||||
|
case 1: case 4: case 6: newDivider = 2; break;
|
||||||
|
case 2: case 5: newDivider = 4; break;
|
||||||
|
}
|
||||||
|
bool is40Column = (_screen_mode > 3);
|
||||||
|
|
||||||
|
if(!_writePointer || newDivider != _currentOutputDivider)
|
||||||
|
{
|
||||||
|
_currentOutputDivider = newDivider;
|
||||||
|
end_pixel_output();
|
||||||
|
_crt->allocate_write_area(640 / newDivider);
|
||||||
|
_currentLine = _writePointer = _crt->get_write_target_for_buffer(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is40Column)
|
||||||
|
{
|
||||||
|
number_of_pixels = ((start_x + number_of_pixels) >> 1) - (start_x >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(_screen_mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0: case 3: case 4: case 6:
|
||||||
|
while(number_of_pixels--)
|
||||||
|
{
|
||||||
|
_writePointer[0] = 7;
|
||||||
|
_writePointer += 8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: case 5:
|
||||||
|
while(number_of_pixels--)
|
||||||
|
{
|
||||||
|
_writePointer += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
while(number_of_pixels--)
|
||||||
|
{
|
||||||
|
_writePointer += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Machine::end_pixel_output()
|
inline void Machine::end_pixel_output()
|
||||||
{
|
{
|
||||||
|
if(_currentLine != nullptr)
|
||||||
|
{
|
||||||
|
_crt->output_data((unsigned int)((_writePointer - _currentLine) * _currentOutputDivider), _currentOutputDivider);
|
||||||
|
_writePointer = _currentLine = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Machine::update_pixels_to_position(int x, int y)
|
inline void Machine::update_pixels_to_position(int x, int y)
|
||||||
@ -419,11 +470,13 @@ inline void Machine::update_pixels_to_position(int x, int y)
|
|||||||
if(display_x < first_graphics_cycle+80)
|
if(display_x < first_graphics_cycle+80)
|
||||||
{
|
{
|
||||||
int cycles_to_output = (display_y < y) ? 80 + first_graphics_cycle - display_x : std::min(80, x - display_x);
|
int cycles_to_output = (display_y < y) ? 80 + first_graphics_cycle - display_x : std::min(80, x - display_x);
|
||||||
output_pixels(cycles_to_output);
|
output_pixels(display_x, cycles_to_output);
|
||||||
display_x += cycles_to_output;
|
display_x += cycles_to_output;
|
||||||
|
|
||||||
if(display_x == first_graphics_cycle+80)
|
if(display_x == first_graphics_cycle+80)
|
||||||
|
{
|
||||||
end_pixel_output();
|
end_pixel_output();
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,13 +528,13 @@ inline void Machine::update_display()
|
|||||||
|--B--|
|
|--B--|
|
||||||
|--P--|
|
|--P--|
|
||||||
|--B--|
|
|--B--|
|
||||||
|-B-
|
|
||||||
|
|
||||||
(2.5 lines of sync; half a line of blank; full blanks; pixels; full blanks; half blank)
|
(2.5 lines of sync; half a line of blank; full blanks; pixels; full blanks; half blank)
|
||||||
|
|
||||||
Even field:
|
Even field:
|
||||||
|
|
||||||
-S-|
|
|-B-S-|
|
||||||
|--S--|
|
|--S--|
|
||||||
|--S--|
|
|--S--|
|
||||||
|--B--|
|
|--B--|
|
||||||
@ -493,13 +546,13 @@ inline void Machine::update_display()
|
|||||||
So:
|
So:
|
||||||
|
|
||||||
Top:
|
Top:
|
||||||
|
if even then half a line of blank
|
||||||
2.5 lines of sync
|
2.5 lines of sync
|
||||||
if odd then half a line of blank
|
if odd then half a line of blank
|
||||||
full blanks
|
full blanks
|
||||||
Pixels
|
Pixels
|
||||||
Bottom:
|
Bottom:
|
||||||
full blanks
|
full blanks
|
||||||
if odd then half a line of blank
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -509,6 +562,8 @@ inline void Machine::update_display()
|
|||||||
// does the top region need to be output?
|
// does the top region need to be output?
|
||||||
if(_displayOutputPosition < end_of_top && _fieldCycles >= end_of_top)
|
if(_displayOutputPosition < end_of_top && _fieldCycles >= end_of_top)
|
||||||
{
|
{
|
||||||
|
// printf("[1] %d / %d\n", _crt->get_field_cycle() >> 10, (_crt->get_field_cycle() >> 3)&127);
|
||||||
|
if(!_is_odd_field) _crt->output_blank(64 * crt_cycles_multiplier);
|
||||||
_crt->output_sync(320 * crt_cycles_multiplier);
|
_crt->output_sync(320 * crt_cycles_multiplier);
|
||||||
if(_is_odd_field) _crt->output_blank(64 * crt_cycles_multiplier);
|
if(_is_odd_field) _crt->output_blank(64 * crt_cycles_multiplier);
|
||||||
|
|
||||||
@ -517,6 +572,7 @@ inline void Machine::update_display()
|
|||||||
_crt->output_sync(9 * crt_cycles_multiplier);
|
_crt->output_sync(9 * crt_cycles_multiplier);
|
||||||
_crt->output_blank(119 * crt_cycles_multiplier);
|
_crt->output_blank(119 * crt_cycles_multiplier);
|
||||||
}
|
}
|
||||||
|
// printf("[2] %d / %d\n", _crt->get_field_cycle() >> 10, (_crt->get_field_cycle() >> 3)&127);
|
||||||
|
|
||||||
_displayOutputPosition = end_of_top;
|
_displayOutputPosition = end_of_top;
|
||||||
|
|
||||||
@ -534,17 +590,17 @@ inline void Machine::update_display()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// is this the bottom region?
|
// is this the bottom region?
|
||||||
if(_displayOutputPosition < end_of_graphics && _fieldCycles > end_of_graphics)
|
if(_displayOutputPosition >= end_of_graphics && _displayOutputPosition < cycles_per_frame)
|
||||||
{
|
{
|
||||||
|
// printf("[3] %d / %d\n", _crt->get_field_cycle() >> 10, (_crt->get_field_cycle() >> 3)&127);
|
||||||
for(int y = first_graphics_line+256; y < 312; y++)
|
for(int y = first_graphics_line+256; y < 312; y++)
|
||||||
{
|
{
|
||||||
_crt->output_sync(9 * crt_cycles_multiplier);
|
_crt->output_sync(9 * crt_cycles_multiplier);
|
||||||
_crt->output_blank(119 * crt_cycles_multiplier);
|
_crt->output_blank(119 * crt_cycles_multiplier);
|
||||||
}
|
}
|
||||||
_displayOutputPosition = end_of_graphics;
|
_displayOutputPosition = cycles_per_frame;
|
||||||
|
|
||||||
if(_is_odd_field) _crt->output_blank(64 * crt_cycles_multiplier);
|
|
||||||
|
|
||||||
|
// printf("[4] %d / %d\n", _crt->get_field_cycle() >> 10, (_crt->get_field_cycle() >> 3)&127);
|
||||||
_is_odd_field ^= true;
|
_is_odd_field ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ class Machine: public CPU6502::Processor<Machine>, Tape::Delegate {
|
|||||||
|
|
||||||
inline void update_display();
|
inline void update_display();
|
||||||
inline void update_pixels_to_position(int x, int y);
|
inline void update_pixels_to_position(int x, int y);
|
||||||
inline void output_pixels(int number_of_pixels);
|
inline void output_pixels(int start_x, int number_of_pixels);
|
||||||
inline void end_pixel_output();
|
inline void end_pixel_output();
|
||||||
inline void reset_pixel_output();
|
inline void reset_pixel_output();
|
||||||
|
|
||||||
@ -189,9 +189,11 @@ class Machine: public CPU6502::Processor<Machine>, Tape::Delegate {
|
|||||||
// Display generation.
|
// Display generation.
|
||||||
uint16_t _startLineAddress, _currentScreenAddress;
|
uint16_t _startLineAddress, _currentScreenAddress;
|
||||||
int _currentOutputLine;
|
int _currentOutputLine;
|
||||||
|
bool _is_odd_field;
|
||||||
|
|
||||||
|
// CRT output
|
||||||
unsigned int _currentOutputDivider;
|
unsigned int _currentOutputDivider;
|
||||||
uint8_t *_currentLine, *_writePointer;
|
uint8_t *_currentLine, *_writePointer;
|
||||||
bool _is_odd_field;
|
|
||||||
|
|
||||||
// Tape.
|
// Tape.
|
||||||
Tape _tape;
|
Tape _tape;
|
||||||
|
@ -165,7 +165,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
|||||||
hsync_requested = false;
|
hsync_requested = false;
|
||||||
vsync_requested = false;
|
vsync_requested = false;
|
||||||
|
|
||||||
uint8_t *next_run = (is_output_run && next_run_length) ? _run_builders[_run_write_pointer]->get_next_input_run() : nullptr;
|
uint8_t *next_run = ((is_output_run && next_run_length) && !_horizontal_flywheel->is_in_retrace() && !_vertical_flywheel->is_in_retrace()) ? _run_builders[_run_write_pointer]->get_next_input_run() : nullptr;
|
||||||
int lengthMask = (_horizontal_flywheel->is_in_retrace() ? kRetraceXMask : 0) | (_vertical_flywheel->is_in_retrace() ? kRetraceYMask : 0);
|
int lengthMask = (_horizontal_flywheel->is_in_retrace() ? kRetraceXMask : 0) | (_vertical_flywheel->is_in_retrace() ? kRetraceYMask : 0);
|
||||||
|
|
||||||
#define position_x(v) (*(uint16_t *)&next_run[kCRTSizeOfVertex*v + kCRTVertexOffsetOfPosition + 0])
|
#define position_x(v) (*(uint16_t *)&next_run[kCRTSizeOfVertex*v + kCRTVertexOffsetOfPosition + 0])
|
||||||
@ -241,6 +241,13 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
|||||||
|
|
||||||
_run_write_pointer = (_run_write_pointer + 1)%kCRTNumberOfFrames;
|
_run_write_pointer = (_run_write_pointer + 1)%kCRTNumberOfFrames;
|
||||||
_run_builders[_run_write_pointer]->reset();
|
_run_builders[_run_write_pointer]->reset();
|
||||||
|
|
||||||
|
static int fc = 0;
|
||||||
|
fc++;
|
||||||
|
if(!(fc&15))
|
||||||
|
{
|
||||||
|
printf("H misses %d; v misses %d\n", _horizontal_flywheel->get_and_reset_number_of_surprises(), _vertical_flywheel->get_and_reset_number_of_surprises());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,7 +256,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
|||||||
|
|
||||||
void CRT::output_scan()
|
void CRT::output_scan()
|
||||||
{
|
{
|
||||||
_next_scan ^= 1;
|
// _next_scan ^= 1;
|
||||||
Scan *scan = &_scans[_next_scan];
|
Scan *scan = &_scans[_next_scan];
|
||||||
|
|
||||||
bool this_is_sync = (scan->type == Type::Sync);
|
bool this_is_sync = (scan->type == Type::Sync);
|
||||||
|
@ -214,6 +214,13 @@ class CRT {
|
|||||||
_visible_area = visible_area;
|
_visible_area = visible_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
inline uint32_t get_field_cycle()
|
||||||
|
{
|
||||||
|
return _run_builders[_run_write_pointer]->duration / _time_multiplier;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CRT();
|
CRT();
|
||||||
void allocate_buffers(unsigned int number, va_list sizes);
|
void allocate_buffers(unsigned int number, va_list sizes);
|
||||||
|
Loading…
Reference in New Issue
Block a user