1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-27 02:55:07 +00:00

Fill in and use some parts of mode description.

This commit is contained in:
Thomas Harte 2023-03-18 23:07:33 -04:00
parent a6251f436a
commit e66a92d6cb
4 changed files with 48 additions and 21 deletions

View File

@ -346,6 +346,13 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
this->screen_mode_ = this->template current_screen_mode<true>();
this->underlying_mode_ = this->template current_screen_mode<false>();
if constexpr (is_yamaha_vdp(personality)) {
auto &desc = Storage<personality>::mode_description_;
desc.pixels_per_byte = pixels_per_byte(this->underlying_mode_);
desc.width = width(this->underlying_mode_);
desc.rotate_address = interleaves_banks(this->underlying_mode_);
}
// Based on the output mode, pick a line mode.
next_line_buffer.first_pixel_output_column = Timing<personality>::FirstPixelCycle;
next_line_buffer.next_border_column = Timing<personality>::CyclesPerLine;
@ -903,7 +910,7 @@ void Base<personality>::commit_register(int reg, uint8_t value) {
Storage<personality>::command_ &&
Storage<personality>::command_->access == Command::AccessType::WaitForColourReceipt
) {
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
Storage<personality>::command_->advance();
Storage<personality>::update_command_step(fetch_pointer_.column);
}
break;

View File

@ -391,7 +391,7 @@ template <Personality personality> struct Base: public Storage<personality> {
case CommandStep::CopySourcePixelToStatus:
Storage<personality>::colour_status_ = extract_colour(source[command_address(context.source, context.arguments & 0x10)], context.source);
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
Storage<personality>::command_->advance();
Storage<personality>::update_command_step(access_column);
break;
@ -441,7 +441,7 @@ template <Personality personality> struct Base: public Storage<personality> {
destination[address] = Storage<personality>::command_latch_;
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
Storage<personality>::command_->advance();
Storage<personality>::update_command_step(access_column);
} break;
@ -460,7 +460,7 @@ template <Personality personality> struct Base: public Storage<personality> {
destination[command_address(context.destination, context.arguments & 0x20)] = context.latched_colour.has_value() ? context.latched_colour.colour : context.colour.colour;
context.latched_colour.reset();
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
Storage<personality>::command_->advance();
Storage<personality>::update_command_step(access_column);
break;
}

View File

@ -57,6 +57,29 @@ constexpr int pixels_per_byte(ScreenMode mode) {
}
}
constexpr int width(ScreenMode mode) {
switch(mode) {
default:
case ScreenMode::Blank: return 0;
case ScreenMode::Text: return 240;
case ScreenMode::MultiColour: return 256;
case ScreenMode::ColouredText: return 256;
case ScreenMode::Graphics: return 256;
case ScreenMode::SMSMode4: return 256;
case ScreenMode::YamahaText80: return 480;
case ScreenMode::YamahaGraphics3: return 256;
case ScreenMode::YamahaGraphics4: return 256;
case ScreenMode::YamahaGraphics5: return 512;
case ScreenMode::YamahaGraphics6: return 512;
case ScreenMode::YamahaGraphics7: return 256;
}
}
constexpr bool interleaves_banks(ScreenMode mode) {
return mode == ScreenMode::YamahaGraphics6 || mode == ScreenMode::YamahaGraphics7;
}
enum class FetchMode {
Text,
Character,

View File

@ -139,7 +139,7 @@ struct Command {
/// Repopulates the fields above with the next action to take, being provided with the
/// number of pixels per byte in the current screen mode.
virtual void advance(int pixels_per_byte) = 0;
virtual void advance() = 0;
protected:
template <int axis, bool include_source> void advance_axis(int offset = 1) {
@ -180,7 +180,7 @@ struct Line: public Command {
return !context.size.v[0];
}
void advance(int) final {
void advance() final {
--context.size.v[0];
cycles = 88;
@ -231,7 +231,7 @@ template <bool is_read> struct Point: public Command {
return done_;
}
void advance(int) final {
void advance() final {
done_ = true;
}
@ -261,10 +261,7 @@ template <bool logical, bool include_source> struct Rectangle: public Command {
/// Advances the current destination and, if @c include_source is @c true also the source;
/// @returns @c true if a new row was started; @c false otherwise.
///
/// @c pixels_per_byte is used for 'fast' (i.e. not logical) rectangles only, setting pace at
/// which the source and destination proceed left-to-right.
bool advance_pixel(int pixels_per_byte = 0) {
bool advance_pixel() {
if constexpr (logical) {
advance_axis<0, include_source>();
--context.size.v[0];
@ -273,10 +270,10 @@ template <bool logical, bool include_source> struct Rectangle: public Command {
return false;
}
} else {
advance_axis<0, include_source>(pixels_per_byte);
context.size.v[0] -= pixels_per_byte;
advance_axis<0, include_source>(mode_description.pixels_per_byte);
context.size.v[0] -= mode_description.pixels_per_byte;
if(context.size.v[0] & ~(pixels_per_byte - 1)) {
if(context.size.v[0] & ~(mode_description.pixels_per_byte - 1)) {
return false;
}
}
@ -312,7 +309,7 @@ template <bool logical> struct MoveFromCPU: public Rectangle<logical, false> {
Command::access = logical ? Command::AccessType::PlotPoint : Command::AccessType::WriteByte;
}
void advance(int pixels_per_byte) final {
void advance() final {
switch(Command::access) {
default: break;
@ -325,7 +322,7 @@ template <bool logical> struct MoveFromCPU: public Rectangle<logical, false> {
case Command::AccessType::PlotPoint:
Command::cycles = 0;
Command::access = Command::AccessType::WaitForColourReceipt;
if(Rectangle<logical, false>::advance_pixel(pixels_per_byte)) {
if(Rectangle<logical, false>::advance_pixel()) {
Command::cycles = 64;
// TODO: I'm not sure this will be honoured per the outer wrapping.
}
@ -353,9 +350,9 @@ template <MoveType type> struct Move: public Rectangle<type == MoveType::Logical
Command::y_only = is_y_only;
}
void advance(int pixels_per_byte) final {
void advance() final {
Command::cycles = is_y_only ? 40 : 64;
if(RectangleBase::advance_pixel(pixels_per_byte)) {
if(RectangleBase::advance_pixel()) {
Command::cycles += is_y_only ? 0 : 64;
}
}
@ -369,9 +366,9 @@ struct HighSpeedFill: public Rectangle<false, false> {
access = AccessType::WriteByte;
}
void advance(int pixels_per_byte) final {
void advance() final {
cycles = 48;
if(advance_pixel(pixels_per_byte)) {
if(advance_pixel()) {
cycles += 56;
}
}
@ -383,7 +380,7 @@ struct LogicalFill: public Rectangle<false, false> {
access = AccessType::PlotPoint;
}
void advance(int) final {
void advance() final {
cycles = 72;
if(advance_pixel()) {
cycles += 64;