1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 03:32:01 +00:00

Vertical state is actually tristate.

This commit is contained in:
Thomas Harte 2023-02-01 22:25:00 -05:00
parent 872b9e5021
commit 115acf835e
2 changed files with 26 additions and 11 deletions

View File

@ -345,14 +345,16 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
break; break;
} }
next_line_buffer.is_refresh = next_line_buffer.vertical_state =
this->screen_mode_ == ScreenMode::Blank || this->screen_mode_ == ScreenMode::Blank ?
this->is_vertical_blank(); VerticalState::Blank :
this->vertical_state();
const bool is_refresh = next_line_buffer.vertical_state == VerticalState::Blank;
// TODO: an actual sprites-enabled flag. // TODO: an actual sprites-enabled flag.
Storage<personality>::begin_line(this->screen_mode_, next_line_buffer.is_refresh, false); Storage<personality>::begin_line(this->screen_mode_, is_refresh, false);
if(next_line_buffer.is_refresh) { if(is_refresh) {
// The Yamaha handles refresh lines via its own microprogram; other VDPs // The Yamaha handles refresh lines via its own microprogram; other VDPs
// can fall back on the regular refresh mechanic. // can fall back on the regular refresh mechanic.
if constexpr (is_yamaha_vdp(personality)) { if constexpr (is_yamaha_vdp(personality)) {
@ -425,7 +427,7 @@ void TMS9918<personality>::run_for(const HalfCycles cycles) {
#define border(left, right) intersect(left, right, this->output_border(end - start, cram_value)) #define border(left, right) intersect(left, right, this->output_border(end - start, cram_value))
if(line_buffer.is_refresh) { if(line_buffer.vertical_state != VerticalState::Pixels) {
if( if(
this->output_pointer_.row >= this->mode_timing_.first_vsync_line && this->output_pointer_.row >= this->mode_timing_.first_vsync_line &&
this->output_pointer_.row < this->mode_timing_.first_vsync_line + 4 this->output_pointer_.row < this->mode_timing_.first_vsync_line + 4
@ -1064,7 +1066,7 @@ uint8_t Base<personality>::read_register() {
return return
transfer_ready | transfer_ready |
(is_vertical_blank() ? 0x40 : 0x00) | (vertical_state() != VerticalState::Pixels ? 0x40 : 0x00) |
(is_horizontal_blank() ? 0x20 : 0x00) | (is_horizontal_blank() ? 0x20 : 0x00) |
(Storage<personality>::command_ ? 0x01 : 0x00); (Storage<personality>::command_ ? 0x01 : 0x00);
@ -1127,8 +1129,11 @@ int Base<personality>::fetch_line() const {
} }
template <Personality personality> template <Personality personality>
bool Base<personality>::is_vertical_blank() const { VerticalState Base<personality>::vertical_state() const {
return fetch_pointer_.row >= mode_timing_.pixel_lines && fetch_pointer_.row != mode_timing_.total_lines - 1; // TODO: the Yamaha uses an internal flag for visible region which toggles at contextually-appropriate moments.
// This test won't work properly there.
if(fetch_pointer_.row == mode_timing_.total_lines - 1) return VerticalState::Prefetch;
return fetch_pointer_.row >= mode_timing_.pixel_lines ? VerticalState::Blank : VerticalState::Pixels;
} }
template <Personality personality> template <Personality personality>

View File

@ -29,6 +29,16 @@
namespace TI { namespace TI {
namespace TMS { namespace TMS {
enum class VerticalState {
/// Describes any line on which pixels do not appear and no fetching occurs, including
/// the border, blanking and sync.
Blank,
/// A line on which pixels do not appear but fetching occurs.
Prefetch,
/// A line on which pixels appear and fetching occurs.
Pixels,
};
// Temporary buffers collect a representation of each line prior to pixel serialisation. // Temporary buffers collect a representation of each line prior to pixel serialisation.
// //
// TODO: either template on personality, to avoid having to be the union of all potential footprints, // TODO: either template on personality, to avoid having to be the union of all potential footprints,
@ -40,7 +50,7 @@ struct LineBuffer {
// screen mode captures proper output mode. // screen mode captures proper output mode.
FetchMode fetch_mode = FetchMode::Text; FetchMode fetch_mode = FetchMode::Text;
ScreenMode screen_mode = ScreenMode::Text; ScreenMode screen_mode = ScreenMode::Text;
bool is_refresh = false; VerticalState vertical_state = VerticalState::Blank;
// Holds the horizontal scroll position to apply to this line; // Holds the horizontal scroll position to apply to this line;
// of those VDPs currently implemented, affects the Master System only. // of those VDPs currently implemented, affects the Master System only.
@ -525,8 +535,8 @@ template <Personality personality> struct Base: public Storage<personality> {
LineBufferPointer output_pointer_, fetch_pointer_; LineBufferPointer output_pointer_, fetch_pointer_;
int fetch_line() const; int fetch_line() const;
bool is_vertical_blank() const;
bool is_horizontal_blank() const; bool is_horizontal_blank() const;
VerticalState vertical_state() const;
int masked_address(int address) const; int masked_address(int address) const;
void write_vram(uint8_t); void write_vram(uint8_t);