mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-01 11:49:58 +00:00
Hacks in 40-column text.
Hot gossip: my IIgs is reporting a system error. A clue!
This commit is contained in:
parent
81c38c7200
commit
287bfeb924
@ -70,7 +70,7 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flushes only if the @c threshold (measured in LocalTimeScale) has been crossed.
|
/// Flushes only if the next window of size @c threshold (measured in LocalTimeScale) has been crossed since the last flush.
|
||||||
template<int threshold> forceinline bool check_flush_threshold() {
|
template<int threshold> forceinline bool check_flush_threshold() {
|
||||||
if(time_since_update_.as_integral() >= threshold) {
|
if(time_since_update_.as_integral() >= threshold) {
|
||||||
flush();
|
flush();
|
||||||
|
@ -533,6 +533,7 @@ class ConcreteMachine:
|
|||||||
video_ += duration;
|
video_ += duration;
|
||||||
|
|
||||||
// Ensure no more than a single line is enqueued for just-in-time video purposes.
|
// Ensure no more than a single line is enqueued for just-in-time video purposes.
|
||||||
|
// TODO: as implemented, check_flush_threshold doesn't actually work. Can it be made to, or is it a bad idea?
|
||||||
if(video_.check_flush_threshold<131>()) {
|
if(video_.check_flush_threshold<131>()) {
|
||||||
update_interrupts();
|
update_interrupts();
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ void VideoBase::output_row(int row, int start, int end) {
|
|||||||
//
|
//
|
||||||
// Guessing four cycles of sync, I've chosen to arrange one output row for this emulator as:
|
// Guessing four cycles of sync, I've chosen to arrange one output row for this emulator as:
|
||||||
//
|
//
|
||||||
// 5 cycles of back porch;
|
// 5 cycles of back porch; [TODO: include a colour burst]
|
||||||
// 8 windows left border, the final five of which fetch palette and control if in IIgs mode;
|
// 8 windows left border, the final five of which fetch palette and control if in IIgs mode;
|
||||||
// 40 windows of pixel output;
|
// 40 windows of pixel output;
|
||||||
// 8 cycles of right border;
|
// 8 cycles of right border;
|
||||||
@ -166,20 +166,47 @@ void VideoBase::output_row(int row, int start, int end) {
|
|||||||
if(start == end) return;
|
if(start == end) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output left border as far as currently known.
|
// Fetch and output such pixels as it is time for.
|
||||||
if(start >= start_of_pixels && start < start_of_right_border) {
|
if(start >= start_of_pixels && start < start_of_right_border) {
|
||||||
const int end_of_period = std::min(start_of_right_border, end);
|
const int end_of_period = std::min(start_of_right_border, end);
|
||||||
|
|
||||||
// TODO: output real pixels.
|
if(start == start_of_pixels) {
|
||||||
uint16_t *const pixel = reinterpret_cast<uint16_t *>(crt_.begin_data(2, 2));
|
// 640 is the absolute most number of pixels that might be generated
|
||||||
if(pixel) *pixel = appleii_palette[7];
|
next_pixel_ = pixels_ = reinterpret_cast<uint16_t *>(crt_.begin_data(640, 2));
|
||||||
crt_.output_data((end_of_period - start) * CyclesPerTick, 1);
|
}
|
||||||
|
|
||||||
|
// TODO: support modes other than 40-column text.
|
||||||
|
if(next_pixel_) {
|
||||||
|
uint16_t row_address = get_row_address(row);
|
||||||
|
for(int c = start; c < end_of_period; c++) {
|
||||||
|
const uint8_t source = ram_[row_address + c];
|
||||||
|
const int character = source & character_zones_[source >> 6].address_mask;
|
||||||
|
const uint8_t xor_mask = character_zones_[source >> 6].xor_mask;
|
||||||
|
const std::size_t character_address = size_t(character << 3) + (row & 7);
|
||||||
|
const uint8_t character_pattern = character_rom_[character_address] ^ xor_mask;
|
||||||
|
const uint16_t colours[2] = {background_colour_, text_colour_};
|
||||||
|
|
||||||
|
next_pixel_[0] = colours[(character_pattern & 0x40) >> 6];
|
||||||
|
next_pixel_[1] = colours[(character_pattern & 0x20) >> 5];
|
||||||
|
next_pixel_[2] = colours[(character_pattern & 0x10) >> 4];
|
||||||
|
next_pixel_[3] = colours[(character_pattern & 0x08) >> 3];
|
||||||
|
next_pixel_[4] = colours[(character_pattern & 0x04) >> 2];
|
||||||
|
next_pixel_[5] = colours[(character_pattern & 0x02) >> 1];
|
||||||
|
next_pixel_[6] = colours[(character_pattern & 0x01) >> 0];
|
||||||
|
next_pixel_ += 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(end_of_period == start_of_right_border) {
|
||||||
|
crt_.output_data((start_of_right_border - start_of_pixels) * CyclesPerTick, next_pixel_ ? size_t(next_pixel_ - pixels_) : 1);
|
||||||
|
next_pixel_ = pixels_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
start = end_of_period;
|
start = end_of_period;
|
||||||
if(start == end) return;
|
if(start == end) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output left border as far as currently known.
|
// Output right border as far as currently known.
|
||||||
if(start >= start_of_right_border && start < start_of_sync) {
|
if(start >= start_of_right_border && start < start_of_sync) {
|
||||||
const int end_of_period = std::min(start_of_sync, end);
|
const int end_of_period = std::min(start_of_sync, end);
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ class VideoBase: public Apple::II::VideoSwitches<Cycles> {
|
|||||||
uint16_t text_colour_ = 0xfff;
|
uint16_t text_colour_ = 0xfff;
|
||||||
uint16_t background_colour_ = 0;
|
uint16_t background_colour_ = 0;
|
||||||
|
|
||||||
|
// Current pixel output buffer.
|
||||||
|
uint16_t *pixels_ = nullptr, *next_pixel_ = nullptr;
|
||||||
|
|
||||||
void output_row(int row, int start, int end);
|
void output_row(int row, int start, int end);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user