1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-11 08:30:55 +00:00

Provide commands with [unpopulated] mode parameters.

This commit is contained in:
Thomas Harte 2023-03-18 13:39:47 -04:00
parent 6d49b2e66b
commit a6251f436a
3 changed files with 17 additions and 9 deletions

View File

@ -928,7 +928,7 @@ void Base<personality>::commit_register(int reg, uint8_t value) {
break; break;
} }
#define Begin(x) Storage<personality>::command_ = std::make_unique<Commands::x>(Storage<personality>::command_context_); #define Begin(x) Storage<personality>::command_ = std::make_unique<Commands::x>(Storage<personality>::command_context_, Storage<personality>::mode_description_);
using MoveType = Commands::MoveType; using MoveType = Commands::MoveType;
switch(value >> 4) { switch(value >> 4) {
// All codes not listed below are invalid; treat them as STOP. // All codes not listed below are invalid; treat them as STOP.

View File

@ -134,6 +134,7 @@ template <Personality personality> struct Storage<personality, std::enable_if_t<
// Command engine state. // Command engine state.
CommandContext command_context_; CommandContext command_context_;
ModeDescription mode_description_;
std::unique_ptr<Command> command_ = nullptr; std::unique_ptr<Command> command_ = nullptr;
enum class CommandStep { enum class CommandStep {

View File

@ -86,6 +86,12 @@ struct CommandContext {
bool test_source; bool test_source;
}; };
struct ModeDescription {
int width = 256;
int pixels_per_byte = 4;
bool rotate_address = false;
};
struct Command { struct Command {
// In net: // In net:
// //
@ -124,7 +130,8 @@ struct Command {
/// Current command parameters. /// Current command parameters.
CommandContext &context; CommandContext &context;
Command(CommandContext &context) : context(context) {} ModeDescription &mode_description;
Command(CommandContext &context, ModeDescription &mode_description) : context(context), mode_description(mode_description) {}
virtual ~Command() {} virtual ~Command() {}
/// @returns @c true if all output from this command is done; @c false otherwise. /// @returns @c true if all output from this command is done; @c false otherwise.
@ -155,7 +162,7 @@ namespace Commands {
/// * plus an additional 32 cycles if a step along the minor axis is taken. /// * plus an additional 32 cycles if a step along the minor axis is taken.
struct Line: public Command { struct Line: public Command {
public: public:
Line(CommandContext &context) : Command(context) { Line(CommandContext &context, ModeDescription &mode_description) : Command(context, mode_description) {
// context.destination = start position; // context.destination = start position;
// context.size.v[0] = long side dots; // context.size.v[0] = long side dots;
// context.size.v[1] = short side dots; // context.size.v[1] = short side dots;
@ -215,7 +222,7 @@ struct Line: public Command {
/// No timings are documented, so this'll output or input as quickly as possible. /// No timings are documented, so this'll output or input as quickly as possible.
template <bool is_read> struct Point: public Command { template <bool is_read> struct Point: public Command {
public: public:
Point(CommandContext &context) : Command(context) { Point(CommandContext &context, ModeDescription &mode_description) : Command(context, mode_description) {
cycles = 0; // TODO. cycles = 0; // TODO.
access = is_read ? AccessType::ReadPoint : AccessType::PlotPoint; access = is_read ? AccessType::ReadPoint : AccessType::PlotPoint;
} }
@ -237,7 +244,7 @@ template <bool is_read> struct Point: public Command {
/// Useful base class for anything that does logical work in a rectangle. /// Useful base class for anything that does logical work in a rectangle.
template <bool logical, bool include_source> struct Rectangle: public Command { template <bool logical, bool include_source> struct Rectangle: public Command {
public: public:
Rectangle(CommandContext &context) : Command(context) { Rectangle(CommandContext &context, ModeDescription &mode_description) : Command(context, mode_description) {
if constexpr (include_source) { if constexpr (include_source) {
start_x_[0] = context.source.v[0]; start_x_[0] = context.source.v[0];
} }
@ -297,7 +304,7 @@ template <bool logical, bool include_source> struct Rectangle: public Command {
// MARK: - Rectangular moves to/from CPU. // MARK: - Rectangular moves to/from CPU.
template <bool logical> struct MoveFromCPU: public Rectangle<logical, false> { template <bool logical> struct MoveFromCPU: public Rectangle<logical, false> {
MoveFromCPU(CommandContext &context) : Rectangle<logical, false>(context) { MoveFromCPU(CommandContext &context, ModeDescription &mode_description) : Rectangle<logical, false>(context, mode_description) {
Command::is_cpu_transfer = true; Command::is_cpu_transfer = true;
// This command is started with the first colour ready to transfer. // This command is started with the first colour ready to transfer.
@ -340,7 +347,7 @@ template <MoveType type> struct Move: public Rectangle<type == MoveType::Logical
static constexpr bool is_y_only = type == MoveType::YOnly; static constexpr bool is_y_only = type == MoveType::YOnly;
using RectangleBase = Rectangle<is_logical, true>; using RectangleBase = Rectangle<is_logical, true>;
Move(CommandContext &context) : RectangleBase(context) { Move(CommandContext &context, ModeDescription &mode_description) : RectangleBase(context, mode_description) {
Command::access = is_logical ? Command::AccessType::CopyPoint : Command::AccessType::CopyByte; Command::access = is_logical ? Command::AccessType::CopyPoint : Command::AccessType::CopyByte;
Command::cycles = is_y_only ? 0 : 64; Command::cycles = is_y_only ? 0 : 64;
Command::y_only = is_y_only; Command::y_only = is_y_only;
@ -357,7 +364,7 @@ template <MoveType type> struct Move: public Rectangle<type == MoveType::Logical
// MARK: - Rectangular fills. // MARK: - Rectangular fills.
struct HighSpeedFill: public Rectangle<false, false> { struct HighSpeedFill: public Rectangle<false, false> {
HighSpeedFill(CommandContext &context) : Rectangle(context) { HighSpeedFill(CommandContext &context, ModeDescription &mode_description) : Rectangle(context, mode_description) {
cycles = 56; cycles = 56;
access = AccessType::WriteByte; access = AccessType::WriteByte;
} }
@ -371,7 +378,7 @@ struct HighSpeedFill: public Rectangle<false, false> {
}; };
struct LogicalFill: public Rectangle<false, false> { struct LogicalFill: public Rectangle<false, false> {
LogicalFill(CommandContext &context) : Rectangle(context) { LogicalFill(CommandContext &context, ModeDescription &mode_description) : Rectangle(context, mode_description) {
cycles = 64; cycles = 64;
access = AccessType::PlotPoint; access = AccessType::PlotPoint;
} }