From ade8df7217162c7ac1fd3e7631a8a65059bcb5c6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 18 Nov 2019 22:12:24 -0500 Subject: [PATCH] Permits a delay on DE propagation back to the CPU. Plus tests. Currently set at 28 cycles, but I don't know. --- Machines/Atari/ST/Video.cpp | 44 ++++++++++++------- .../Clock Signal.xcodeproj/project.pbxproj | 4 ++ .../xcschemes/Clock Signal.xcscheme | 2 +- .../AtariStaticAnalyserTests.mm | 6 +-- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Machines/Atari/ST/Video.cpp b/Machines/Atari/ST/Video.cpp index 3c0ed64a7..cc659b6bc 100644 --- a/Machines/Atari/ST/Video.cpp +++ b/Machines/Atari/ST/Video.cpp @@ -87,6 +87,8 @@ struct Checker { } checker; #endif +const int de_delay_period = 28*2; + } Video::Video() : @@ -117,7 +119,7 @@ void Video::run_for(HalfCycles duration) { int duration_remaining = integer_duration; while(erase_iterator != pending_events_.end()) { erase_iterator->delay -= duration_remaining; - if(erase_iterator->delay < 0) { + if(erase_iterator->delay <= 0) { duration_remaining = -erase_iterator->delay; erase_iterator->apply(public_state_); ++erase_iterator; @@ -249,7 +251,7 @@ void Video::run_for(HalfCycles duration) { // Chuck any deferred output changes into the queue. const bool next_display_enable = vertical_.enable && horizontal_.enable; if(display_enable != next_display_enable) { - add_event(28*2 - integer_duration, next_display_enable ? Event::Type::SetDisplayEnable : Event::Type::ResetDisplayEnable); + add_event(de_delay_period - integer_duration, next_display_enable ? Event::Type::SetDisplayEnable : Event::Type::ResetDisplayEnable); } } } @@ -278,7 +280,7 @@ bool Video::vsync() { } bool Video::display_enabled() { - return horizontal_.enable && vertical_.enable; + return public_state_.display_enable; } HalfCycles Video::get_next_sequence_point() { @@ -300,26 +302,34 @@ HalfCycles Video::get_next_sequence_point() { const auto horizontal_timings = horizontal_parameters(field_frequency_); - // If this is a vertically-enabled line, check for the display enable boundaries. + int event_time = line_length_; // Worst case: report end of line. + + // If any events are pending, give the first of those the chance to be next. + if(!pending_events_.empty()) { + event_time = std::min(event_time, x_ + event_time); + } + + // If this is a vertically-enabled line, check for the display enable boundaries, + the standard delay. if(vertical_.enable) { - /* - TODO: what if there's a sync event scheduled for this line? That can happen with the - lower border open. - */ - if(x_ < horizontal_timings.set_enable) return HalfCycles(horizontal_timings.set_enable - x_); - if(x_ < horizontal_timings.reset_enable) return HalfCycles(horizontal_timings.reset_enable - x_); - } else { - if(vertical_.sync_schedule != VerticalState::SyncSchedule::None && (x_ < 30*2)) { - return HalfCycles(30*2 - x_); + if(x_ < horizontal_timings.set_enable + de_delay_period) { + event_time = std::min(event_time, horizontal_timings.set_enable + de_delay_period); + } + else if(x_ < horizontal_timings.reset_enable + de_delay_period) { + event_time = std::min(event_time, horizontal_timings.reset_enable + de_delay_period); } } - // Test for beginning and end of sync. - if(x_ < line_length_ - 50) return HalfCycles(line_length_ - 50 - x_); - if(x_ < line_length_ - 10) return HalfCycles(line_length_ - 10 - x_); + // If a vertical sync event is scheduled, test for that. + if(vertical_.sync_schedule != VerticalState::SyncSchedule::None && (x_ < 30*2)) { + event_time = std::min(event_time, 30*2); + } + + // Test for beginning and end of horizontal sync. + if(x_ < line_length_ - 50*2) event_time = std::min(line_length_ - 50*2, event_time); + else if(x_ < line_length_ - 10*2) event_time = std::min(line_length_ - 10*2, event_time); // It wasn't any of those, so as a temporary expedient, just supply end of line. - return HalfCycles(line_length_ - x_); + return HalfCycles(event_time - x_); } // MARK: - IO dispatch diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index e5320b768..04af4156d 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -709,6 +709,7 @@ 4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */; }; 4BE0A3EE237BB170002AB46F /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; }; 4BE0A3EF237BB170002AB46F /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; }; + 4BE34438238389E10058E78F /* AtariSTVideoTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BE34437238389E10058E78F /* AtariSTVideoTests.mm */; }; 4BE76CF922641ED400ACD6FA /* QLTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BE76CF822641ED300ACD6FA /* QLTests.mm */; }; 4BE90FFD22D5864800FB464D /* MacintoshVideoTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BE90FFC22D5864800FB464D /* MacintoshVideoTests.mm */; }; 4BE9A6B11EDE293000CBCB47 /* zexdoc.com in Resources */ = {isa = PBXBuildFile; fileRef = 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */; }; @@ -1582,6 +1583,7 @@ 4BE32314205328FF006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; 4BE3231520532AA7006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; 4BE3231620532BED006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; + 4BE34437238389E10058E78F /* AtariSTVideoTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AtariSTVideoTests.mm; sourceTree = ""; }; 4BE76CF822641ED300ACD6FA /* QLTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QLTests.mm; sourceTree = ""; }; 4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = ""; }; 4BE90FFC22D5864800FB464D /* MacintoshVideoTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MacintoshVideoTests.mm; sourceTree = ""; }; @@ -3138,6 +3140,7 @@ 4BB73EB51B587A5100552FC2 /* Clock SignalTests */ = { isa = PBXGroup; children = ( + 4BE34437238389E10058E78F /* AtariSTVideoTests.mm */, 4B85322922778E4200F26553 /* Comparative68000.hpp */, 4B90467222C6FA31000E2074 /* TestRunner68000.hpp */, 4B97ADC722C6FD9B00A22A41 /* 68000ArithmeticTests.mm */, @@ -4492,6 +4495,7 @@ 4BD388882239E198002D14B5 /* 68000Tests.mm in Sources */, 4BA91E1D216D85BA00F79557 /* MasterSystemVDPTests.mm in Sources */, 4B98A0611FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm in Sources */, + 4BE34438238389E10058E78F /* AtariSTVideoTests.mm in Sources */, 4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */, 4BE76CF922641ED400ACD6FA /* QLTests.mm in Sources */, 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */, diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index 1465a4f62..47f9c7286 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -67,7 +67,7 @@ #include "../../../Analyser/Static/StaticAnalyser.hpp" -#include "../../../Analyser/Static/Atari/Target.hpp" +#include "../../../Analyser/Static/Atari2600/Target.hpp" -using PagingModel = Analyser::Static::Atari::Target::PagingModel; +using PagingModel = Analyser::Static::Atari2600::Target::PagingModel; @interface AtariROMRecord : NSObject @property(nonatomic, readonly) PagingModel pagingModel; @@ -601,7 +601,7 @@ static NSDictionary *romRecordsBySHA1 = @{ if(!romRecord) continue; // assert equality - Analyser::Static::Atari::Target *atari_target = dynamic_cast(targets.front().get()); + auto *const atari_target = dynamic_cast(targets.front().get()); XCTAssert(atari_target != nullptr); XCTAssert(atari_target->paging_model == romRecord.pagingModel, @"%@; should be %d, is %d", testFile, romRecord.pagingModel, atari_target->paging_model); XCTAssert(atari_target->uses_superchip == romRecord.usesSuperchip, @"%@; should be %@", testFile, romRecord.usesSuperchip ? @"true" : @"false");