diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index a6ebe6355..32b25ced1 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -843,20 +843,17 @@ void Base::commit_register(int reg, uint8_t value) { // b0–b3: LO0–LO3 (???) // b4–b7: CM0-CM3 (???) +#define Begin(x) Storage::command_ = std::make_unique(Storage::command_context_); switch(value >> 4) { // All codes not listed below are invalid; just abandon // whatever's going on, if anything. default: Storage::command_ = nullptr; case 0b0000: break; // TODO: stop. - case 0b0100: - Storage::command_ = std::make_unique(Storage::command_context_); - break; - case 0b0101: break; // TODO: pset. + case 0b0100: break; // TODO: point. + case 0b0101: Begin(PointSet); break; case 0b0110: break; // TODO: srch. - case 0b0111: - Storage::command_ = std::make_unique(Storage::command_context_); - break; + case 0b0111: Begin(Line); break; case 0b1000: break; // TODO: lmmv. case 0b1001: break; // TODO: lmmm. @@ -868,6 +865,7 @@ void Base::commit_register(int reg, uint8_t value) { case 0b1110: break; // TODO: ymmm. case 0b1111: break; // TODO: hmmc. } +#undef Begin // Seed timing information if a command was found. if(Storage::command_) { @@ -884,7 +882,7 @@ void Base::commit_register(int reg, uint8_t value) { packed_colour |= packed_colour << 4; while(!Storage::command_->done()) { - const int address = + const unsigned int address = (Storage::command_->location.v[0] >> 2) + (Storage::command_->location.v[1] << 7); diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index 609daaeca..8b640b80a 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -63,14 +63,14 @@ struct Command { virtual bool done() = 0; /// Repopulates the fields above with the next action to take. - virtual void advance() {} + virtual void advance() = 0; }; // MARK: - Line drawing. namespace Commands { -/// Implements the line command, which is plain-old Bresenham. +/// Implements the LINE command, which is plain-old Bresenham. /// /// Per Grauw timing is: /// @@ -125,17 +125,27 @@ struct Line: public Command { Vector major_, minor_; }; -struct Point: public Command { +/// Implements the PSET command, which plots a single pixel. +/// +/// No timings are documented, so this'll output as quickly as possible. +struct PointSet: public Command { public: - Point(CommandContext &context) : Command(context) { + PointSet(CommandContext &context) : Command(context) { cycles = 0; access = AccessType::PlotPoint; location = context.destination; } bool done() final { - return true; + return done_; } + + void advance() final { + done_ = true; + } + + private: + bool done_ = false; }; }