diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 10943ef5f..8466e66ce 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -916,25 +916,26 @@ void Base::commit_register(int reg, uint8_t value) { } #define Begin(x) Storage::command_ = std::make_unique(Storage::command_context_); + using MoveType = Commands::MoveType; switch(value >> 4) { // All codes not listed below are invalid; treat them as STOP. default: case 0b0000: Storage::command_ = nullptr; break; // STOP. case 0b0100: break; // TODO: point. [read a pixel colour] - case 0b0101: Begin(PointSet); break; // PSET [plot a pixel]. + case 0b0101: Begin(PointSet); break; // PSET [plot a pixel]. case 0b0110: break; // TODO: srch. [search horizontally for a colour] - case 0b0111: Begin(Line); break; // LINE [draw a Bresenham line]. + case 0b0111: Begin(Line); break; // LINE [draw a Bresenham line]. - case 0b1000: Begin(LogicalFill); break; // LMMV [logical move, VDP to VRAM, i.e. solid-colour fill]. - case 0b1001: Begin(LogicalMove); break; // LMMM [logical move, VRAM to VRAM]. + case 0b1000: Begin(LogicalFill); break; // LMMV [logical move, VDP to VRAM, i.e. solid-colour fill]. + case 0b1001: Begin(Move); break; // LMMM [logical move, VRAM to VRAM]. case 0b1010: break; // TODO: lmcm. [logical move, VRAM to CPU] - case 0b1011: Begin(MoveFromCPU); break; // LMMC [logical move, CPU to VRAM]. + case 0b1011: Begin(MoveFromCPU); break; // LMMC [logical move, CPU to VRAM]. - case 0b1100: Begin(HighSpeedFill); break; // HMMV [high-speed move, VDP to VRAM, i.e. single-byte fill]. - case 0b1101: Begin(HighSpeedMove); break; // HMMM [high-speed move, VRAM to VRAM]. + case 0b1100: Begin(HighSpeedFill); break; // HMMV [high-speed move, VDP to VRAM, i.e. single-byte fill]. + case 0b1101: Begin(Move); break; // HMMM [high-speed move, VRAM to VRAM]. case 0b1110: break; // TODO: ymmm. [high-speed move, y only, VRAM to VRAM] - case 0b1111: Begin(MoveFromCPU); break; // HMMC [high-speed move, CPU to VRAM]. + case 0b1111: Begin(MoveFromCPU); break; // HMMC [high-speed move, CPU to VRAM]. } #undef Begin diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index b09ca19f0..b684bb27a 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -328,30 +328,26 @@ template struct MoveFromCPU: public Rectangle { // MARK: - Rectangular moves within VRAM. -struct HighSpeedMove: public Rectangle { - HighSpeedMove(CommandContext &context) : Rectangle(context) { - access = AccessType::CopyByte; - cycles = 64; - } - - void advance(int pixels_per_byte) final { - cycles = 64; - if(advance_pixel(pixels_per_byte)) { - cycles += 64; - } - } +enum class MoveType { + Logical, + HighSpeed, + YOnly, }; -struct LogicalMove: public Rectangle { - LogicalMove(CommandContext &context) : Rectangle(context) { - access = AccessType::CopyPoint; - cycles = 64; +template struct Move: public Rectangle { + static constexpr bool is_logical = type == MoveType::Logical; + static constexpr bool is_y_only = type == MoveType::YOnly; + using Rectangle = Rectangle; + + Move(CommandContext &context) : Rectangle(context) { + Command::access = is_logical ? Command::AccessType::CopyPoint : Command::AccessType::CopyByte; + Command::cycles = is_y_only ? 0 : 64; } void advance(int pixels_per_byte) final { - cycles = 64; - if(advance_pixel(pixels_per_byte)) { - cycles += 64; + Command::cycles = is_y_only ? 40 : 64; + if(Rectangle::advance_pixel(pixels_per_byte)) { + Command::cycles += is_y_only ? 0 : 64; } } };