mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-20 14:29:11 +00:00
Add a phoney colour burst.
This commit is contained in:
parent
6d7c6de32f
commit
1aa168054e
@ -85,14 +85,17 @@ class CGA {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct CRTCOutputter {
|
struct CRTCOutputter {
|
||||||
|
enum class OutputState {
|
||||||
|
Sync, Pixels, Border, ColourBurst
|
||||||
|
};
|
||||||
|
|
||||||
CRTCOutputter() :
|
CRTCOutputter() :
|
||||||
crt(912, 8, 262, 3, Outputs::Display::InputDataType::Red2Green2Blue2)
|
crt(912, 8, Outputs::Display::Type::NTSC60, Outputs::Display::InputDataType::Red2Green2Blue2)
|
||||||
{
|
{
|
||||||
// crt.set_visible_area(Outputs::Display::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f));
|
// crt.set_visible_area(Outputs::Display::Rect(0.1072f, 0.1f, 0.842105263157895f, 0.842105263157895f));
|
||||||
crt.set_display_type(Outputs::Display::DisplayType::RGB);
|
crt.set_display_type(Outputs::Display::DisplayType::CompositeColour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void set_mode(uint8_t control) {
|
void set_mode(uint8_t control) {
|
||||||
// b5: enable blink
|
// b5: enable blink
|
||||||
// b4: 1 => 640x200 graphics
|
// b4: 1 => 640x200 graphics
|
||||||
@ -100,7 +103,8 @@ class CGA {
|
|||||||
// b2: 1 => monochrome
|
// b2: 1 => monochrome
|
||||||
// b1: 1 => 320x200 graphics; 0 => text
|
// b1: 1 => 320x200 graphics; 0 => text
|
||||||
// b0: 1 => 80-column text; 0 => 40
|
// b0: 1 => 80-column text; 0 => 40
|
||||||
control_ = control;
|
|
||||||
|
control_ = control; // To capture blink, monochrome and video enable bits.
|
||||||
|
|
||||||
if(control & 0x2) {
|
if(control & 0x2) {
|
||||||
mode_ = (control & 0x10) ? Mode::Pixels640 : Mode::Pixels320;
|
mode_ = (control & 0x10) ? Mode::Pixels640 : Mode::Pixels320;
|
||||||
@ -130,11 +134,39 @@ class CGA {
|
|||||||
return control_;
|
return control_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_hsync(bool new_hsync) {
|
||||||
|
if(new_hsync == previous_hsync) {
|
||||||
|
cycles_since_hsync += clock_divider;
|
||||||
|
} else {
|
||||||
|
cycles_since_hsync = 0;
|
||||||
|
previous_hsync = new_hsync;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputState implied_state(const Motorola::CRTC::BusState &state) const {
|
||||||
|
OutputState new_state;
|
||||||
|
|
||||||
|
if(state.hsync || state.vsync) {
|
||||||
|
new_state = OutputState::Sync;
|
||||||
|
} else if(!state.display_enable || !(control_&0x08)) {
|
||||||
|
new_state = OutputState::Border;
|
||||||
|
|
||||||
|
if(cycles_since_hsync <= 4) {
|
||||||
|
new_state = OutputState::ColourBurst;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new_state = OutputState::Pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: impose a colour burst, if enabled.
|
||||||
|
|
||||||
|
return new_state;
|
||||||
|
}
|
||||||
|
|
||||||
void perform_bus_cycle_phase1(const Motorola::CRTC::BusState &state) {
|
void perform_bus_cycle_phase1(const Motorola::CRTC::BusState &state) {
|
||||||
// Determine new output state.
|
// Determine new output state.
|
||||||
const OutputState new_state =
|
update_hsync(state.hsync);
|
||||||
(state.hsync | state.vsync) ? OutputState::Sync :
|
const OutputState new_state = implied_state(state);
|
||||||
((state.display_enable && control_&0x08) ? OutputState::Pixels : OutputState::Border);
|
|
||||||
|
|
||||||
// Upon either a state change or just having accumulated too much local time...
|
// Upon either a state change or just having accumulated too much local time...
|
||||||
if(new_state != output_state || active_pixels_per_tick != pixels_per_tick || active_clock_divider != clock_divider || count > 912) {
|
if(new_state != output_state || active_pixels_per_tick != pixels_per_tick || active_clock_divider != clock_divider || count > 912) {
|
||||||
@ -143,6 +175,7 @@ class CGA {
|
|||||||
switch(output_state) {
|
switch(output_state) {
|
||||||
case OutputState::Sync: crt.output_sync(count * active_clock_divider); break;
|
case OutputState::Sync: crt.output_sync(count * active_clock_divider); break;
|
||||||
case OutputState::Border: crt.output_blank(count * active_clock_divider); break;
|
case OutputState::Border: crt.output_blank(count * active_clock_divider); break;
|
||||||
|
case OutputState::ColourBurst: crt.output_colour_burst(count * active_clock_divider, 0); break;
|
||||||
case OutputState::Pixels: flush_pixels(); break;
|
case OutputState::Pixels: flush_pixels(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,11 +322,12 @@ class CGA {
|
|||||||
std::vector<uint8_t> font;
|
std::vector<uint8_t> font;
|
||||||
|
|
||||||
// CRTC state tracking, for CRT serialisation.
|
// CRTC state tracking, for CRT serialisation.
|
||||||
enum class OutputState {
|
OutputState output_state = OutputState::Sync;
|
||||||
Sync, Pixels, Border
|
|
||||||
} output_state = OutputState::Sync;
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
bool previous_hsync = false;
|
||||||
|
int cycles_since_hsync = 0;
|
||||||
|
|
||||||
// Current Programmer-set parameters.
|
// Current Programmer-set parameters.
|
||||||
int clock_divider = 1;
|
int clock_divider = 1;
|
||||||
int pixels_per_tick = 8;
|
int pixels_per_tick = 8;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user