1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Add pixel serialisation for Yamaha graphics mode 5.

This commit is contained in:
Thomas Harte 2023-01-24 23:07:29 -05:00
parent f8b42d4107
commit 700470915a
4 changed files with 47 additions and 8 deletions

View File

@ -279,6 +279,7 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
next_line_buffer.first_pixel_output_column = Timing<personality>::FirstPixelCycle;
next_line_buffer.next_border_column = Timing<personality>::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<personality>::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<personality>::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<personality>::CyclesPerLine) {
output_sync(Timing<personality>::CyclesPerLine);
}
@ -452,12 +458,12 @@ void TMS9918<personality>::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. */
}

View File

@ -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 <Personality personality> struct Base: public Storage<personality> {
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<ScreenMode mode> void draw_yamaha(LineBuffer &, int start, int end);
void draw_yamaha(int start, int end);
};
#include "Fetch.hpp"

View File

@ -288,7 +288,35 @@ void Base<personality>::draw_sms(int start, int end, uint32_t cram_dot) {
// MARK: - Yamaha
// TODO.
template <Personality personality>
template <ScreenMode mode>
void Base<personality>::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<personality>::palette_[
(buffer.bitmap[c >> 2] >> ((c & 3) << 1)) & 3
];
}
return;
}
}
template <Personality personality>
void Base<personality>::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<ScreenMode::YamahaGraphics5>(line_buffer, start, end); break;
default: break;
}
}
}
// MARK: - Mega Drive

View File

@ -530,7 +530,7 @@ template<bool use_end> void Base<personality>::fetch_yamaha(LineBuffer &line_buf
if constexpr (is_yamaha_vdp(personality)) {
// Dispatch according to [supported] screen mode.
#define Dispatch(mode) case mode: fetch_yamaha<mode>(line_buffer, y, end); break;
switch(screen_mode_) {
switch(line_buffer.screen_mode) {
default: break;
Dispatch(ScreenMode::Blank);
Dispatch(ScreenMode::Text);