1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-31 14:29:25 +00:00

Merge pull request #665 from TomHarte/CPCCrash

Slightly improves CPC performance
This commit is contained in:
Thomas Harte 2019-10-20 20:19:29 -04:00 committed by GitHub
commit d4077afd30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 11 deletions

View File

@ -222,9 +222,9 @@ class CRTCBusHandler {
if(cycles_) {
switch(previous_output_mode_) {
default:
case OutputMode::Blank: crt_.output_blank(cycles_ * 16); break;
case OutputMode::Blank: crt_.output_blank(cycles_ * 16); break;
case OutputMode::Sync: crt_.output_sync(cycles_ * 16); break;
case OutputMode::Border: output_border(cycles_); break;
case OutputMode::Border: output_border(cycles_); break;
case OutputMode::ColourBurst: crt_.output_default_colour_burst(cycles_ * 16); break;
case OutputMode::Pixels:
crt_.output_data(cycles_ * 16, size_t(cycles_ * 16 / pixel_divider_));
@ -249,14 +249,16 @@ class CRTCBusHandler {
// the CPC shuffles output lines as:
// MA13 MA12 RA2 RA1 RA0 MA9 MA8 MA7 MA6 MA5 MA4 MA3 MA2 MA1 MA0 CCLK
// ... so form the real access address.
uint16_t address =
const uint16_t address =
static_cast<uint16_t>(
((state.refresh_address & 0x3ff) << 1) |
((state.row_address & 0x7) << 11) |
((state.refresh_address & 0x3000) << 2)
);
// fetch two bytes and translate into pixels
// Fetch two bytes and translate into pixels. Guaranteed: the mode can change only at
// hsync, so there's no risk of pixel_pointer_ overrunning 320 output pixels without
// exactly reaching 320 output pixels.
switch(mode_) {
case 0:
reinterpret_cast<uint16_t *>(pixel_pointer_)[0] = mode0_output_[ram_[address]];
@ -284,9 +286,9 @@ class CRTCBusHandler {
}
// flush the current buffer pixel if full; the CRTC allows many different display
// Flush the current buffer pixel if full; the CRTC allows many different display
// widths so it's not necessarily possible to predict the correct number in advance
// and using the upper bound could lead to inefficient behaviour
// and using the upper bound could lead to inefficient behaviour.
if(pixel_pointer_ == pixel_data_ + 320) {
crt_.output_data(cycles_ * 16, size_t(cycles_ * 16 / pixel_divider_));
pixel_pointer_ = pixel_data_ = nullptr;
@ -369,9 +371,17 @@ class CRTCBusHandler {
private:
void output_border(int length) {
uint8_t *colour_pointer = static_cast<uint8_t *>(crt_.begin_data(1));
if(colour_pointer) *colour_pointer = border_;
crt_.output_level(length * 16);
assert(length >= 0);
// A black border can be output via crt_.output_blank for a minor performance
// win; otherwise paint whatever the border colour really is.
if(border_) {
uint8_t *const colour_pointer = static_cast<uint8_t *>(crt_.begin_data(1));
if(colour_pointer) *colour_pointer = border_;
crt_.output_level(length * 16);
} else {
crt_.output_blank(length * 16);
}
}
#define Mode0Colour0(c) ((c & 0x80) >> 7) | ((c & 0x20) >> 3) | ((c & 0x08) >> 2) | ((c & 0x02) << 2)

View File

@ -123,8 +123,8 @@ class ScanTarget: public Outputs::Display::ScanTarget {
/// A pointer to the first thing not yet submitted for display.
std::atomic<PointerSet> read_pointers_;
// Maintains a buffer of the most recent 3072 scans.
std::array<Scan, 3072> scan_buffer_;
/// Maintains a buffer of the most recent scans.
std::array<Scan, 16384> scan_buffer_;
// Maintains a list of composite scan buffer coordinates; the Line struct
// is transported to the GPU in its entirety; the LineMetadatas live in CPU