mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Implements the Command
side of the line command.
This commit is contained in:
parent
1c6a0ad3f7
commit
baa6f9b3cd
@ -46,11 +46,14 @@ struct Command {
|
|||||||
// This command is blocked until @c access has been performed, reading
|
// This command is blocked until @c access has been performed, reading
|
||||||
// from or writing to @c value. It should not be performed until at least
|
// from or writing to @c value. It should not be performed until at least
|
||||||
// @c cycles have passed.
|
// @c cycles have passed.
|
||||||
MemoryAccess access = MemoryAccess::None;
|
enum class AccessType {
|
||||||
|
/// Plots a single pixel of the current contextual colour at @c location,
|
||||||
|
/// which occurs as a read, then a 24-cycle pause, then a write.
|
||||||
|
PlotPoint
|
||||||
|
};
|
||||||
|
AccessType access = AccessType::PlotPoint;
|
||||||
int cycles = 0;
|
int cycles = 0;
|
||||||
uint8_t value = 0;
|
Vector location;
|
||||||
|
|
||||||
// TODO: how best to describe access destination? Probably as (x, y) and logical/fast?
|
|
||||||
|
|
||||||
/// Current command parameters.
|
/// Current command parameters.
|
||||||
CommandContext &context;
|
CommandContext &context;
|
||||||
@ -67,21 +70,59 @@ struct Command {
|
|||||||
|
|
||||||
namespace Commands {
|
namespace Commands {
|
||||||
|
|
||||||
|
/// Implements the line command, which is plain-old Bresenham.
|
||||||
|
///
|
||||||
|
/// Per Grauw timing is:
|
||||||
|
///
|
||||||
|
/// * 88 cycles between every pixel plot;
|
||||||
|
/// * 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) : Command(context) {
|
||||||
// Set up Bresenham constants.
|
// Set up Bresenham constants.
|
||||||
|
if(abs(context.size.v[0]) > abs(context.size.v[1])) {
|
||||||
|
major_.v[0] = context.size.v[0] < 0 ? -1 : 1;
|
||||||
|
minor_.v[1] = context.size.v[1] < 0 ? -1 : 1;
|
||||||
|
major_.v[1] = minor_.v[0] = 0;
|
||||||
|
|
||||||
|
position_ = abs(context.size.v[1]);
|
||||||
|
duration_ = abs(context.size.v[0]);
|
||||||
|
} else {
|
||||||
|
major_.v[1] = context.size.v[1] < 0 ? -1 : 1;
|
||||||
|
minor_.v[0] = context.size.v[0] < 0 ? -1 : 1;
|
||||||
|
major_.v[0] = minor_.v[1] = 0;
|
||||||
|
|
||||||
|
position_ = abs(context.size.v[0]);
|
||||||
|
duration_ = abs(context.size.v[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
numerator_ = position_ << 1;
|
||||||
|
denominator_ = duration_ << 1;
|
||||||
|
|
||||||
|
cycles = 0;
|
||||||
|
access = AccessType::PlotPoint;
|
||||||
|
location = context.destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool next() {
|
bool next() {
|
||||||
// Should implement Bresenham with cadence:
|
if(!duration_) return false;
|
||||||
//
|
|
||||||
// 88 cycles before the next read; 24 to write.
|
--duration_;
|
||||||
// Add 32 extra cycles if a minor-axis step occurs.
|
cycles = 88;
|
||||||
return false;
|
location += major_;
|
||||||
|
position_ -= numerator_;
|
||||||
|
if(position_ < 0) {
|
||||||
|
cycles += 32;
|
||||||
|
location += minor_;
|
||||||
|
position_ += denominator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int position_, numerator_, denominator_, duration_;
|
||||||
|
Vector major_, minor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user