mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
At least manages to place a pixel region on screen.
Albeit that I've suddenly realised that I've failed properly to think about high-res versus low-res.
This commit is contained in:
parent
52e375a985
commit
6e034c9b7f
@ -206,20 +206,67 @@ template <int cycle> void Chipset::output() {
|
||||
LINK(burst, output_default_colour_burst, burst - blank2); // TODO: only if colour enabled.
|
||||
LINK(blank3, output_blank, blank3 - burst);
|
||||
|
||||
// Output colour 0 to fill the rest of the line; Kickstart uses this
|
||||
// colour to post the error code. TODO: actual pixels, etc.
|
||||
if(cycle == line_length_ - 1) {
|
||||
uint16_t *const pixels = reinterpret_cast<uint16_t *>(crt_.begin_data(1));
|
||||
if(pixels) {
|
||||
*pixels = palette_[0];
|
||||
display_horizontal_ |= (cycle*2) == fetch_window_[0];
|
||||
display_horizontal_ &= (cycle*2) != fetch_window_[1];
|
||||
|
||||
if constexpr (cycle > blank3) {
|
||||
const bool is_pixel_display = display_horizontal_ && fetch_vertical_;
|
||||
|
||||
if(
|
||||
(is_pixel_display == is_border_) ||
|
||||
(is_border_ && border_colour_ != palette_[0])) {
|
||||
flush_output();
|
||||
|
||||
is_border_ = !is_pixel_display;
|
||||
border_colour_ = palette_[0];
|
||||
}
|
||||
|
||||
if(is_pixel_display) {
|
||||
if(!pixels_) {
|
||||
uint16_t *const new_pixels = reinterpret_cast<uint16_t *>(crt_.begin_data(4 * size_t(line_length_ - cycle)));
|
||||
if(new_pixels) {
|
||||
flush_output();
|
||||
}
|
||||
pixels_ = new_pixels;
|
||||
}
|
||||
|
||||
if(pixels_) {
|
||||
pixels_[0] = 0xffff;
|
||||
pixels_[1] = 0x0000;
|
||||
pixels_[2] = 0xffff;
|
||||
pixels_[3] = 0x0000;
|
||||
pixels_ += 4;
|
||||
}
|
||||
}
|
||||
++zone_duration_;
|
||||
|
||||
// Output the rest of the line. TODO: optimise border area.
|
||||
if(cycle == line_length_ - 1) {
|
||||
flush_output();
|
||||
}
|
||||
crt_.output_data((cycle - blank3) * 4, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#undef LINK
|
||||
}
|
||||
|
||||
void Chipset::flush_output() {
|
||||
if(!zone_duration_) return;
|
||||
|
||||
if(is_border_) {
|
||||
uint16_t *const pixels = reinterpret_cast<uint16_t *>(crt_.begin_data(1));
|
||||
if(pixels) {
|
||||
*pixels = border_colour_;
|
||||
}
|
||||
crt_.output_data(zone_duration_ * 4, 1);
|
||||
} else {
|
||||
crt_.output_data(zone_duration_ * 4);
|
||||
}
|
||||
zone_duration_ = 0;
|
||||
pixels_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
|
||||
constexpr auto BlitterFlag = DMAMask<DMAFlag::Blitter, DMAFlag::AllBelow>::value;
|
||||
constexpr auto BitplaneFlag = DMAMask<DMAFlag::Bitplane, DMAFlag::AllBelow>::value;
|
||||
@ -229,8 +276,8 @@ template <int cycle, bool stop_if_cpu> bool Chipset::perform_cycle() {
|
||||
// Update state as to whether bitplane fetching should happen now.
|
||||
//
|
||||
// TODO: figure out how the hard stops factor into this.
|
||||
fetch_horizontal_ |= cycle == display_window_start_[0];
|
||||
fetch_horizontal_ &= cycle != display_window_stop_[0];
|
||||
fetch_horizontal_ |= cycle == fetch_window_[0];
|
||||
fetch_horizontal_ &= cycle != fetch_window_[1];
|
||||
|
||||
// Top priority: bitplane collection.
|
||||
if((dma_control_ & BitplaneFlag) == BitplaneFlag) {
|
||||
@ -361,6 +408,9 @@ template <bool stop_on_cpu> Chipset::Changes Chipset::run(HalfCycles length) {
|
||||
did_fetch_ = false;
|
||||
}
|
||||
|
||||
std::fill(even_playfield_.begin(), even_playfield_.end(), 0);
|
||||
std::fill(odd_playfield_.begin(), odd_playfield_.end(), 0);
|
||||
|
||||
if(y_ == frame_height_) {
|
||||
++changes.vsyncs;
|
||||
interrupt_requests_ |= InterruptMask<InterruptFlag::VerticalBlank>::value;
|
||||
|
@ -169,8 +169,16 @@ class Chipset {
|
||||
|
||||
// Ephemeral bitplane collection state.
|
||||
bool fetch_vertical_ = false, fetch_horizontal_ = false;
|
||||
bool display_horizontal_ = false;
|
||||
bool did_fetch_ = false;
|
||||
|
||||
// Output state.
|
||||
uint16_t border_colour_ = 0;
|
||||
bool is_border_ = true;
|
||||
int zone_duration_ = 0;
|
||||
uint16_t *pixels_ = nullptr;
|
||||
void flush_output();
|
||||
|
||||
using BitplaneData = std::array<uint16_t, 6>;
|
||||
|
||||
class Bitplanes: public DMADevice<6> {
|
||||
@ -184,15 +192,15 @@ class Chipset {
|
||||
private:
|
||||
bool is_high_res_ = false;
|
||||
int collection_offset_ = 0;
|
||||
int plane_count_ = 1;
|
||||
int plane_count_ = 0;
|
||||
|
||||
BitplaneData next;
|
||||
} bitplanes_;
|
||||
|
||||
void post_bitplanes(const BitplaneData &data);
|
||||
|
||||
uint8_t even_playfield_[912];
|
||||
uint8_t odd_playfield_[912];
|
||||
std::array<uint8_t, 912> even_playfield_;
|
||||
std::array<uint8_t, 912> odd_playfield_;
|
||||
int odd_delay_ = 0, even_delay_ = 0;
|
||||
|
||||
// MARK: - Copper.
|
||||
|
Loading…
x
Reference in New Issue
Block a user