mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +00:00
Provide context for byte-by-byte commands.
This commit is contained in:
parent
c5c722ae56
commit
a315384e30
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user