1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Corrects counting deficiencies that could produce an unstable display.

This commit is contained in:
Thomas Harte 2017-11-27 21:36:12 -05:00
parent 173e16b107
commit dbb14ea2e2
2 changed files with 31 additions and 24 deletions

View File

@ -24,8 +24,6 @@ std::shared_ptr<Outputs::CRT::CRT> TMS9918::get_crt() {
} }
void TMS9918::run_for(const HalfCycles cycles) { void TMS9918::run_for(const HalfCycles cycles) {
// TODO: all video output (!)
// As specific as I've been able to get: // As specific as I've been able to get:
// Scanline time is always 227.75 cycles. // Scanline time is always 227.75 cycles.
// PAL output is 313 lines total. NTSC output is 262 lines total. // PAL output is 313 lines total. NTSC output is 262 lines total.
@ -36,6 +34,7 @@ void TMS9918::run_for(const HalfCycles cycles) {
int int_cycles = (cycles.as_int() * 3) + cycles_error_; int int_cycles = (cycles.as_int() * 3) + cycles_error_;
cycles_error_ = int_cycles & 3; cycles_error_ = int_cycles & 3;
int_cycles >>= 2; int_cycles >>= 2;
if(!int_cycles) return;
// //
// Break that down as: // Break that down as:
@ -43,48 +42,56 @@ void TMS9918::run_for(const HalfCycles cycles) {
while(int_cycles) { while(int_cycles) {
int cycles_left = std::min(342 - column_, int_cycles); int cycles_left = std::min(342 - column_, int_cycles);
int end_column = std::min(column_ + int_cycles, 342); column_ += cycles_left;
if(row_ < 192) { if(row_ < 192) {
// Pixels. // Pixels.
if(column_ < 26 && end_column >= 26) { if(!output_column_ && column_ >= 26) {
crt_->output_sync(static_cast<unsigned int>(26)); crt_->output_sync(static_cast<unsigned int>(26));
column_ = 26; output_column_ = 26;
} }
if(column_ >= 26 && end_column >= 69) { // TODO: modes other than text // TODO: colour burst.
if(output_column_ == 26 && column_ >= 69) { // TODO: modes other than text
crt_->output_blank(static_cast<unsigned int>(69 - 26)); crt_->output_blank(static_cast<unsigned int>(69 - 26));
column_ = 69; output_column_ = 69;
pixel_target_ = crt_->allocate_write_area(256); pixel_target_ = crt_->allocate_write_area(256);
} }
while(column_ < end_column && column_ < 309) { // TODO: modes other than text if(output_column_ >= 69) {
pixel_target_[0] = pixel_target_[1] = pixel_target_[2] = pixel_target_[3] = 0xff; int pixels_end = std::min(309, column_);
pixel_target_ += 4; if(output_column_ < pixels_end) {
column_ ++; while(output_column_ < pixels_end) { // TODO: modes other than text
pixel_target_[0] = pixel_target_[1] = pixel_target_[2] = pixel_target_[3] = 0xff;
pixel_target_ += 4;
output_column_ ++;
}
if(output_column_ == 309) {
crt_->output_data(240, 1); // TODO: modes other than text
}
}
} }
if(column_ == 309 && end_column > 309) { if(column_ == 342) {
crt_->output_data(240, 1); // TODO: modes other than text
}
if(end_column == 342) {
crt_->output_blank(static_cast<unsigned int>(342 - 309)); crt_->output_blank(static_cast<unsigned int>(342 - 309));
} }
} else if(row_ >= 227 && row_ < 230) { // TODO: don't hard-code NTSC. } else if(row_ >= 227 && row_ < 230) { // TODO: don't hard-code NTSC.
// Vertical sync. // Vertical sync.
crt_->output_sync(static_cast<unsigned int>(cycles_left)); if(column_ == 342) {
crt_->output_sync(static_cast<unsigned int>(342));
}
} else { } else {
// Blank. // Blank.
if(column_ < 26 && end_column >= 26) { if(!output_column_ && column_ >= 26) {
crt_->output_sync(static_cast<unsigned int>(26)); crt_->output_sync(static_cast<unsigned int>(26));
column_ = 26; output_column_ = 26;
} }
if(column_ < end_column) { if(column_ == 342) {
crt_->output_blank(static_cast<unsigned int>(end_column - column_)); crt_->output_blank(static_cast<unsigned int>(342 - 26));
column_ = end_column;
} }
} }
int_cycles -= cycles_left; int_cycles -= cycles_left;
column_ = end_column;
if(column_ == 342) { if(column_ == 342) {
column_ = 0; column_ = output_column_ = 0;
row_ = (row_ + 1) % 262; // TODO: don't hard-code NTSC. row_ = (row_ + 1) % 262; // TODO: don't hard-code NTSC.
// TODO: consider triggering an interrupt here. // TODO: consider triggering an interrupt here.
} }

View File

@ -68,7 +68,7 @@ class TMS9918 {
void reevaluate_interrupts(); void reevaluate_interrupts();
int column_ = 0, row_ = 0; int column_ = 0, row_ = 0, output_column_ = 0;
int cycles_error_ = 0; int cycles_error_ = 0;
uint8_t *pixel_target_ = nullptr; uint8_t *pixel_target_ = nullptr;
}; };