From c5c722ae56dd1f1e702399315e37223377fb1d6c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 31 Jan 2023 13:35:39 -0500 Subject: [PATCH 01/10] Generalise axis steps; begin HMMV. --- Components/9918/Implementation/9918.cpp | 2 +- Components/9918/Implementation/9918Base.hpp | 10 +++++ .../9918/Implementation/YamahaCommands.hpp | 43 ++++++++++++++++--- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index ee7baec4a..178e45d60 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -915,7 +915,7 @@ void Base::commit_register(int reg, uint8_t value) { case 0b1010: break; // TODO: lmcm. [logical move, VRAM to CPU] case 0b1011: Begin(LogicalMoveFromCPU); break; // LMMC [logical move, CPU to VRAM] - case 0b1100: break; // TODO: hmmv. [high-speed move, VRAM to VDP] + case 0b1100: Begin(HighSpeedFill); break; // HMMV [high-speed move, VDP to VRAM] case 0b1101: break; // TODO: hmmm. [high-speed move, VRAM to VRAM] case 0b1110: break; // TODO: ymmm. [high-speed move, y only, VRAM to VRAM] case 0b1111: break; // TODO: hmmc. [high-speed move, CPU to VRAM] diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 242f80034..3ec608949 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -192,6 +192,7 @@ template struct Storage struct Storage struct Base: public Storage { Storage::command_->advance(); Storage::update_command_step(access_column); } break; + + case CommandStep::WriteByte: + ram_[command_address()] = Storage::command_context_.colour; + Storage::command_->advance(); + Storage::update_command_step(access_column); + break; } } diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index 2ad52c83e..291066ea1 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -79,6 +79,9 @@ struct Command { /// Blocks until the next CPU write to the colour register. WaitForColourReceipt, + + /// Writes an entire byte to the location containing the current @c location. + WriteByte, }; AccessType access = AccessType::PlotPoint; int cycles = 0; @@ -94,6 +97,12 @@ struct Command { /// Repopulates the fields above with the next action to take. virtual void advance() = 0; + + protected: + template void advance_axis() { + context.destination.add(context.arguments & (0x4 << axis) ? -1 : 1); + } + }; // MARK: - Line drawing. @@ -140,9 +149,9 @@ struct Line: public Command { // b3: 1 => y direction is up; // 0 => y direction is down. if(context.arguments & 0x1) { - location.add<1>(context.arguments & 0x8 ? -1 : 1); + advance_axis<1>(); } else { - location.add<0>(context.arguments & 0x4 ? -1 : 1); + advance_axis<0>(); } position_ -= numerator_; @@ -151,9 +160,9 @@ struct Line: public Command { cycles += 32; if(context.arguments & 0x1) { - location.add<0>(context.arguments & 0x4 ? -1 : 1); + advance_axis<0>(); } else { - location.add<1>(context.arguments & 0x8 ? -1 : 1); + advance_axis<1>(); } } } @@ -212,7 +221,7 @@ struct LogicalMoveFromCPU: public Command { case AccessType::PlotPoint: cycles = 0; access = AccessType::WaitForColourReceipt; - context.destination.add<0>(context.arguments & 0x4 ? -1 : 1); + advance_axis<0>(); --context.size.v[0]; if(!context.size.v[0]) { @@ -220,7 +229,7 @@ struct LogicalMoveFromCPU: public Command { context.size.v[0] = width_; context.destination.v[0] = start_x_; - context.destination.add<1>(context.arguments & 0x8 ? -1 : 1); + advance_axis<1>(); --context.size.v[1]; } break; @@ -235,6 +244,28 @@ struct LogicalMoveFromCPU: public Command { int start_x_ = 0, width_ = 0; }; +struct HighSpeedFill: public Command { + HighSpeedFill(CommandContext &context) : Command(context) { + start_x_ = context.destination.v[0]; + width_ = context.size.v[0]; + + cycles = 56; + access = AccessType::WriteByte; + location = context.destination; + } + + bool done() final { + return true; + } + + void advance() final { + cycles = 48; + } + + private: + int start_x_ = 0, width_ = 0; +}; + } } } From a315384e30d093dcfc18beab751ab08c7689da6c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 31 Jan 2023 21:29:55 -0500 Subject: [PATCH 02/10] Provide context for byte-by-byte commands. --- Components/9918/Implementation/9918.cpp | 2 +- Components/9918/Implementation/9918Base.hpp | 6 ++-- .../9918/Implementation/AccessEnums.hpp | 17 ++++++++++ .../9918/Implementation/YamahaCommands.hpp | 33 ++++++++++++++----- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 178e45d60..510b5ed1c 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -871,7 +871,7 @@ void Base::commit_register(int reg, uint8_t value) { Storage::command_ && Storage::command_->access == Command::AccessType::WaitForColourReceipt ) { - Storage::command_->advance(); + Storage::command_->advance(pixels_per_byte(this->screen_mode_)); Storage::update_command_step(fetch_pointer_.column); } break; diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 3ec608949..8d5b36309 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -365,8 +365,6 @@ template struct Storage struct Base: public Storage { ram_[address] = Storage::command_latch_; - Storage::command_->advance(); + Storage::command_->advance(pixels_per_byte(this->screen_mode_)); Storage::update_command_step(access_column); } break; case CommandStep::WriteByte: ram_[command_address()] = Storage::command_context_.colour; - Storage::command_->advance(); + Storage::command_->advance(pixels_per_byte(this->screen_mode_)); Storage::update_command_step(access_column); break; } diff --git a/Components/9918/Implementation/AccessEnums.hpp b/Components/9918/Implementation/AccessEnums.hpp index 66a80ec1e..a2a079b64 100644 --- a/Components/9918/Implementation/AccessEnums.hpp +++ b/Components/9918/Implementation/AccessEnums.hpp @@ -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, diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index 291066ea1..6eb9fa13d 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -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 void advance_axis() { - context.destination.add(context.arguments & (0x4 << axis) ? -1 : 1); + template void advance_axis(int offset = 1) { + context.destination.add(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: From 90e8ce325333d297f41b43a1f557bbe0a6598a6f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 31 Jan 2023 21:33:57 -0500 Subject: [PATCH 03/10] Fix lines. TODO: determine whether I really need `location` as distinct from `.destination`. --- Components/9918/Implementation/YamahaCommands.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index 6eb9fa13d..ebaf85dde 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -165,6 +165,8 @@ struct Line: public Command { advance_axis<1>(); } } + + location = context.destination; } private: From 002d27d9c231a762510edd9f74225252d500b5de Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:17:49 -0500 Subject: [PATCH 04/10] Resolve various type conversion errors, and reduce duplication. --- Components/9918/Implementation/9918.cpp | 69 +++++---------------- Components/9918/Implementation/9918Base.hpp | 64 ++++++++++++------- Components/9918/Implementation/Fetch.hpp | 26 ++++---- 3 files changed, 72 insertions(+), 87 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 510b5ed1c..ca23f1272 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -488,7 +488,7 @@ void TMS9918::run_for(const HalfCycles cycles) { this->asked_for_write_area_ = true; this->pixel_origin_ = this->pixel_target_ = reinterpret_cast( - this->crt_.begin_data(line_buffer.pixel_count) + this->crt_.begin_data(size_t(line_buffer.pixel_count)) ); } @@ -507,7 +507,7 @@ void TMS9918::run_for(const HalfCycles cycles) { if(end == line_buffer.next_border_column) { const int length = line_buffer.next_border_column - line_buffer.first_pixel_output_column; - this->crt_.output_data(from_internal(length), line_buffer.pixel_count); + this->crt_.output_data(from_internal(length), size_t(line_buffer.pixel_count)); this->pixel_origin_ = this->pixel_target_ = nullptr; this->asked_for_write_area_ = false; } @@ -645,32 +645,11 @@ void Base::commit_register(int reg, uint8_t value) { if(sprites_magnified_) sprite_height_ <<= 1; break; - case 2: - pattern_name_address_ = size_t((value & 0xf) << 10) | 0x3ff; - break; - - case 3: - colour_table_address_ = - (colour_table_address_ & ~0x3fc0) | - (value << 6) | - 0x3f; - break; - - case 4: - pattern_generator_table_address_ = size_t((value & 0x07) << 11) | 0x7ff; - // TODO: don't mask off so many bits for, at least, the Yamahas. - break; - - case 5: - sprite_attribute_table_address_ = - (sprite_attribute_table_address_ & ~0x3d80) | - ((value << 7) & 0x3f80) | - 0x7f; - break; - - case 6: - sprite_generator_table_address_ = size_t((value & 0x07) << 11) | 0x7ff; - break; + case 2: install_field<10>(pattern_name_address_, value); break; + case 3: install_field<6>(colour_table_address_, value); break; + case 4: install_field<11>(pattern_generator_table_address_, value); break; + case 5: install_field<7>(sprite_attribute_table_address_, value); break; + case 6: install_field<11>(sprite_generator_table_address_, value); break; case 7: text_colour_ = value >> 4; @@ -755,11 +734,6 @@ void Base::commit_register(int reg, uint8_t value) { LOG("Screen mode: " << int(current_screen_mode())); break; - case 2: - // Retain extra addressing bits. - pattern_name_address_ = size_t((value & 0x7f) << 10) | 0x3ff; - break; - case 8: LOG("TODO: Yamaha VRAM organisation, sprite disable, etc; " << PADHEX(2) << +value); // b7: "1 = input on colour bus, enable mouse; 1 = output on colour bus, disable mouse" [documentation clearly in error] @@ -781,19 +755,11 @@ void Base::commit_register(int reg, uint8_t value) { // b0: 1 = [dot clock] DLCLK is input; 0 = DLCLK is output break; - case 10: - colour_table_address_ = - (colour_table_address_ & ~0x1c000) | - ((value << 14) & 0x1c000); - // b0–b2: A14–A16 of the colour table. - break; + // b0–b2: A14–A16 of the colour table. + case 10: install_field<14>(colour_table_address_, value); break; - case 11: - sprite_attribute_table_address_ = - (sprite_attribute_table_address_ & ~0x18000) | - ((value << 15) & 0x18000); - // b0–b1: A15–A16 of the sprite table. - break; + // b0–b1: A15–A16 of the sprite table. + case 11: install_field<15>(sprite_attribute_table_address_, value); break; case 12: LOG("TODO: Yamaha text and background blink colour; " << PADHEX(2) << +value); @@ -806,9 +772,7 @@ void Base::commit_register(int reg, uint8_t value) { // b4–b7: display time for even page. break; - case 14: - ram_pointer_ = (ram_pointer_ & ~0x1c000) | ((value << 14) & 0x1c000); - break; + case 14: install_field<14>(ram_pointer_, value); break; case 15: Storage::selected_status_ = value & 0xf; @@ -863,8 +827,8 @@ void Base::commit_register(int reg, uint8_t value) { case 44: Storage::command_context_.colour = value; - Storage::command_context_.colour4bpp = (value & 0xf) | (value << 4); - Storage::command_context_.colour2bpp = (value & 0x3) | ((value & 0x3) << 2) | ((value & 0x3) << 4) | ((value & 0x3) << 6); + Storage::command_context_.colour4bpp = uint8_t((value & 0xf) | (value << 4)); + Storage::command_context_.colour2bpp = uint8_t((value & 0x3) | ((value & 0x3) << 2) | ((value & 0x3) << 4) | ((value & 0x3) << 6)); // Check whether a command was blocked on this. if( @@ -948,13 +912,12 @@ void Base::write_register(uint8_t value) { write_phase_ = true; // The initial write should half update the access pointer. - ram_pointer_ = (ram_pointer_ & ~0xff) | low_write_; + install_field<0>(ram_pointer_, value); return; } // The RAM pointer is always set on a second write, regardless of - // whether the caller is intending to enqueue a VDP operation. - ram_pointer_ = (ram_pointer_ & ~0x3f00) | ((value << 8) & 0x3f00); + // whether the caller is intending to enqueue a VDP operation. install_field<8, 0x3f>(ram_pointer_, value); write_phase_ = false; if(value & 0x80) { diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 8d5b36309..0b11a9987 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -86,7 +86,7 @@ struct LineBuffer { */ int first_pixel_output_column = 94; int next_border_column = 334; - size_t pixel_count = 256; + int pixel_count = 256; // An active sprite is one that has been selected for composition onto // this line. @@ -121,11 +121,15 @@ template struct Storage { }; template <> struct Storage { + using AddressT = uint16_t; + void begin_line(ScreenMode, bool, bool) {} }; // Yamaha-specific storage. template struct Storage> { + using AddressT = uint32_t; + int selected_status_ = 0; int indirect_register_ = 0; @@ -351,6 +355,8 @@ template struct Storage struct Storage> { + using AddressT = uint16_t; + // The SMS VDP has a programmer-set colour palette, with a dedicated patch of RAM. But the RAM is only exactly // fast enough for the pixel clock. So when the programmer writes to it, that causes a one-pixel glitch; there // isn't the bandwidth for the read both write to occur simultaneously. The following buffer therefore keeps @@ -379,10 +385,10 @@ template struct Storage struct Base: public Storage { Outputs::CRT::CRT crt_; TVStandard tv_standard_ = TVStandard::NTSC; + using AddressT = typename Storage::AddressT; + + /// Mutates @c target such that @c source & @c source_mask replaces the bits that currently start + /// at @c shift bits from least significant. Subsequently ensures @c target is constrained by the + /// applicable @c memory_mask. + template void install_field(AddressT &target, uint8_t source) { + constexpr auto mask = AddressT(~(source_mask << shift)); + target = ( + (target & mask) | + AddressT((source & source_mask) << shift) + ) & memory_mask(personality); + } // Personality-specific metrics and converters. ClockConverter clock_converter_; @@ -440,7 +458,7 @@ template struct Base: public Storage { std::array ram_; // State of the DRAM/CRAM-access mechanism. - size_t ram_pointer_ = 0; + AddressT ram_pointer_ = 0; uint8_t read_ahead_buffer_ = 0; MemoryAccess queued_access_ = MemoryAccess::None; int minimum_access_column_ = 0; @@ -463,11 +481,11 @@ template struct Base: public Storage { int sprite_height_ = 8; // Programmer-specified addresses. - size_t pattern_name_address_ = 0; // i.e. address of the tile map. - size_t colour_table_address_ = 0; // address of the colour map (if applicable). - size_t pattern_generator_table_address_ = 0; // address of the tile contents. - size_t sprite_attribute_table_address_ = 0; // address of the sprite list. - size_t sprite_generator_table_address_ = 0; // address of the sprite contents. + AddressT pattern_name_address_ = memory_mask(personality); // Address of the tile map. + AddressT colour_table_address_ = memory_mask(personality); // Address of the colour map (if applicable). + AddressT pattern_generator_table_address_ = memory_mask(personality); // Address of the tile contents. + AddressT sprite_attribute_table_address_ = memory_mask(personality); // Address of the sprite list. + AddressT sprite_generator_table_address_ = memory_mask(personality); // Address of the sprite contents. // Default colours. uint8_t text_colour_ = 0; @@ -588,29 +606,33 @@ template struct Base: public Storage { return ScreenMode::Blank; } - uint32_t command_address() const { + AddressT command_address() const { if constexpr (is_yamaha_vdp(personality)) { switch(this->screen_mode_) { default: case ScreenMode::YamahaGraphics4: // 256 pixels @ 4bpp - return + return AddressT( (Storage::command_->location.v[0] >> 1) + - (Storage::command_->location.v[1] << 7); + (Storage::command_->location.v[1] << 7) + ); case ScreenMode::YamahaGraphics5: // 512 pixels @ 2bpp - return + return AddressT( (Storage::command_->location.v[0] >> 2) + - (Storage::command_->location.v[1] << 7); + (Storage::command_->location.v[1] << 7) + ); case ScreenMode::YamahaGraphics6: // 512 pixels @ 4bpp - return + return AddressT( (Storage::command_->location.v[0] >> 1) + - (Storage::command_->location.v[1] << 8); + (Storage::command_->location.v[1] << 8) + ); case ScreenMode::YamahaGraphics7: // 256 pixels @ 8bpp - return + return AddressT( (Storage::command_->location.v[0] >> 0) + - (Storage::command_->location.v[1] << 8); + (Storage::command_->location.v[1] << 8) + ); } } else { return 0; @@ -720,7 +742,7 @@ template struct Base: public Storage { return; } - size_t address = ram_pointer_; + AddressT address = ram_pointer_; ++ram_pointer_; if constexpr (is_yamaha_vdp(personality)) { diff --git a/Components/9918/Implementation/Fetch.hpp b/Components/9918/Implementation/Fetch.hpp index 18b55f1c0..b2a3d1f8b 100644 --- a/Components/9918/Implementation/Fetch.hpp +++ b/Components/9918/Implementation/Fetch.hpp @@ -469,7 +469,7 @@ template void Base::fetch_sms(LineBuffer &line_buffer template template void Base::fetch_yamaha([[maybe_unused]] LineBuffer &line_buffer, [[maybe_unused]] int y, int end) { - const int rotated_name_ = pattern_name_address_ >> 1; + const AddressT rotated_name_ = pattern_name_address_ >> 1; const uint8_t *const ram2 = &ram_[65536]; while(Storage::next_event_->offset < end) { @@ -488,10 +488,10 @@ template void Base::fetch_yamaha([[maybe_unused]] const int start = (y << 7) | column | 0x1'8000; - line_buffer.bitmap[column + 0] = ram_[pattern_name_address_ & (start + 0)]; - line_buffer.bitmap[column + 1] = ram_[pattern_name_address_ & (start + 1)]; - line_buffer.bitmap[column + 2] = ram_[pattern_name_address_ & (start + 2)]; - line_buffer.bitmap[column + 3] = ram_[pattern_name_address_ & (start + 3)]; + line_buffer.bitmap[column + 0] = ram_[pattern_name_address_ & AddressT(start + 0)]; + line_buffer.bitmap[column + 1] = ram_[pattern_name_address_ & AddressT(start + 1)]; + line_buffer.bitmap[column + 2] = ram_[pattern_name_address_ & AddressT(start + 2)]; + line_buffer.bitmap[column + 3] = ram_[pattern_name_address_ & AddressT(start + 3)]; } break; case ScreenMode::YamahaGraphics6: @@ -502,14 +502,14 @@ template void Base::fetch_yamaha([[maybe_unused]] const int start = (y << 7) | column | 0x1'8000; // Fetch from alternate banks. - line_buffer.bitmap[column + 0] = ram_[rotated_name_ & (start + 0)]; - line_buffer.bitmap[column + 1] = ram2[rotated_name_ & (start + 0)]; - line_buffer.bitmap[column + 2] = ram_[rotated_name_ & (start + 1)]; - line_buffer.bitmap[column + 3] = ram2[rotated_name_ & (start + 1)]; - line_buffer.bitmap[column + 4] = ram_[rotated_name_ & (start + 2)]; - line_buffer.bitmap[column + 5] = ram2[rotated_name_ & (start + 2)]; - line_buffer.bitmap[column + 6] = ram_[rotated_name_ & (start + 3)]; - line_buffer.bitmap[column + 7] = ram2[rotated_name_ & (start + 3)]; + line_buffer.bitmap[column + 0] = ram_[rotated_name_ & AddressT(start + 0)]; + line_buffer.bitmap[column + 1] = ram2[rotated_name_ & AddressT(start + 0)]; + line_buffer.bitmap[column + 2] = ram_[rotated_name_ & AddressT(start + 1)]; + line_buffer.bitmap[column + 3] = ram2[rotated_name_ & AddressT(start + 1)]; + line_buffer.bitmap[column + 4] = ram_[rotated_name_ & AddressT(start + 2)]; + line_buffer.bitmap[column + 5] = ram2[rotated_name_ & AddressT(start + 2)]; + line_buffer.bitmap[column + 6] = ram_[rotated_name_ & AddressT(start + 3)]; + line_buffer.bitmap[column + 7] = ram2[rotated_name_ & AddressT(start + 3)]; } break; default: From 1264600babe9bc3ed649b4d21dd86ef8973a7004 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:18:36 -0500 Subject: [PATCH 05/10] Shorten long lines. --- Components/9918/Implementation/9918.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index ca23f1272..f67e261a6 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -827,8 +827,16 @@ void Base::commit_register(int reg, uint8_t value) { case 44: Storage::command_context_.colour = value; - Storage::command_context_.colour4bpp = uint8_t((value & 0xf) | (value << 4)); - Storage::command_context_.colour2bpp = uint8_t((value & 0x3) | ((value & 0x3) << 2) | ((value & 0x3) << 4) | ((value & 0x3) << 6)); + Storage::command_context_.colour4bpp = uint8_t( + (value & 0xf) | + (value << 4) + ); + Storage::command_context_.colour2bpp = uint8_t( + (value & 0x3) | + ((value & 0x3) << 2) | + ((value & 0x3) << 4) | + ((value & 0x3) << 6) + ); // Check whether a command was blocked on this. if( From 3636383b1f601b35b5cd9cf879f43558e6187728 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:20:11 -0500 Subject: [PATCH 06/10] Silence abstract/non-virtual-destructor warning. --- Components/9918/Implementation/YamahaCommands.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Components/9918/Implementation/YamahaCommands.hpp b/Components/9918/Implementation/YamahaCommands.hpp index ebaf85dde..6fd3e7cdc 100644 --- a/Components/9918/Implementation/YamahaCommands.hpp +++ b/Components/9918/Implementation/YamahaCommands.hpp @@ -91,6 +91,7 @@ struct Command { /// Current command parameters. CommandContext &context; Command(CommandContext &context) : context(context) {} + virtual ~Command() {} /// @returns @c true if all output from this command is done; @c false otherwise. virtual bool done() = 0; From 4cc34fd55713bfb76fc7259d8adcf6c9b6178f6e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:28:19 -0500 Subject: [PATCH 07/10] Resolve GCC complaint. --- Components/9918/Implementation/AccessEnums.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Components/9918/Implementation/AccessEnums.hpp b/Components/9918/Implementation/AccessEnums.hpp index a2a079b64..5aa912183 100644 --- a/Components/9918/Implementation/AccessEnums.hpp +++ b/Components/9918/Implementation/AccessEnums.hpp @@ -41,6 +41,7 @@ enum class ScreenMode { constexpr int pixels_per_byte(ScreenMode mode) { switch(mode) { + default: case ScreenMode::Blank: return 0; case ScreenMode::Text: return 6; case ScreenMode::MultiColour: return 2; From ce6dd188a446d33d54cc972520a3200e0b641784 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:31:40 -0500 Subject: [PATCH 08/10] Double up on `alignas`. --- Numeric/RegisterSizes.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Numeric/RegisterSizes.hpp b/Numeric/RegisterSizes.hpp index c0a86b92f..669227e9c 100644 --- a/Numeric/RegisterSizes.hpp +++ b/Numeric/RegisterSizes.hpp @@ -19,7 +19,7 @@ namespace CPU { /// Provides access to all intermediate parts of a larger int. -template union alignas(Full) RegisterPair { +template union alignas(Full) alignas(Half) RegisterPair { RegisterPair(Full v) : full(v) {} RegisterPair() {} From 9d2841bf6a13f2fde85585807ccf6356ac5bd0f3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:55:33 -0500 Subject: [PATCH 09/10] Reenable full ram pointer capture. Thanks @PatrickvL ! --- Components/9918/Implementation/9918.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index f67e261a6..7de0f3196 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -925,7 +925,8 @@ void Base::write_register(uint8_t value) { } // The RAM pointer is always set on a second write, regardless of - // whether the caller is intending to enqueue a VDP operation. install_field<8, 0x3f>(ram_pointer_, value); + // whether the caller is intending to enqueue a VDP operation. + install_field<8, 0x3f>(ram_pointer_, value); write_phase_ = false; if(value & 0x80) { From f0e70f18fde48290510aec8b77bddc741b4f0e7f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 1 Feb 2023 14:59:42 -0500 Subject: [PATCH 10/10] Fix seeding of output_pointer_. --- Components/9918/Implementation/9918.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 7de0f3196..3cf924234 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -46,8 +46,8 @@ Base::Base() : // at a random position. fetch_pointer_.row = rand() % 262; fetch_pointer_.column = rand() % (Timing::CyclesPerLine - output_lag); - output_pointer_.row = output_pointer_.row; - output_pointer_.column = output_pointer_.column + output_lag; + output_pointer_.row = fetch_pointer_.row; + output_pointer_.column = fetch_pointer_.column + output_lag; } template