1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Prepare for source/destination operations.

This commit is contained in:
Thomas Harte 2023-02-02 21:16:24 -05:00
parent 6d315b4660
commit 83f6d1cda3
2 changed files with 32 additions and 38 deletions

View File

@ -629,32 +629,32 @@ template <Personality personality> struct Base: public Storage<personality> {
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<personality>::command_->location.v[0] >> 1) +
(Storage<personality>::command_->location.v[1] << 7)
(location.v[0] >> 1) +
(location.v[1] << 7)
);
case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp
return AddressT(
(Storage<personality>::command_->location.v[0] >> 2) +
(Storage<personality>::command_->location.v[1] << 7)
(location.v[0] >> 2) +
(location.v[1] << 7)
);
case ScreenMode::YamahaGraphics6: // 512 pixels @ 4bpp
return AddressT(
(Storage<personality>::command_->location.v[0] >> 1) +
(Storage<personality>::command_->location.v[1] << 8)
(location.v[0] >> 1) +
(location.v[1] << 8)
);
case ScreenMode::YamahaGraphics7: // 256 pixels @ 8bpp
return AddressT(
(Storage<personality>::command_->location.v[0] >> 0) +
(Storage<personality>::command_->location.v[1] << 8)
(location.v[0] >> 0) +
(location.v[1] << 8)
);
}
} else {
@ -662,7 +662,7 @@ template <Personality personality> struct Base: public Storage<personality> {
}
}
std::pair<uint8_t, uint8_t> command_colour_mask() const {
std::pair<uint8_t, uint8_t> command_colour_mask(Vector location) const {
if constexpr (is_yamaha_vdp(personality)) {
switch(this->screen_mode_) {
default:
@ -670,14 +670,14 @@ template <Personality personality> struct Base: public Storage<personality> {
case ScreenMode::YamahaGraphics6: // 512 pixels @ 4bpp
return
std::make_pair(
0xf0 >> ((Storage<personality>::command_->location.v[0] & 1) << 2),
0xf0 >> ((location.v[0] & 1) << 2),
Storage<personality>::command_context_.colour4bpp
);
case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp
return
std::make_pair(
0xc0 >> ((Storage<personality>::command_->location.v[0] & 3) << 1),
0xc0 >> ((location.v[0] & 3) << 1),
Storage<personality>::command_context_.colour2bpp
);
@ -707,26 +707,27 @@ template <Personality personality> struct Base: public Storage<personality> {
return;
}
auto &context = Storage<personality>::command_context_;
switch(Storage<personality>::next_command_step_) {
// Duplicative, but keeps the compiler happy.
case CommandStep::None:
break;
case CommandStep::ReadPixel:
Storage<personality>::command_latch_ = ram_[command_address()];
Storage<personality>::command_latch_ = ram_[command_address(context.destination)];
Storage<personality>::minimum_command_column_ = access_column + 24;
Storage<personality>::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<personality>::command_context_.test_source || colour) {
switch(Storage<personality>::command_context_.pixel_operation) {
if(!context.test_source || colour) {
switch(context.pixel_operation) {
default:
case LogicalOperation::Copy:
Storage<personality>::command_latch_ &= ~mask;
@ -755,7 +756,7 @@ template <Personality personality> struct Base: public Storage<personality> {
} break;
case CommandStep::WriteByte:
ram_[command_address()] = Storage<personality>::command_context_.colour;
ram_[command_address(context.destination)] = context.colour;
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
Storage<personality>::update_command_step(access_column);
break;

View File

@ -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 <int axis> void advance_axis(int offset = 1) {
template <int axis, bool include_source> void advance_axis(int offset = 1) {
context.destination.add<axis>(context.arguments & (0x4 << axis) ? -offset : offset);
if constexpr (include_source) {
context.source.add<axis>(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: