1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-16 18:30:32 +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_ &&
Storage<personality>::command_->access == Command::AccessType::WaitForColourReceipt 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); Storage<personality>::update_command_step(fetch_pointer_.column);
} }
break; break;

View File

@ -365,8 +365,6 @@ template <Personality personality> struct Storage<personality, std::enable_if_t<
uint32_t colour_ram_[32]; uint32_t colour_ram_[32];
bool cram_is_selected_ = false; bool cram_is_selected_ = false;
// Fields below affect only the Master System output mode.
// Programmer-set flags. // Programmer-set flags.
bool vertical_scroll_lock_ = false; bool vertical_scroll_lock_ = false;
bool horizontal_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_; 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); Storage<personality>::update_command_step(access_column);
} break; } break;
case CommandStep::WriteByte: case CommandStep::WriteByte:
ram_[command_address()] = Storage<personality>::command_context_.colour; 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); Storage<personality>::update_command_step(access_column);
break; break;
} }

View File

@ -39,6 +39,23 @@ enum class ScreenMode {
YamahaGraphics2 = Graphics, 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 { enum class FetchMode {
Text, Text,
Character, Character,

View File

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