From 83f6d1cda35f2d637dd80560a2b061516ce0bc22 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 2 Feb 2023 21:16:24 -0500 Subject: [PATCH] Prepare for source/destination operations. --- Components/9918/Implementation/9918Base.hpp | 37 ++++++++++--------- .../9918/Implementation/YamahaCommands.hpp | 33 +++++++---------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 55b6ba76b..410262b82 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -629,32 +629,32 @@ template struct Base: public Storage { return ScreenMode::Blank; } - AddressT command_address() const { + AddressT command_address(Vector location) const { if constexpr (is_yamaha_vdp(personality)) { switch(this->screen_mode_) { default: case ScreenMode::YamahaGraphics4: // 256 pixels @ 4bpp return AddressT( - (Storage::command_->location.v[0] >> 1) + - (Storage::command_->location.v[1] << 7) + (location.v[0] >> 1) + + (location.v[1] << 7) ); case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp return AddressT( - (Storage::command_->location.v[0] >> 2) + - (Storage::command_->location.v[1] << 7) + (location.v[0] >> 2) + + (location.v[1] << 7) ); case ScreenMode::YamahaGraphics6: // 512 pixels @ 4bpp return AddressT( - (Storage::command_->location.v[0] >> 1) + - (Storage::command_->location.v[1] << 8) + (location.v[0] >> 1) + + (location.v[1] << 8) ); case ScreenMode::YamahaGraphics7: // 256 pixels @ 8bpp return AddressT( - (Storage::command_->location.v[0] >> 0) + - (Storage::command_->location.v[1] << 8) + (location.v[0] >> 0) + + (location.v[1] << 8) ); } } else { @@ -662,7 +662,7 @@ template struct Base: public Storage { } } - std::pair command_colour_mask() const { + std::pair command_colour_mask(Vector location) const { if constexpr (is_yamaha_vdp(personality)) { switch(this->screen_mode_) { default: @@ -670,14 +670,14 @@ template struct Base: public Storage { case ScreenMode::YamahaGraphics6: // 512 pixels @ 4bpp return std::make_pair( - 0xf0 >> ((Storage::command_->location.v[0] & 1) << 2), + 0xf0 >> ((location.v[0] & 1) << 2), Storage::command_context_.colour4bpp ); case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp return std::make_pair( - 0xc0 >> ((Storage::command_->location.v[0] & 3) << 1), + 0xc0 >> ((location.v[0] & 3) << 1), Storage::command_context_.colour2bpp ); @@ -707,26 +707,27 @@ template struct Base: public Storage { return; } + auto &context = Storage::command_context_; switch(Storage::next_command_step_) { // Duplicative, but keeps the compiler happy. case CommandStep::None: break; case CommandStep::ReadPixel: - Storage::command_latch_ = ram_[command_address()]; + Storage::command_latch_ = ram_[command_address(context.destination)]; Storage::minimum_command_column_ = access_column + 24; Storage::next_command_step_ = CommandStep::WritePixel; break; case CommandStep::WritePixel: { - const auto [mask, unmasked_colour] = command_colour_mask(); - const auto address = command_address(); + const auto [mask, unmasked_colour] = command_colour_mask(context.destination); + const auto address = command_address(context.destination); const uint8_t colour = unmasked_colour & mask; using LogicalOperation = CommandContext::LogicalOperation; - if(!Storage::command_context_.test_source || colour) { - switch(Storage::command_context_.pixel_operation) { + if(!context.test_source || colour) { + switch(context.pixel_operation) { default: case LogicalOperation::Copy: Storage::command_latch_ &= ~mask; @@ -755,7 +756,7 @@ template struct Base: public Storage { } break; case CommandStep::WriteByte: - ram_[command_address()] = Storage::command_context_.colour; + ram_[command_address(context.destination)] = context.colour; Storage::command_->advance(pixels_per_byte(this->underlying_mode_)); Storage::update_command_step(access_column); break; diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index 3daa35f89..92a9cc12b 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -86,7 +86,6 @@ struct Command { AccessType access = AccessType::PlotPoint; int cycles = 0; bool is_cpu_transfer = false; - Vector location; /// Current command parameters. CommandContext &context; @@ -101,8 +100,11 @@ struct Command { virtual void advance(int pixels_per_byte) = 0; protected: - template void advance_axis(int offset = 1) { + template void advance_axis(int offset = 1) { context.destination.add(context.arguments & (0x4 << axis) ? -offset : offset); + if constexpr (include_source) { + context.source.add(context.arguments & (0x4 << axis) ? -offset : offset); + } } }; @@ -124,7 +126,6 @@ struct Line: public Command { // context.size.v[1] = short side dots; // context.arguments => direction - location = context.destination; position_ = context.size.v[1]; numerator_ = position_ << 1; denominator_ = context.size.v[0] << 1; @@ -150,9 +151,9 @@ struct Line: public Command { // b3: 1 => y direction is up; // 0 => y direction is down. if(context.arguments & 0x1) { - advance_axis<1>(); + advance_axis<1, false>(); } else { - advance_axis<0>(); + advance_axis<0, false>(); } position_ -= numerator_; @@ -161,13 +162,11 @@ struct Line: public Command { cycles += 32; if(context.arguments & 0x1) { - advance_axis<0>(); + advance_axis<0, false>(); } else { - advance_axis<1>(); + advance_axis<1, false>(); } } - - location = context.destination; } private: @@ -180,9 +179,8 @@ struct Line: public Command { struct PointSet: public Command { public: PointSet(CommandContext &context) : Command(context) { - cycles = 0; + cycles = 0; // TODO. access = AccessType::PlotPoint; - location = context.destination; } bool done() final { @@ -208,7 +206,6 @@ struct LogicalMoveFromCPU: public Command { // This command is started with the first colour ready to transfer. cycles = 32; access = AccessType::PlotPoint; - location = context.destination; } void advance(int) final { @@ -217,14 +214,13 @@ struct LogicalMoveFromCPU: public Command { case AccessType::WaitForColourReceipt: cycles = 32; - location = context.destination; access = AccessType::PlotPoint; break; case AccessType::PlotPoint: cycles = 0; access = AccessType::WaitForColourReceipt; - advance_axis<0>(); + advance_axis<0, false>(); --context.size.v[0]; if(!context.size.v[0]) { @@ -232,7 +228,7 @@ struct LogicalMoveFromCPU: public Command { context.size.v[0] = width_; context.destination.v[0] = start_x_; - advance_axis<1>(); + advance_axis<1, false>(); --context.size.v[1]; } break; @@ -254,7 +250,6 @@ struct HighSpeedFill: public Command { cycles = 56; access = AccessType::WriteByte; - location = context.destination; } bool done() final { @@ -264,7 +259,7 @@ struct HighSpeedFill: public Command { void advance(int pixels_per_byte) final { cycles = 48; - advance_axis<0>(pixels_per_byte); + advance_axis<0, false>(pixels_per_byte); context.size.v[0] -= pixels_per_byte; if(!(context.size.v[0] & ~(pixels_per_byte - 1))) { @@ -272,11 +267,9 @@ struct HighSpeedFill: public Command { context.size.v[0] = width_; context.destination.v[0] = start_x_; - advance_axis<1>(); + advance_axis<1, false>(); --context.size.v[1]; } - - location = context.destination; } private: