1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Provide context for byte-by-byte commands.

This commit is contained in:
Thomas Harte 2023-01-31 21:29:55 -05:00
parent c5c722ae56
commit a315384e30
4 changed files with 44 additions and 14 deletions

View File

@ -871,7 +871,7 @@ void Base<personality>::commit_register(int reg, uint8_t value) {
Storage<personality>::command_ &&
Storage<personality>::command_->access == Command::AccessType::WaitForColourReceipt
) {
Storage<personality>::command_->advance();
Storage<personality>::command_->advance(pixels_per_byte(this->screen_mode_));
Storage<personality>::update_command_step(fetch_pointer_.column);
}
break;

View File

@ -365,8 +365,6 @@ template <Personality personality> struct Storage<personality, std::enable_if_t<
uint32_t colour_ram_[32];
bool cram_is_selected_ = false;
// Fields below affect only the Master System output mode.
// Programmer-set flags.
bool vertical_scroll_lock_ = false;
bool horizontal_scroll_lock_ = false;
@ -707,13 +705,13 @@ template <Personality personality> struct Base: public Storage<personality> {
ram_[address] = Storage<personality>::command_latch_;
Storage<personality>::command_->advance();
Storage<personality>::command_->advance(pixels_per_byte(this->screen_mode_));
Storage<personality>::update_command_step(access_column);
} break;
case CommandStep::WriteByte:
ram_[command_address()] = Storage<personality>::command_context_.colour;
Storage<personality>::command_->advance();
Storage<personality>::command_->advance(pixels_per_byte(this->screen_mode_));
Storage<personality>::update_command_step(access_column);
break;
}

View File

@ -39,6 +39,23 @@ enum class ScreenMode {
YamahaGraphics2 = Graphics,
};
constexpr int pixels_per_byte(ScreenMode mode) {
switch(mode) {
case ScreenMode::Blank: return 0;
case ScreenMode::Text: return 6;
case ScreenMode::MultiColour: return 2;
case ScreenMode::ColouredText: return 8;
case ScreenMode::Graphics: return 8;
case ScreenMode::SMSMode4: return 2;
case ScreenMode::YamahaText80: return 6;
case ScreenMode::YamahaGraphics3: return 8;
case ScreenMode::YamahaGraphics4: return 2;
case ScreenMode::YamahaGraphics5: return 4;
case ScreenMode::YamahaGraphics6: return 2;
case ScreenMode::YamahaGraphics7: return 1;
}
}
enum class FetchMode {
Text,
Character,

View File

@ -95,14 +95,14 @@ struct Command {
/// @returns @c true if all output from this command is done; @c false otherwise.
virtual bool done() = 0;
/// Repopulates the fields above with the next action to take.
virtual void advance() = 0;
/// Repopulates the fields above with the next action to take, being provided with the
/// number of pixels per byte in the current screen mode.
virtual void advance(int pixels_per_byte) = 0;
protected:
template <int axis> void advance_axis() {
context.destination.add<axis>(context.arguments & (0x4 << axis) ? -1 : 1);
template <int axis> void advance_axis(int offset = 1) {
context.destination.add<axis>(context.arguments & (0x4 << axis) ? -offset : offset);
}
};
// MARK: - Line drawing.
@ -136,7 +136,7 @@ struct Line: public Command {
return !context.size.v[0];
}
void advance() final {
void advance(int) final {
--context.size.v[0];
cycles = 88;
@ -186,7 +186,7 @@ struct PointSet: public Command {
return done_;
}
void advance() final {
void advance(int) final {
done_ = true;
}
@ -208,7 +208,7 @@ struct LogicalMoveFromCPU: public Command {
location = context.destination;
}
void advance() final {
void advance(int) final {
switch(access) {
default: break;
@ -258,8 +258,23 @@ struct HighSpeedFill: public Command {
return true;
}
void advance() final {
void advance(int pixels_per_byte) final {
cycles = 48;
// TODO: step at byte speed, not pixel speed.
advance_axis<0>(pixels_per_byte);
--context.size.v[0];
if(!context.size.v[0]) {
cycles += 56;
context.size.v[0] = width_;
context.destination.v[0] = start_x_;
advance_axis<1>();
--context.size.v[1];
}
location = context.destination;
}
private: