From e66a92d6cb8be89201d14d5307668e4f50c62a80 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 18 Mar 2023 23:07:33 -0400 Subject: [PATCH] Fill in and use some parts of mode description. --- Components/9918/Implementation/9918.cpp | 9 +++++- Components/9918/Implementation/9918Base.hpp | 6 ++-- .../9918/Implementation/AccessEnums.hpp | 23 ++++++++++++++ .../9918/Implementation/YamahaCommands.hpp | 31 +++++++++---------- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 3027ff900..51570447a 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -346,6 +346,13 @@ void TMS9918::run_for(const HalfCycles cycles) { this->screen_mode_ = this->template current_screen_mode(); this->underlying_mode_ = this->template current_screen_mode(); + if constexpr (is_yamaha_vdp(personality)) { + auto &desc = Storage::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::FirstPixelCycle; next_line_buffer.next_border_column = Timing::CyclesPerLine; @@ -903,7 +910,7 @@ void Base::commit_register(int reg, uint8_t value) { Storage::command_ && Storage::command_->access == Command::AccessType::WaitForColourReceipt ) { - Storage::command_->advance(pixels_per_byte(this->underlying_mode_)); + Storage::command_->advance(); Storage::update_command_step(fetch_pointer_.column); } break; diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index a0b95316f..b011c6a4c 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -391,7 +391,7 @@ template struct Base: public Storage { case CommandStep::CopySourcePixelToStatus: Storage::colour_status_ = extract_colour(source[command_address(context.source, context.arguments & 0x10)], context.source); - Storage::command_->advance(pixels_per_byte(this->underlying_mode_)); + Storage::command_->advance(); Storage::update_command_step(access_column); break; @@ -441,7 +441,7 @@ template struct Base: public Storage { destination[address] = Storage::command_latch_; - Storage::command_->advance(pixels_per_byte(this->underlying_mode_)); + Storage::command_->advance(); Storage::update_command_step(access_column); } break; @@ -460,7 +460,7 @@ template struct Base: public Storage { 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::command_->advance(pixels_per_byte(this->underlying_mode_)); + Storage::command_->advance(); Storage::update_command_step(access_column); break; } diff --git a/Components/9918/Implementation/AccessEnums.hpp b/Components/9918/Implementation/AccessEnums.hpp index 7261e21b4..d5e581b7f 100644 --- a/Components/9918/Implementation/AccessEnums.hpp +++ b/Components/9918/Implementation/AccessEnums.hpp @@ -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, diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index 3037f247b..032fb840b 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -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 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 struct Point: public Command { return done_; } - void advance(int) final { + void advance() final { done_ = true; } @@ -261,10 +261,7 @@ template 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 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 struct MoveFromCPU: public Rectangle { 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 struct MoveFromCPU: public Rectangle { case Command::AccessType::PlotPoint: Command::cycles = 0; Command::access = Command::AccessType::WaitForColourReceipt; - if(Rectangle::advance_pixel(pixels_per_byte)) { + if(Rectangle::advance_pixel()) { Command::cycles = 64; // TODO: I'm not sure this will be honoured per the outer wrapping. } @@ -353,9 +350,9 @@ template struct Move: public Rectangle { 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 { access = AccessType::PlotPoint; } - void advance(int) final { + void advance() final { cycles = 72; if(advance_pixel()) { cycles += 64;