diff --git a/Machines/Oric/Video.cpp b/Machines/Oric/Video.cpp index 79e9dffc9..7e228c38e 100644 --- a/Machines/Oric/Video.cpp +++ b/Machines/Oric/Video.cpp @@ -26,12 +26,27 @@ namespace { VideoOutput::VideoOutput(uint8_t *memory) : ram_(memory), crt_(64*6, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red1Green1Blue1), + frequency_mismatch_warner_(*this), v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition), counter_period_(PAL50Period) { - crt_.set_visible_area(crt_.get_rect_for_area(54, 224, 16 * 6, 40 * 6, 4.0f / 3.0f)); crt_.set_phase_linked_luminance_offset(-1.0f / 8.0f); data_type_ = Outputs::Display::InputDataType::Red1Green1Blue1; crt_.set_input_data_type(data_type_); + crt_.set_delegate(&frequency_mismatch_warner_); + update_crt_frequency(); +} + +void VideoOutput::register_crt_frequency_mismatch() { + crt_is_60Hz_ ^= true; + update_crt_frequency(); +} + +void VideoOutput::update_crt_frequency() { + // Set the proper frequency... + crt_.set_new_display_type(64*6, crt_is_60Hz_ ? Outputs::Display::Type::PAL60 : Outputs::Display::Type::PAL50); + + // ... but also pick an appropriate crop rectangle. + crt_.set_visible_area(crt_.get_rect_for_area(crt_is_60Hz_ ? 26 : 54, 224, 16 * 6, 40 * 6, 4.0f / 3.0f)); } void VideoOutput::set_display_type(Outputs::Display::DisplayType display_type) { @@ -92,8 +107,8 @@ void VideoOutput::set_colour_rom(const std::vector &rom) { } void VideoOutput::run_for(const Cycles cycles) { - // Vertical: 0-39: pixels; otherwise blank; 48-53 sync, 54-56 colour burst - // Horizontal: 0-223: pixels; otherwise blank; 256-259 sync + // Horizontal: 0-39: pixels; otherwise blank; 48-53 sync, 54-56 colour burst. + // Vertical: 0-223: pixels; otherwise blank; 256-259 (50Hz) or 234-238 (60Hz) sync. #define clamp(action) \ if(cycles_run_for <= number_of_cycles) { action; } else cycles_run_for = number_of_cycles; diff --git a/Machines/Oric/Video.hpp b/Machines/Oric/Video.hpp index 68e767ca1..fc4c9e046 100644 --- a/Machines/Oric/Video.hpp +++ b/Machines/Oric/Video.hpp @@ -29,21 +29,27 @@ class VideoOutput { void set_display_type(Outputs::Display::DisplayType display_type); Outputs::Display::ScanStatus get_scaled_scan_status() const; + void register_crt_frequency_mismatch(); + private: uint8_t *ram_; Outputs::CRT::CRT crt_; + Outputs::CRT::CRTFrequencyMismatchWarner frequency_mismatch_warner_; + bool crt_is_60Hz_ = false; - // Counters and limits + void update_crt_frequency(); + + // Counters and limits. int counter_ = 0, frame_counter_ = 0; int v_sync_start_position_, v_sync_end_position_, counter_period_; - // Output target and device + // Output target and device. uint8_t *rgb_pixel_target_; uint32_t *composite_pixel_target_; uint32_t colour_forms_[8]; Outputs::Display::InputDataType data_type_; - // Registers + // Registers. uint8_t ink_, paper_; int character_set_base_address_ = 0xb400; diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index dddb71cdc..84f30480d 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -111,8 +111,10 @@ void CRT::set_brightness(float brightness) { void CRT::set_new_display_type(int cycles_per_line, Outputs::Display::Type displayType) { switch(displayType) { case Outputs::Display::Type::PAL50: + case Outputs::Display::Type::PAL60: scan_target_modals_.intended_gamma = 2.8f; - set_new_timing(cycles_per_line, 312, Outputs::Display::ColourSpace::YUV, 709379, 2500, 5, true); // i.e. 283.7516 colour cycles per line; 2.5 lines = vertical sync. + set_new_timing(cycles_per_line, (displayType == Outputs::Display::Type::PAL50) ? 312 : 262, Outputs::Display::ColourSpace::YUV, 709379, 2500, 5, true); + // i.e. 283.7516 colour cycles per line; 2.5 lines = vertical sync. break; case Outputs::Display::Type::NTSC60: diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index f8b9153eb..8fce41666 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -9,6 +9,7 @@ #ifndef CRT_hpp #define CRT_hpp +#include #include #include #include diff --git a/Outputs/ScanTarget.hpp b/Outputs/ScanTarget.hpp index 030548579..139ddaa15 100644 --- a/Outputs/ScanTarget.hpp +++ b/Outputs/ScanTarget.hpp @@ -18,6 +18,7 @@ namespace Display { enum class Type { PAL50, + PAL60, NTSC60 };