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:
parent
6d49b2e66b
commit
a6251f436a
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user