mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Prepare for source/destination operations.
This commit is contained in:
parent
6d315b4660
commit
83f6d1cda3
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user