mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-01 11:49:58 +00:00
Fill in and use some parts of mode description.
This commit is contained in:
parent
a6251f436a
commit
e66a92d6cb
@ -346,6 +346,13 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
|
|||||||
this->screen_mode_ = this->template current_screen_mode<true>();
|
this->screen_mode_ = this->template current_screen_mode<true>();
|
||||||
this->underlying_mode_ = this->template current_screen_mode<false>();
|
this->underlying_mode_ = this->template current_screen_mode<false>();
|
||||||
|
|
||||||
|
if constexpr (is_yamaha_vdp(personality)) {
|
||||||
|
auto &desc = Storage<personality>::mode_description_;
|
||||||
|
desc.pixels_per_byte = pixels_per_byte(this->underlying_mode_);
|
||||||
|
desc.width = width(this->underlying_mode_);
|
||||||
|
desc.rotate_address = interleaves_banks(this->underlying_mode_);
|
||||||
|
}
|
||||||
|
|
||||||
// Based on the output mode, pick a line mode.
|
// Based on the output mode, pick a line mode.
|
||||||
next_line_buffer.first_pixel_output_column = Timing<personality>::FirstPixelCycle;
|
next_line_buffer.first_pixel_output_column = Timing<personality>::FirstPixelCycle;
|
||||||
next_line_buffer.next_border_column = Timing<personality>::CyclesPerLine;
|
next_line_buffer.next_border_column = Timing<personality>::CyclesPerLine;
|
||||||
@ -903,7 +910,7 @@ void Base<personality>::commit_register(int reg, uint8_t value) {
|
|||||||
Storage<personality>::command_ &&
|
Storage<personality>::command_ &&
|
||||||
Storage<personality>::command_->access == Command::AccessType::WaitForColourReceipt
|
Storage<personality>::command_->access == Command::AccessType::WaitForColourReceipt
|
||||||
) {
|
) {
|
||||||
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
|
Storage<personality>::command_->advance();
|
||||||
Storage<personality>::update_command_step(fetch_pointer_.column);
|
Storage<personality>::update_command_step(fetch_pointer_.column);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -391,7 +391,7 @@ template <Personality personality> struct Base: public Storage<personality> {
|
|||||||
case CommandStep::CopySourcePixelToStatus:
|
case CommandStep::CopySourcePixelToStatus:
|
||||||
Storage<personality>::colour_status_ = extract_colour(source[command_address(context.source, context.arguments & 0x10)], context.source);
|
Storage<personality>::colour_status_ = extract_colour(source[command_address(context.source, context.arguments & 0x10)], context.source);
|
||||||
|
|
||||||
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
|
Storage<personality>::command_->advance();
|
||||||
Storage<personality>::update_command_step(access_column);
|
Storage<personality>::update_command_step(access_column);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -441,7 +441,7 @@ template <Personality personality> struct Base: public Storage<personality> {
|
|||||||
|
|
||||||
destination[address] = Storage<personality>::command_latch_;
|
destination[address] = Storage<personality>::command_latch_;
|
||||||
|
|
||||||
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
|
Storage<personality>::command_->advance();
|
||||||
Storage<personality>::update_command_step(access_column);
|
Storage<personality>::update_command_step(access_column);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -460,7 +460,7 @@ template <Personality personality> struct Base: public Storage<personality> {
|
|||||||
destination[command_address(context.destination, context.arguments & 0x20)] = context.latched_colour.has_value() ? context.latched_colour.colour : context.colour.colour;
|
destination[command_address(context.destination, context.arguments & 0x20)] = context.latched_colour.has_value() ? context.latched_colour.colour : context.colour.colour;
|
||||||
context.latched_colour.reset();
|
context.latched_colour.reset();
|
||||||
|
|
||||||
Storage<personality>::command_->advance(pixels_per_byte(this->underlying_mode_));
|
Storage<personality>::command_->advance();
|
||||||
Storage<personality>::update_command_step(access_column);
|
Storage<personality>::update_command_step(access_column);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,29 @@ constexpr int pixels_per_byte(ScreenMode mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr int width(ScreenMode mode) {
|
||||||
|
switch(mode) {
|
||||||
|
default:
|
||||||
|
case ScreenMode::Blank: return 0;
|
||||||
|
case ScreenMode::Text: return 240;
|
||||||
|
case ScreenMode::MultiColour: return 256;
|
||||||
|
case ScreenMode::ColouredText: return 256;
|
||||||
|
case ScreenMode::Graphics: return 256;
|
||||||
|
case ScreenMode::SMSMode4: return 256;
|
||||||
|
case ScreenMode::YamahaText80: return 480;
|
||||||
|
case ScreenMode::YamahaGraphics3: return 256;
|
||||||
|
case ScreenMode::YamahaGraphics4: return 256;
|
||||||
|
case ScreenMode::YamahaGraphics5: return 512;
|
||||||
|
case ScreenMode::YamahaGraphics6: return 512;
|
||||||
|
case ScreenMode::YamahaGraphics7: return 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool interleaves_banks(ScreenMode mode) {
|
||||||
|
return mode == ScreenMode::YamahaGraphics6 || mode == ScreenMode::YamahaGraphics7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum class FetchMode {
|
enum class FetchMode {
|
||||||
Text,
|
Text,
|
||||||
Character,
|
Character,
|
||||||
|
@ -139,7 +139,7 @@ struct Command {
|
|||||||
|
|
||||||
/// Repopulates the fields above with the next action to take, being provided with the
|
/// Repopulates the fields above with the next action to take, being provided with the
|
||||||
/// number of pixels per byte in the current screen mode.
|
/// number of pixels per byte in the current screen mode.
|
||||||
virtual void advance(int pixels_per_byte) = 0;
|
virtual void advance() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <int axis, bool include_source> void advance_axis(int offset = 1) {
|
template <int axis, bool include_source> void advance_axis(int offset = 1) {
|
||||||
@ -180,7 +180,7 @@ struct Line: public Command {
|
|||||||
return !context.size.v[0];
|
return !context.size.v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(int) final {
|
void advance() final {
|
||||||
--context.size.v[0];
|
--context.size.v[0];
|
||||||
cycles = 88;
|
cycles = 88;
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ template <bool is_read> struct Point: public Command {
|
|||||||
return done_;
|
return done_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(int) final {
|
void advance() final {
|
||||||
done_ = true;
|
done_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,10 +261,7 @@ template <bool logical, bool include_source> struct Rectangle: public Command {
|
|||||||
|
|
||||||
/// Advances the current destination and, if @c include_source is @c true also the source;
|
/// Advances the current destination and, if @c include_source is @c true also the source;
|
||||||
/// @returns @c true if a new row was started; @c false otherwise.
|
/// @returns @c true if a new row was started; @c false otherwise.
|
||||||
///
|
bool advance_pixel() {
|
||||||
/// @c pixels_per_byte is used for 'fast' (i.e. not logical) rectangles only, setting pace at
|
|
||||||
/// which the source and destination proceed left-to-right.
|
|
||||||
bool advance_pixel(int pixels_per_byte = 0) {
|
|
||||||
if constexpr (logical) {
|
if constexpr (logical) {
|
||||||
advance_axis<0, include_source>();
|
advance_axis<0, include_source>();
|
||||||
--context.size.v[0];
|
--context.size.v[0];
|
||||||
@ -273,10 +270,10 @@ template <bool logical, bool include_source> struct Rectangle: public Command {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
advance_axis<0, include_source>(pixels_per_byte);
|
advance_axis<0, include_source>(mode_description.pixels_per_byte);
|
||||||
context.size.v[0] -= pixels_per_byte;
|
context.size.v[0] -= mode_description.pixels_per_byte;
|
||||||
|
|
||||||
if(context.size.v[0] & ~(pixels_per_byte - 1)) {
|
if(context.size.v[0] & ~(mode_description.pixels_per_byte - 1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +309,7 @@ template <bool logical> struct MoveFromCPU: public Rectangle<logical, false> {
|
|||||||
Command::access = logical ? Command::AccessType::PlotPoint : Command::AccessType::WriteByte;
|
Command::access = logical ? Command::AccessType::PlotPoint : Command::AccessType::WriteByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(int pixels_per_byte) final {
|
void advance() final {
|
||||||
switch(Command::access) {
|
switch(Command::access) {
|
||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
@ -325,7 +322,7 @@ template <bool logical> struct MoveFromCPU: public Rectangle<logical, false> {
|
|||||||
case Command::AccessType::PlotPoint:
|
case Command::AccessType::PlotPoint:
|
||||||
Command::cycles = 0;
|
Command::cycles = 0;
|
||||||
Command::access = Command::AccessType::WaitForColourReceipt;
|
Command::access = Command::AccessType::WaitForColourReceipt;
|
||||||
if(Rectangle<logical, false>::advance_pixel(pixels_per_byte)) {
|
if(Rectangle<logical, false>::advance_pixel()) {
|
||||||
Command::cycles = 64;
|
Command::cycles = 64;
|
||||||
// TODO: I'm not sure this will be honoured per the outer wrapping.
|
// TODO: I'm not sure this will be honoured per the outer wrapping.
|
||||||
}
|
}
|
||||||
@ -353,9 +350,9 @@ template <MoveType type> struct Move: public Rectangle<type == MoveType::Logical
|
|||||||
Command::y_only = is_y_only;
|
Command::y_only = is_y_only;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(int pixels_per_byte) final {
|
void advance() final {
|
||||||
Command::cycles = is_y_only ? 40 : 64;
|
Command::cycles = is_y_only ? 40 : 64;
|
||||||
if(RectangleBase::advance_pixel(pixels_per_byte)) {
|
if(RectangleBase::advance_pixel()) {
|
||||||
Command::cycles += is_y_only ? 0 : 64;
|
Command::cycles += is_y_only ? 0 : 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,9 +366,9 @@ struct HighSpeedFill: public Rectangle<false, false> {
|
|||||||
access = AccessType::WriteByte;
|
access = AccessType::WriteByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(int pixels_per_byte) final {
|
void advance() final {
|
||||||
cycles = 48;
|
cycles = 48;
|
||||||
if(advance_pixel(pixels_per_byte)) {
|
if(advance_pixel()) {
|
||||||
cycles += 56;
|
cycles += 56;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,7 +380,7 @@ struct LogicalFill: public Rectangle<false, false> {
|
|||||||
access = AccessType::PlotPoint;
|
access = AccessType::PlotPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(int) final {
|
void advance() final {
|
||||||
cycles = 72;
|
cycles = 72;
|
||||||
if(advance_pixel()) {
|
if(advance_pixel()) {
|
||||||
cycles += 64;
|
cycles += 64;
|
||||||
|
Loading…
Reference in New Issue
Block a user