1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 00:29:34 +00:00

Complete ReadSourcePixel & ReadSourceByte paths.

This commit is contained in:
Thomas Harte 2023-02-04 21:23:41 -05:00
parent a2786e6266
commit c6372295c5
2 changed files with 29 additions and 11 deletions

View File

@ -674,8 +674,26 @@ template <Personality personality> struct Base: public Storage<personality> {
} }
} }
uint8_t extract_colour(uint8_t byte, Vector location) const {
switch(this->screen_mode_) {
default:
case ScreenMode::YamahaGraphics4: // 256 pixels @ 4bpp
case ScreenMode::YamahaGraphics6: // 512 pixels @ 4bpp
return (byte >> (((location.v[0] & 1) ^ 1) << 2)) & 0xf;
case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp
return (byte >> (((location.v[0] & 3) ^ 3) << 1)) & 0x3;
case ScreenMode::YamahaGraphics7: // 256 pixels @ 8bpp
return byte;
}
}
std::pair<uint8_t, uint8_t> command_colour_mask(Vector location) const { std::pair<uint8_t, uint8_t> command_colour_mask(Vector location) const {
if constexpr (is_yamaha_vdp(personality)) { if constexpr (is_yamaha_vdp(personality)) {
auto &context = Storage<personality>::command_context_;
auto colour = context.latched_colour.has_value() ? context.latched_colour : context.colour;
switch(this->screen_mode_) { switch(this->screen_mode_) {
default: default:
case ScreenMode::YamahaGraphics4: // 256 pixels @ 4bpp case ScreenMode::YamahaGraphics4: // 256 pixels @ 4bpp
@ -683,21 +701,21 @@ template <Personality personality> struct Base: public Storage<personality> {
return return
std::make_pair( std::make_pair(
0xf0 >> ((location.v[0] & 1) << 2), 0xf0 >> ((location.v[0] & 1) << 2),
Storage<personality>::command_context_.colour.colour4bpp colour.colour4bpp
); );
case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp
return return
std::make_pair( std::make_pair(
0xc0 >> ((location.v[0] & 3) << 1), 0xc0 >> ((location.v[0] & 3) << 1),
Storage<personality>::command_context_.colour.colour2bpp colour.colour2bpp
); );
case ScreenMode::YamahaGraphics7: // 256 pixels @ 8bpp case ScreenMode::YamahaGraphics7: // 256 pixels @ 8bpp
return return
std::make_pair( std::make_pair(
0xff, 0xff,
Storage<personality>::command_context_.colour.colour colour.colour
); );
} }
} else { } else {
@ -726,10 +744,7 @@ template <Personality personality> struct Base: public Storage<personality> {
break; break;
case CommandStep::ReadSourcePixel: case CommandStep::ReadSourcePixel:
// TODO: the read as below, but to an appropriate piece of temporary colour context.latched_colour.set(extract_colour(ram_[command_address(context.source)], context.source));
// storage; per the manual the colour register is unchanged, so I can't just
// put it there.
// Storage<personality>::command_latch_ = ram_[command_address(context.source)];
Storage<personality>::minimum_command_column_ = access_column + 32; Storage<personality>::minimum_command_column_ = access_column + 32;
Storage<personality>::next_command_step_ = CommandStep::ReadDestinationPixel; Storage<personality>::next_command_step_ = CommandStep::ReadDestinationPixel;
@ -746,6 +761,7 @@ template <Personality personality> struct Base: public Storage<personality> {
const auto [mask, unmasked_colour] = command_colour_mask(context.destination); const auto [mask, unmasked_colour] = command_colour_mask(context.destination);
const auto address = command_address(context.destination); const auto address = command_address(context.destination);
const uint8_t colour = unmasked_colour & mask; const uint8_t colour = unmasked_colour & mask;
context.latched_colour.reset();
using LogicalOperation = CommandContext::LogicalOperation; using LogicalOperation = CommandContext::LogicalOperation;
if(!context.test_source || colour) { if(!context.test_source || colour) {
@ -778,15 +794,16 @@ template <Personality personality> struct Base: public Storage<personality> {
} break; } break;
case CommandStep::ReadSourceByte: case CommandStep::ReadSourceByte:
// TODO: the read as below, and store somewhere for future write. context.latched_colour.set(ram_[command_address(context.source)]);
// Storage<personality>::command_latch_ = ram_[command_address(context.source)];
Storage<personality>::minimum_command_column_ = access_column + 24; Storage<personality>::minimum_command_column_ = access_column + 24;
Storage<personality>::next_command_step_ = CommandStep::WriteByte; Storage<personality>::next_command_step_ = CommandStep::WriteByte;
break; break;
case CommandStep::WriteByte: case CommandStep::WriteByte:
ram_[command_address(context.destination)] = context.colour.colour; ram_[command_address(context.destination)] = context.latched_colour.has_value() ? context.latched_colour.colour : context.colour.colour;
context.latched_colour.reset();
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_)); Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
Storage<personality>::update_command_step(access_column); Storage<personality>::update_command_step(access_column);
break; break;

View File

@ -54,7 +54,7 @@ struct Colour {
colour4bpp = 0xff; colour4bpp = 0xff;
} }
bool has_value() { bool has_value() const {
return (colour & 0x3) == (colour4bpp & 0x3); return (colour & 0x3) == (colour4bpp & 0x3);
} }
@ -73,6 +73,7 @@ struct CommandContext {
uint8_t arguments = 0; uint8_t arguments = 0;
Colour colour; Colour colour;
Colour latched_colour;
enum class LogicalOperation { enum class LogicalOperation {
Copy = 0b0000, Copy = 0b0000,