mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 16:31:31 +00:00
Without yet figuring out what vertical sync is meant to do, moved just about far enough forwards to see _something_ that hopefully I can soon discern characters within.
This commit is contained in:
parent
444d3b69b6
commit
79e05a2413
@ -38,7 +38,7 @@ MOS6560::MOS6560() :
|
|||||||
_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)"
|
||||||
"{"
|
"{"
|
||||||
"return vec3(1.0);"
|
"return vec3(texture(sampler, coordinate).r / 15.0);"
|
||||||
"}");
|
"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +71,11 @@ void MOS6560::set_register(int address, uint8_t value)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf:
|
case 0xf:
|
||||||
|
if(_this_state == State::Border)
|
||||||
|
{
|
||||||
|
output_border(_cycles_in_state * 4);
|
||||||
|
_cycles_in_state = 0;
|
||||||
|
}
|
||||||
_invertedCells = !!((value >> 3)&1);
|
_invertedCells = !!((value >> 3)&1);
|
||||||
_borderColour = value & 0x07;
|
_borderColour = value & 0x07;
|
||||||
_backgroundColour = value >> 4;
|
_backgroundColour = value >> 4;
|
||||||
@ -83,31 +88,21 @@ void MOS6560::set_register(int address, uint8_t value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MOS6560::output_border(unsigned int number_of_cycles)
|
||||||
|
{
|
||||||
|
uint8_t *colour_pointer = _crt->allocate_write_area(1);
|
||||||
|
if(colour_pointer) *colour_pointer = _borderColour;
|
||||||
|
_crt->output_level(number_of_cycles);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t MOS6560::get_address()
|
uint16_t MOS6560::get_address()
|
||||||
{
|
{
|
||||||
/*
|
// determine output state; colour burst and sync timing are currently a guess
|
||||||
Per http://tinyvga.com/6561 :
|
if(_horizontal_counter > 61) _this_state = State::ColourBurst;
|
||||||
|
else if(_horizontal_counter > 57) _this_state = State::Sync;
|
||||||
The basic video timing is very simple. For
|
|
||||||
every character the VIC-I is about to display, it first fetches the
|
|
||||||
character code and colour, then the character appearance (from the
|
|
||||||
character generator memory). The character codes are read on every
|
|
||||||
raster line, thus making every line a "bad line". When the raster
|
|
||||||
beam is outside of the text window, the videochip reads from $001c for
|
|
||||||
most time. (Some videochips read from $181c instead.) The address
|
|
||||||
occasionally varies, but it might also be due to a flaky bus. (By
|
|
||||||
reading from unconnected address space, such as $9100-$910f, you can
|
|
||||||
read the data fetched by the videochip on the previous clock cycle.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
State this_state;
|
|
||||||
|
|
||||||
// random guesses; who knows?
|
|
||||||
if(_horizontal_counter > 61) this_state = State::ColourBurst;
|
|
||||||
else if(_horizontal_counter > 57) this_state = State::Sync;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this_state = (_column_counter >= 0 && _row_counter >= 0) ? State::Pixels : State::Border;
|
_this_state = (_column_counter >= 0 && _row_counter >= 0) ? State::Pixels : State::Border;
|
||||||
}
|
}
|
||||||
|
|
||||||
_horizontal_counter++;
|
_horizontal_counter++;
|
||||||
@ -139,10 +134,71 @@ uint16_t MOS6560::get_address()
|
|||||||
}
|
}
|
||||||
else if(_horizontal_counter == _first_column_location) _column_counter = 0;
|
else if(_horizontal_counter == _first_column_location) _column_counter = 0;
|
||||||
|
|
||||||
|
// update the CRT
|
||||||
|
if(_this_state != _output_state)
|
||||||
|
{
|
||||||
|
switch(_output_state)
|
||||||
|
{
|
||||||
|
case State::Sync: _crt->output_sync(_cycles_in_state * 4); break;
|
||||||
|
case State::ColourBurst: _crt->output_colour_burst(_cycles_in_state * 4, 0, 0); break;
|
||||||
|
case State::Border: output_border(_cycles_in_state * 4); break;
|
||||||
|
case State::Pixels: _crt->output_data(_cycles_in_state * 4, 1); break;
|
||||||
|
}
|
||||||
|
_output_state = _this_state;
|
||||||
|
_cycles_in_state = 0;
|
||||||
|
|
||||||
|
pixel_pointer = nullptr;
|
||||||
|
if(_output_state == State::Pixels)
|
||||||
|
{
|
||||||
|
pixel_pointer = _crt->allocate_write_area(260);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_cycles_in_state++;
|
||||||
|
|
||||||
|
// compute the address
|
||||||
|
if(_this_state == State::Pixels)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Per http://tinyvga.com/6561 :
|
||||||
|
|
||||||
|
The basic video timing is very simple. For
|
||||||
|
every character the VIC-I is about to display, it first fetches the
|
||||||
|
character code and colour, then the character appearance (from the
|
||||||
|
character generator memory). The character codes are read on every
|
||||||
|
raster line, thus making every line a "bad line". When the raster
|
||||||
|
beam is outside of the text window, the videochip reads from $001c for
|
||||||
|
most time. (Some videochips read from $181c instead.) The address
|
||||||
|
occasionally varies, but it might also be due to a flaky bus. (By
|
||||||
|
reading from unconnected address space, such as $9100-$910f, you can
|
||||||
|
read the data fetched by the videochip on the previous clock cycle.)
|
||||||
|
*/
|
||||||
|
// TODO: increment this address
|
||||||
|
if(_column_counter&1)
|
||||||
|
return _character_cell_start_address + _character_code*8;
|
||||||
|
else
|
||||||
|
return _video_matrix_start_address;
|
||||||
|
}
|
||||||
|
|
||||||
return 0x1c;
|
return 0x1c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MOS6560::set_graphics_value(uint8_t value, uint8_t colour_value)
|
void MOS6560::set_graphics_value(uint8_t value, uint8_t colour_value)
|
||||||
{
|
{
|
||||||
|
if(_this_state == State::Pixels)
|
||||||
|
{
|
||||||
|
if(_column_counter&1)
|
||||||
|
{
|
||||||
|
// TODO: output proper pixels here
|
||||||
|
if(pixel_pointer)
|
||||||
|
{
|
||||||
|
*pixel_pointer = (uint8_t)rand();
|
||||||
|
pixel_pointer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_character_code = value;
|
||||||
|
_character_colour = colour_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,14 @@ class MOS6560 {
|
|||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
Sync, ColourBurst, Border, Pixels
|
Sync, ColourBurst, Border, Pixels
|
||||||
};
|
} _this_state, _output_state;
|
||||||
|
unsigned int _cycles_in_state;
|
||||||
|
|
||||||
|
uint8_t _character_code, _character_colour;
|
||||||
|
|
||||||
|
uint8_t *pixel_pointer;
|
||||||
|
|
||||||
|
void output_border(unsigned int number_of_cycles);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user