From 0a89c2cd8018ec2705b8afeef25d31efe2aba33a Mon Sep 17 00:00:00 2001 From: sorgelig Date: Tue, 5 Feb 2019 15:07:44 +0800 Subject: [PATCH] Separate PAL/NTSC modes for vsync_adjust. --- MiSTer.ini | 6 +++ cfg.cpp | 2 + cfg.h | 3 +- support/st/st_tos.cpp | 5 +++ user_io.cpp | 102 ++++++++++++++++++++++++------------------ user_io.h | 6 --- 6 files changed, 73 insertions(+), 51 deletions(-) diff --git a/MiSTer.ini b/MiSTer.ini index 12b8e15..0d16ab8 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -53,3 +53,9 @@ video_info=0 ; For proper adjusting and to reduce possible out of range pixel clock, use 60Hz HDMI video ; modes as a base even for 50Hz systems. vsync_adjust=0 + +; These parameters have the same format as video_mode. +; You need to supply both PAL and NTSC modes if you want vsync_adjust to switch between +; predefined modes as a base. This will reduce the range of pixel clock. +;video_mode_ntsc=0 +;video_mode_pal=7 diff --git a/cfg.cpp b/cfg.cpp index bf35bd3..b45cf4b 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -32,6 +32,8 @@ const ini_var_t ini_vars[] = { { "RESET_COMBO", (void*)(&(cfg.reset_combo)), UINT8, 0, 3, 1 }, { "KEY_MENU_AS_RGUI", (void*)(&(cfg.key_menu_as_rgui)), UINT8, 0, 1, 1 }, { "VIDEO_MODE", (void*)(cfg.video_conf), STRING, 0, sizeof(cfg.video_conf)-1, 1 }, + { "VIDEO_MODE_PAL", (void*)(cfg.video_conf_pal), STRING, 0, sizeof(cfg.video_conf_pal) - 1, 1 }, + { "VIDEO_MODE_NTSC", (void*)(cfg.video_conf_ntsc), STRING, 0, sizeof(cfg.video_conf_ntsc) - 1, 1 }, { "VIDEO_INFO", (void*)(&(cfg.video_info)), UINT8, 0, 10, 1 }, { "VSYNC_ADJUST", (void*)(&(cfg.vsync_adjust)), UINT8, 0, 2, 1 }, { "HDMI_AUDIO_96K", (void*)(&(cfg.hdmi_audio_96k)), UINT8, 0, 1, 1 }, diff --git a/cfg.h b/cfg.h index f2cf286..c061ea7 100644 --- a/cfg.h +++ b/cfg.h @@ -22,7 +22,6 @@ typedef struct { uint8_t vga_scaler; uint8_t hdmi_audio_96k; uint8_t dvi; - uint8_t video_mode; uint8_t video_info; uint8_t vsync_adjust; uint8_t kbd_nomouse; @@ -34,6 +33,8 @@ typedef struct { uint8_t rbf_hide_datecode; uint8_t menu_pal; char video_conf[1024]; + char video_conf_pal[1024]; + char video_conf_ntsc[1024]; } cfg_t; //// functions //// diff --git a/support/st/st_tos.cpp b/support/st/st_tos.cpp index 1d9ba66..7d16ab0 100644 --- a/support/st/st_tos.cpp +++ b/support/st/st_tos.cpp @@ -197,6 +197,11 @@ static void dma_nak(void) { DisableFpga(); } +static char user_io_dip_switch1() +{ + return 0; +} + static void handle_acsi(unsigned char *buffer) { static unsigned char asc[2] = { 0,0 }; unsigned char target = buffer[19] >> 5; diff --git a/user_io.cpp b/user_io.cpp index a7cc33c..752a640 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -1432,9 +1432,6 @@ void user_io_send_buttons(char force) static unsigned short key_map = 0; unsigned short map = 0; - map = cfg.video_mode; - map = (map << CONF_RES_SHIFT) & CONF_RES_MASK; - int btn = fpga_get_buttons(); if (btn & BUTTON_OSD) map |= BUTTON1; @@ -2105,11 +2102,6 @@ void user_io_poll() } } -char user_io_dip_switch1() -{ - return 0; -} - char user_io_menu_button() { return((fpga_get_buttons() & BUTTON_OSD) ? 1 : 0); @@ -2631,7 +2623,9 @@ vmode_t vmodes[] = }; #define VMODES_NUM (sizeof(vmodes) / sizeof(vmodes[0])) -static uint32_t vitems[32]; +static uint32_t vitems_cur[32] = {}, vitems_def[32] = {}, vitems_pal[32] = {}, vitems_ntsc[32] = {}; +static int vmode_def = 0, vmode_pal = 0, vmode_ntsc = 0; + double Fpix = 0; static uint32_t getPLLdiv(uint32_t div) @@ -2678,7 +2672,7 @@ static int findPLLpar(double Fout, uint32_t *pc, uint32_t *pm, double *pko) return 0; } -static void setPLL(double Fout) +static void setPLL(double Fout, uint32_t *vitems) { double fvco, ko; uint32_t m, c; @@ -2833,7 +2827,7 @@ static void loadScalerCfg() } } -static void setVideo() +static void setVideo(uint32_t *vitems) { loadScalerCfg(); setScaler(); @@ -2843,14 +2837,16 @@ static void setVideo() printf("video: "); for (int i = 1; i <= 8; i++) { + vitems_cur[i] = vitems[i]; spi_w(vitems[i]); printf("%d, ", vitems[i]); } printf("\nPLL: "); for (int i = 9; i < 21; i++) { + vitems_cur[i] = vitems[i]; printf("0x%X, ", vitems[i]); - if (i & 1) spi_w(vitems[i] | ((i==9 && (is_menu_core() ? cfg.menu_pal : (cfg.vsync_adjust==2))) ? 0x8000 : 0)); + if (i & 1) spi_w(vitems[i] | ((i == 9 && (is_menu_core() ? cfg.menu_pal : (cfg.vsync_adjust == 2))) ? 0x8000 : 0)); else { spi_w(vitems[i]); @@ -2862,12 +2858,11 @@ static void setVideo() DisableIO(); } -static int parse_custom_video_mode() +static int parse_custom_video_mode(char* vcfg, uint32_t *vitems) { - char *vcfg = cfg.video_conf; - int khz = 0; int cnt = 0; + char *orig = vcfg; while (*vcfg) { char *next; @@ -2876,19 +2871,19 @@ static int parse_custom_video_mode() double Fpix = khz ? strtoul(vcfg, &next, 0)/1000.f : strtod(vcfg, &next); if (vcfg == next || (Fpix < 2.f || Fpix > 300.f)) { - printf("Error parsing video_mode parameter: ""%s""\n", cfg.video_conf); - return 0; + printf("Error parsing video_mode parameter: ""%s""\n", orig); + return -1; } - setPLL(Fpix); + setPLL(Fpix, vitems); break; } uint32_t val = strtoul(vcfg, &next, 0); if (vcfg == next || (*next != ',' && *next)) { - printf("Error parsing video_mode parameter: ""%s""\n", cfg.video_conf); - return 0; + printf("Error parsing video_mode parameter: ""%s""\n", orig); + return -1; } if (!cnt && val >= 100) @@ -2911,51 +2906,70 @@ static int parse_custom_video_mode() if ((vitems[0] == 0 && cnt < 21) || (vitems[0] == 1 && cnt < 9)) { printf("Incorrect amount of items in video_mode parameter: %d\n", cnt); - return 0; + return -1; } if (vitems[0] > 1) { printf("Incorrect video_mode parameter\n"); - return 0; + return -1; } - return -1; + return -2; +} + +static int store_custom_video_mode(char* vcfg, uint32_t *vitems) +{ + int ret = parse_custom_video_mode(vcfg, vitems); + if (ret == -2) return 1; + + uint mode = (ret < 0) ? 0 : ret; + if (mode >= VMODES_NUM) mode = 0; + for (int i = 0; i < 8; i++) vitems[i + 1] = vmodes[mode].vpar[i]; + setPLL(vmodes[mode].Fpix, vitems); + + return ret >= 0; } void parse_video_mode() { - // always 0. Use custom parameters. - cfg.video_mode = 0; - - int mode = parse_custom_video_mode(); - if (mode >= 0) - { - if ((uint)mode >= VMODES_NUM) mode = 0; - for (int i = 0; i < 8; i++) - { - vitems[i + 1] = vmodes[mode].vpar[i]; - } - - setPLL(vmodes[mode].Fpix); - } - setVideo(); + vmode_def = store_custom_video_mode(cfg.video_conf, vitems_def); + vmode_pal = store_custom_video_mode(cfg.video_conf_pal, vitems_pal); + vmode_ntsc = store_custom_video_mode(cfg.video_conf_ntsc, vitems_ntsc); + setVideo(vitems_def); } static int adjust_video_mode(uint32_t vtime) { - printf("Adjust VSync(%d).\n", cfg.vsync_adjust); + printf("\033[1;33madjust_video_mode(%u): vsync_adjust=%d", vtime, cfg.vsync_adjust); + + uint32_t *vitems = vitems_def; + if (vmode_pal && vmode_ntsc) + { + if (vtime > 1800000) + { + printf(", using PAL mode"); + vitems = vitems_pal; + } + else + { + printf(", using NTSC mode"); + vitems = vitems_ntsc; + } + } + + printf(".\033[0m\n"); double Fpix = 100 * (vitems[1] + vitems[2] + vitems[3] + vitems[4]) * (vitems[5] + vitems[6] + vitems[7] + vitems[8]); Fpix /= vtime; - if (Fpix < 20.f || Fpix > 200.f) + if (Fpix < 2.f || Fpix > 300.f) { printf("Estimated Fpix(%.4f MHz) is outside supported range. Canceling auto-adjust.\n", Fpix); return 0; } - setPLL(Fpix); - setVideo(); + setPLL(Fpix, vitems); + setVideo(vitems); user_io_send_buttons(1); return 1; } @@ -3105,11 +3119,11 @@ static uint32_t show_video_info(int force) sprintf(str, "%4dx%-4d %6.2fKHz %4.1fHz\n" \ "\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\n" \ "%4dx%-4d %6.2fMHz %4.1fHz", - width, height, hrate, vrate, vitems[1], vitems[5], Fpix, vrateh); + width, height, hrate, vrate, vitems_cur[1], vitems_cur[5], Fpix, vrateh); Info(str, cfg.video_info * 1000); } - uint32_t scrh = vitems[5]; + uint32_t scrh = vitems_cur[5]; if (height && scrh) { if (cfg.vscale_border) diff --git a/user_io.h b/user_io.h index dae4d3e..9a5bb55 100644 --- a/user_io.h +++ b/user_io.h @@ -124,8 +124,6 @@ #define CONF_YPBPR 0b00100000 #define CONF_AUDIO_96K 0b01000000 #define CONF_DVI 0b10000000 -#define CONF_RES_MASK 0x700 -#define CONF_RES_SHIFT 8 // core type value should be unlikely to be returned by broken cores #define CORE_TYPE_UNKNOWN 0x55 @@ -192,7 +190,6 @@ char *user_io_8bit_get_string(char); uint32_t user_io_8bit_set_status(uint32_t, uint32_t); int user_io_file_tx(const char* name, unsigned char index = 0, char opensave = 0, char mute = 0, char composite = 0); int user_io_file_mount(char *name, unsigned char index = 0, char pre = 0); -char user_io_dip_switch1(void); char user_io_serial_status(serial_status_t *, uint8_t); char *user_io_get_core_name(); const char *user_io_get_core_name_ex(); @@ -223,8 +220,6 @@ char user_io_osd_is_visible(); void user_io_send_buttons(char); void parse_video_mode(); -void add_modifiers(uint8_t mod, uint16_t* keys_ps2); - void user_io_set_index(unsigned char index); unsigned char user_io_ext_idx(char *, char*); @@ -232,7 +227,6 @@ void user_io_check_reset(unsigned short modifiers, char useKeys); void user_io_rtc_reset(); -void parse_video_mode(); int hasAPI1_5(); const char* get_rbf_dir();