1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-07 23:25:00 +00:00

Enables the Oric for 50/60Hz mode switching, inventing PAL60 for the purpose.

This commit is contained in:
Thomas Harte
2020-01-23 22:14:02 -05:00
parent 6802318784
commit 9136917f00
5 changed files with 32 additions and 7 deletions

View File

@@ -26,12 +26,27 @@ namespace {
VideoOutput::VideoOutput(uint8_t *memory) : VideoOutput::VideoOutput(uint8_t *memory) :
ram_(memory), ram_(memory),
crt_(64*6, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red1Green1Blue1), 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), v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition),
counter_period_(PAL50Period) { 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); crt_.set_phase_linked_luminance_offset(-1.0f / 8.0f);
data_type_ = Outputs::Display::InputDataType::Red1Green1Blue1; data_type_ = Outputs::Display::InputDataType::Red1Green1Blue1;
crt_.set_input_data_type(data_type_); 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) { void VideoOutput::set_display_type(Outputs::Display::DisplayType display_type) {
@@ -92,8 +107,8 @@ void VideoOutput::set_colour_rom(const std::vector<uint8_t> &rom) {
} }
void VideoOutput::run_for(const Cycles cycles) { void VideoOutput::run_for(const Cycles cycles) {
// Vertical: 0-39: pixels; otherwise blank; 48-53 sync, 54-56 colour burst // Horizontal: 0-39: pixels; otherwise blank; 48-53 sync, 54-56 colour burst.
// Horizontal: 0-223: pixels; otherwise blank; 256-259 sync // Vertical: 0-223: pixels; otherwise blank; 256-259 (50Hz) or 234-238 (60Hz) sync.
#define clamp(action) \ #define clamp(action) \
if(cycles_run_for <= number_of_cycles) { action; } else cycles_run_for = number_of_cycles; if(cycles_run_for <= number_of_cycles) { action; } else cycles_run_for = number_of_cycles;

View File

@@ -29,21 +29,27 @@ class VideoOutput {
void set_display_type(Outputs::Display::DisplayType display_type); void set_display_type(Outputs::Display::DisplayType display_type);
Outputs::Display::ScanStatus get_scaled_scan_status() const; Outputs::Display::ScanStatus get_scaled_scan_status() const;
void register_crt_frequency_mismatch();
private: private:
uint8_t *ram_; uint8_t *ram_;
Outputs::CRT::CRT crt_; Outputs::CRT::CRT crt_;
Outputs::CRT::CRTFrequencyMismatchWarner<VideoOutput> 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 counter_ = 0, frame_counter_ = 0;
int v_sync_start_position_, v_sync_end_position_, counter_period_; int v_sync_start_position_, v_sync_end_position_, counter_period_;
// Output target and device // Output target and device.
uint8_t *rgb_pixel_target_; uint8_t *rgb_pixel_target_;
uint32_t *composite_pixel_target_; uint32_t *composite_pixel_target_;
uint32_t colour_forms_[8]; uint32_t colour_forms_[8];
Outputs::Display::InputDataType data_type_; Outputs::Display::InputDataType data_type_;
// Registers // Registers.
uint8_t ink_, paper_; uint8_t ink_, paper_;
int character_set_base_address_ = 0xb400; int character_set_base_address_ = 0xb400;

View File

@@ -111,8 +111,10 @@ void CRT::set_brightness(float brightness) {
void CRT::set_new_display_type(int cycles_per_line, Outputs::Display::Type displayType) { void CRT::set_new_display_type(int cycles_per_line, Outputs::Display::Type displayType) {
switch(displayType) { switch(displayType) {
case Outputs::Display::Type::PAL50: case Outputs::Display::Type::PAL50:
case Outputs::Display::Type::PAL60:
scan_target_modals_.intended_gamma = 2.8f; 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; break;
case Outputs::Display::Type::NTSC60: case Outputs::Display::Type::NTSC60:

View File

@@ -9,6 +9,7 @@
#ifndef CRT_hpp #ifndef CRT_hpp
#define CRT_hpp #define CRT_hpp
#include <array>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <memory> #include <memory>

View File

@@ -18,6 +18,7 @@ namespace Display {
enum class Type { enum class Type {
PAL50, PAL50,
PAL60,
NTSC60 NTSC60
}; };