1
0
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:
Thomas Harte 2023-12-06 13:10:28 -05:00
parent 6d7c6de32f
commit 1aa168054e

View File

@ -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;