mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-19 23:29:05 +00:00
Attempts an implementation of the undocumented low res + annunciator 3 graphics mode.
This commit is contained in:
parent
afeec09902
commit
d70f5da94e
@ -243,6 +243,28 @@ void VideoBase::output_low_resolution(uint8_t *target, const uint8_t *const sour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoBase::output_fat_low_resolution(uint8_t *target, const uint8_t *const source, size_t length, int column, int row) const {
|
||||||
|
const int row_shift = row&4;
|
||||||
|
for(size_t c = 0; c < length; ++c) {
|
||||||
|
// Low-resolution graphics mode shifts the colour code on a loop, but has to account for whether this
|
||||||
|
// 14-sample output window is starting at the beginning of a colour cycle or halfway through.
|
||||||
|
if((column + static_cast<int>(c))&1) {
|
||||||
|
target[0] = target[1] = target[8] = target[9] = (source[c] >> row_shift) & 4;
|
||||||
|
target[2] = target[3] = target[10] = target[11] = (source[c] >> row_shift) & 8;
|
||||||
|
target[4] = target[5] = target[12] = target[13] = (source[c] >> row_shift) & 1;
|
||||||
|
target[6] = target[7] = (source[c] >> row_shift) & 2;
|
||||||
|
graphics_carry_ = (source[c] >> row_shift) & 8;
|
||||||
|
} else {
|
||||||
|
target[0] = target[1] = target[8] = target[9] = (source[c] >> row_shift) & 1;
|
||||||
|
target[2] = target[3] = target[10] = target[11] = (source[c] >> row_shift) & 2;
|
||||||
|
target[4] = target[5] = target[12] = target[13] = (source[c] >> row_shift) & 4;
|
||||||
|
target[6] = target[7] = (source[c] >> row_shift) & 8;
|
||||||
|
graphics_carry_ = (source[c] >> row_shift) & 2;
|
||||||
|
}
|
||||||
|
target += 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VideoBase::output_double_low_resolution(uint8_t *target, const uint8_t *const source, const uint8_t *const auxiliary_source, size_t length, int column, int row) const {
|
void VideoBase::output_double_low_resolution(uint8_t *target, const uint8_t *const source, const uint8_t *const auxiliary_source, size_t length, int column, int row) const {
|
||||||
const int row_shift = row&4;
|
const int row_shift = row&4;
|
||||||
for(size_t c = 0; c < length; ++c) {
|
for(size_t c = 0; c < length; ++c) {
|
||||||
|
@ -159,14 +159,15 @@ class VideoBase {
|
|||||||
|
|
||||||
// Enumerates all Apple II and IIe display modes.
|
// Enumerates all Apple II and IIe display modes.
|
||||||
enum class GraphicsMode {
|
enum class GraphicsMode {
|
||||||
LowRes = 0,
|
Text = 0,
|
||||||
DoubleLowRes,
|
DoubleText,
|
||||||
HighRes,
|
HighRes,
|
||||||
DoubleHighRes,
|
DoubleHighRes,
|
||||||
Text,
|
LowRes,
|
||||||
DoubleText,
|
DoubleLowRes,
|
||||||
|
FatLowRes
|
||||||
};
|
};
|
||||||
bool is_text_mode(GraphicsMode m) { return m >= GraphicsMode::Text; }
|
bool is_text_mode(GraphicsMode m) { return m <= GraphicsMode::DoubleText; }
|
||||||
bool is_double_mode(GraphicsMode m) { return !!(static_cast<int>(m)&1); }
|
bool is_double_mode(GraphicsMode m) { return !!(static_cast<int>(m)&1); }
|
||||||
|
|
||||||
// Various soft-switch values.
|
// Various soft-switch values.
|
||||||
@ -238,6 +239,14 @@ class VideoBase {
|
|||||||
*/
|
*/
|
||||||
void output_double_high_resolution(uint8_t *target, const uint8_t *source, const uint8_t *auxiliary_source, size_t length) const;
|
void output_double_high_resolution(uint8_t *target, const uint8_t *source, const uint8_t *auxiliary_source, size_t length) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Outputs 40-column "fat low resolution" graphics to @c target, drawing @c length columns from @c source.
|
||||||
|
|
||||||
|
Fat low-resolution mode is like regular low-resolution mode except that data is shifted out on the 7M
|
||||||
|
clock rather than the 14M.
|
||||||
|
*/
|
||||||
|
void output_fat_low_resolution(uint8_t *target, const uint8_t *source, size_t length, int column, int row) const;
|
||||||
|
|
||||||
// Maintain a ClockDeferrer for delayed mode switches.
|
// Maintain a ClockDeferrer for delayed mode switches.
|
||||||
ClockDeferrer<Cycles> deferrer_;
|
ClockDeferrer<Cycles> deferrer_;
|
||||||
};
|
};
|
||||||
@ -368,6 +377,7 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
|||||||
case GraphicsMode::Text:
|
case GraphicsMode::Text:
|
||||||
case GraphicsMode::DoubleText:
|
case GraphicsMode::DoubleText:
|
||||||
case GraphicsMode::LowRes:
|
case GraphicsMode::LowRes:
|
||||||
|
case GraphicsMode::FatLowRes:
|
||||||
case GraphicsMode::DoubleLowRes: {
|
case GraphicsMode::DoubleLowRes: {
|
||||||
const uint16_t text_address = static_cast<uint16_t>(((video_page()+1) * 0x400) + row_address);
|
const uint16_t text_address = static_cast<uint16_t>(((video_page()+1) * 0x400) + row_address);
|
||||||
fetch_address = static_cast<uint16_t>(text_address + column_);
|
fetch_address = static_cast<uint16_t>(text_address + column_);
|
||||||
@ -441,6 +451,15 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
|||||||
pixel_row);
|
pixel_row);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GraphicsMode::FatLowRes:
|
||||||
|
output_fat_low_resolution(
|
||||||
|
&pixel_pointer_[pixel_start * 14 + 7],
|
||||||
|
&base_stream_[static_cast<size_t>(pixel_start)],
|
||||||
|
static_cast<size_t>(pixel_end - pixel_start),
|
||||||
|
pixel_start,
|
||||||
|
pixel_row);
|
||||||
|
break;
|
||||||
|
|
||||||
case GraphicsMode::DoubleLowRes:
|
case GraphicsMode::DoubleLowRes:
|
||||||
output_double_low_resolution(
|
output_double_low_resolution(
|
||||||
&pixel_pointer_[pixel_start * 14],
|
&pixel_pointer_[pixel_start * 14],
|
||||||
@ -548,7 +567,9 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
|||||||
if(high_resolution_) {
|
if(high_resolution_) {
|
||||||
return (annunciator_3_ && columns_80_) ? GraphicsMode::DoubleHighRes : GraphicsMode::HighRes;
|
return (annunciator_3_ && columns_80_) ? GraphicsMode::DoubleHighRes : GraphicsMode::HighRes;
|
||||||
} else {
|
} else {
|
||||||
return annunciator_3_ ? GraphicsMode::DoubleLowRes : GraphicsMode::LowRes;
|
if(columns_80_) return GraphicsMode::DoubleLowRes;
|
||||||
|
if(annunciator_3_) return GraphicsMode::FatLowRes;
|
||||||
|
return GraphicsMode::LowRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user