diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index e24c206ea..4ff388901 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -279,6 +279,7 @@ void TMS9918::run_for(const HalfCycles cycles) { next_line_buffer.first_pixel_output_column = Timing::FirstPixelCycle; next_line_buffer.next_border_column = Timing::CyclesPerLine; next_line_buffer.pixel_count = 256; + next_line_buffer.screen_mode = this->screen_mode_; this->mode_timing_.maximum_visible_sprites = 4; switch(this->screen_mode_) { case ScreenMode::Text: @@ -293,10 +294,15 @@ void TMS9918::run_for(const HalfCycles cycles) { break; case ScreenMode::YamahaGraphics3: case ScreenMode::YamahaGraphics4: - case ScreenMode::YamahaGraphics5: - case ScreenMode::YamahaGraphics6: case ScreenMode::YamahaGraphics7: next_line_buffer.line_mode = LineMode::Yamaha; + this->mode_timing_.maximum_visible_sprites = 8; + break; + case ScreenMode::YamahaGraphics5: + case ScreenMode::YamahaGraphics6: + next_line_buffer.pixel_count = 512; + next_line_buffer.line_mode = LineMode::Yamaha; + this->mode_timing_.maximum_visible_sprites = 8; break; default: // This covers both MultiColour and Graphics modes. @@ -390,7 +396,7 @@ void TMS9918::run_for(const HalfCycles cycles) { this->output_pointer_.row < this->mode_timing_.first_vsync_line + 4 ) { // Vertical sync. - // TODO: the Mega Drive supports interlaced video, I think? + // TODO: the Yamaha and Mega Drive both support interlaced video. if(end_column == Timing::CyclesPerLine) { output_sync(Timing::CyclesPerLine); } @@ -452,12 +458,12 @@ void TMS9918::run_for(const HalfCycles cycles) { } if(this->pixel_target_) { + // TODO: this dispatch, and the fetch, should be factored into a templatised place, probably. switch(line_buffer.line_mode) { case LineMode::SMS: draw(draw_sms(relative_start, relative_end, cram_value), Clock::TMSPixel); break; case LineMode::Character: draw(draw_tms_character(relative_start, relative_end), Clock::TMSPixel); break; case LineMode::Text: draw(draw_tms_text(relative_start, relative_end), Clock::TMSPixel); break; - - // TODO: Yamaha line modes. + case LineMode::Yamaha: draw(draw_yamaha(relative_start, relative_end), Clock::Internal); break; case LineMode::Refresh: break; /* Dealt with elsewhere. */ } diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 9f9dac90c..90ccb5ee5 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -72,8 +72,10 @@ enum class MemoryAccess { struct LineBuffer { LineBuffer() {} - // The line mode describes the proper timing diagram for this line. + // The line mode describes the proper timing diagram for this line; + // screen mode captures proper output mode. LineMode line_mode = LineMode::Text; + ScreenMode screen_mode = ScreenMode::Text; // Holds the horizontal scroll position to apply to this line; // of those VDPs currently implemented, affects the Master System only. @@ -663,6 +665,9 @@ template struct Base: public Storage { void draw_tms_character(int start, int end); void draw_tms_text(int start, int end); void draw_sms(int start, int end, uint32_t cram_dot); + + template void draw_yamaha(LineBuffer &, int start, int end); + void draw_yamaha(int start, int end); }; #include "Fetch.hpp" diff --git a/Components/9918/Implementation/Draw.hpp b/Components/9918/Implementation/Draw.hpp index 8b40fcbe3..aebb2d269 100644 --- a/Components/9918/Implementation/Draw.hpp +++ b/Components/9918/Implementation/Draw.hpp @@ -288,7 +288,35 @@ void Base::draw_sms(int start, int end, uint32_t cram_dot) { // MARK: - Yamaha -// TODO. +template +template +void Base::draw_yamaha(LineBuffer &buffer, int start, int end) { + // TODO: sprites. And all other graphics modes. + + if constexpr (mode == ScreenMode::YamahaGraphics5) { + for(int c = start >> 1; c < end >> 1; c++) { + pixel_target_[c] = Storage::palette_[ + (buffer.bitmap[c >> 2] >> ((c & 3) << 1)) & 3 + ]; + } + + return; + } + +} + +template +void Base::draw_yamaha(int start, int end) { + LineBuffer &line_buffer = line_buffers_[output_pointer_.row]; + + if constexpr (is_yamaha_vdp(personality)) { + switch(line_buffer.screen_mode) { + case ScreenMode::YamahaGraphics5: draw_yamaha(line_buffer, start, end); break; + + default: break; + } + } +} // MARK: - Mega Drive diff --git a/Components/9918/Implementation/Fetch.hpp b/Components/9918/Implementation/Fetch.hpp index 7c4dfad4c..18b55f1c0 100644 --- a/Components/9918/Implementation/Fetch.hpp +++ b/Components/9918/Implementation/Fetch.hpp @@ -530,7 +530,7 @@ template void Base::fetch_yamaha(LineBuffer &line_buf if constexpr (is_yamaha_vdp(personality)) { // Dispatch according to [supported] screen mode. #define Dispatch(mode) case mode: fetch_yamaha(line_buffer, y, end); break; - switch(screen_mode_) { + switch(line_buffer.screen_mode) { default: break; Dispatch(ScreenMode::Blank); Dispatch(ScreenMode::Text);