1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-29 16:55:59 +00:00

Maintain an actual pixel buffer.

This commit is contained in:
Thomas Harte 2023-11-22 13:40:50 -05:00
parent 12179e486f
commit f249e4ada6

View File

@ -90,30 +90,59 @@ class MDA {
} }
void perform_bus_cycle_phase1(const Motorola::CRTC::BusState &state) { void perform_bus_cycle_phase1(const Motorola::CRTC::BusState &state) {
// Determine new output state.
const OutputState new_state = const OutputState new_state =
(state.hsync | state.vsync) ? OutputState::Sync : (state.hsync | state.vsync) ? OutputState::Sync :
(state.display_enable ? OutputState::Pixels : OutputState::Border); (state.display_enable ? OutputState::Pixels : OutputState::Border);
if(new_state != output_state) {
switch(output_state) {
case OutputState::Sync:
crt.output_sync(count);
break;
case OutputState::Border: // Upon either a state change or just having accumulated too much local time...
case OutputState::Pixels: { if(new_state != output_state || count > 882) {
uint8_t *const target = crt.begin_data(1); // (1) flush preexisting state.
if(target) { if(count) {
target[0] = (output_state == OutputState::Border) ? 0x00 : 0xff; switch(output_state) {
} case OutputState::Sync: crt.output_sync(count); break;
crt.output_level(count); case OutputState::Border: crt.output_blank(count); break;
} break; case OutputState::Pixels:
crt.output_data(count);
pixels = pixel_pointer = nullptr;
break;
}
} }
// (2) adopt new state.
output_state = new_state; output_state = new_state;
count = 0; count = 0;
} }
// Collect pixels if applicable.
if(output_state == OutputState::Pixels) {
if(!pixels) {
pixel_pointer = pixels = crt.begin_data(DefaultAllocationSize);
// Flush any period where pixels weren't recorded due to back pressure.
if(pixels && count) {
crt.output_blank(count);
count = 0;
}
}
if(pixels) {
pixel_pointer[0] = pixel_pointer[2] = pixel_pointer[4] = pixel_pointer[6] = 0;
pixel_pointer[1] = pixel_pointer[3] = pixel_pointer[5] = pixel_pointer[7] = pixel_pointer[8] = 1;
pixel_pointer += 9;
}
}
// Advance.
count += 9; count += 9;
// Output pixel row prematurely if storage is exhausted.
if(output_state == OutputState::Pixels && pixel_pointer == pixels + DefaultAllocationSize) {
crt.output_data(count);
count = 0;
pixels = pixel_pointer = nullptr;
}
} }
void perform_bus_cycle_phase2(const Motorola::CRTC::BusState &) {} void perform_bus_cycle_phase2(const Motorola::CRTC::BusState &) {}
@ -123,6 +152,10 @@ class MDA {
Sync, Pixels, Border Sync, Pixels, Border
} output_state = OutputState::Sync; } output_state = OutputState::Sync;
int count = 0; int count = 0;
uint8_t *pixels = nullptr;
uint8_t *pixel_pointer = nullptr;
static constexpr size_t DefaultAllocationSize = 720;
} outputter_; } outputter_;
Motorola::CRTC::CRTC6845<CRTCOutputter> crtc_; Motorola::CRTC::CRTC6845<CRTCOutputter> crtc_;