diff --git a/MiSTer.ini b/MiSTer.ini index 0a85fd1..b0c9b67 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -8,6 +8,8 @@ hdmi_audio_96k=0 ; set to 1 for 96khz/16bit HDMI audio (48khz/16bit otherw keyrah_mode=0x18d80002 ; VIDPID of keyrah for special code translation (0x23418037 for Arduino Micro) volumectl=0 ; enable audio volume control by multimedia keys vscale_integer=0 ; set to 1 to use only integer vertical scaling +vscale_border=0 ; set vertical border for TVs cutting the upper/bottom parts of screen (1-99) + ; vscale_integer and vscale_border are mutually exclusive! ;bootscreen=0 ; uncomment to disable boot screen of some cores like Minimig. ;mouse_throttle=10 ; 1-100 mouse speed divisor. Useful for very sensitive mouses diff --git a/cfg.cpp b/cfg.cpp index e846e3e..cb4fee7 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -41,6 +41,7 @@ const ini_var_t ini_vars[] = { { "BOOTSCREEN", (void*)(&(cfg.bootscreen)), UINT8, 0, 1, 1 }, { "VOLUMECTL", (void*)(&(cfg.volumectl)), UINT8, 0, 1, 1 }, { "VSCALE_INTEGER", (void*)(&(cfg.vscale_integer)), UINT8, 0, 1, 1 }, + { "VSCALE_BORDER", (void*)(&(cfg.vscale_border)), UINT8, 0, 100, 1 }, }; // mist ini config diff --git a/cfg.h b/cfg.h index 597e473..e62e2b4 100644 --- a/cfg.h +++ b/cfg.h @@ -30,6 +30,7 @@ typedef struct { uint8_t bootscreen; uint8_t volumectl; uint8_t vscale_integer; + uint8_t vscale_border; char video_conf[1024]; } cfg_t; diff --git a/menu.cpp b/menu.cpp index ebd0edb..427c528 100644 --- a/menu.cpp +++ b/menu.cpp @@ -2256,12 +2256,10 @@ void HandleUI(void) /* minimig main menu */ /******************************************************************/ case MENU_MAIN1: - menumask = 0xFF0; // b01110000 Floppy turbo, Harddisk options & Exit. + menumask = 0x1FF0; // b01110000 Floppy turbo, Harddisk options & Exit. OsdSetTitle("Minimig", OSD_ARROW_RIGHT | OSD_ARROW_LEFT); helptext = helptexts[HELPTEXT_MAIN]; - OsdWrite(0, "", 0, 0); - // floppy drive info // We display a line for each drive that's active // in the config file, but grey out any that the FPGA doesn't think are active. @@ -2269,7 +2267,7 @@ void HandleUI(void) for (int i = 0; i < 4; i++) { if (i == config.floppy.drives + 1) - OsdWrite(i+1, " KP +/- to add/remove drives", 0, 1); + OsdWrite(i, " KP +/- to add/remove drives", 0, 1); else { strcpy(s, " dfx: "); @@ -2309,24 +2307,25 @@ void HandleUI(void) } else strcpy(s, ""); - OsdWrite(i+1, s, menusub == i, (i>drives) || (i>config.floppy.drives)); + OsdWrite(i, s, menusub == i, (i>drives) || (i>config.floppy.drives)); } } sprintf(s, " Floppy disk turbo : %s", config.floppy.speed ? "on" : "off"); - OsdWrite(5, s, menusub == 4, 0); - OsdWrite(6, "", 0, 0); + OsdWrite(4, s, menusub == 4, 0); + OsdWrite(5, "", 0, 0); - OsdWrite(7, " Hard disks", menusub == 5, 0); - OsdWrite(8, " Chipset", menusub == 6, 0); - OsdWrite(9, " Memory", menusub == 7, 0); - OsdWrite(10, " Audio & Video", menusub == 8, 0); - OsdWrite(11, "", 0, 0); + OsdWrite(6, " Hard disks", menusub == 5, 0); + OsdWrite(7, " Chipset", menusub == 6, 0); + OsdWrite(8, " Memory", menusub == 7, 0); + OsdWrite(9, " Audio & Video", menusub == 8, 0); + OsdWrite(10, "", 0, 0); - OsdWrite(12, " Save configuration", menusub == 9, 0); - OsdWrite(13, " Load configuration", menusub == 10, 0); - OsdWrite(14, "", 0, 0); + OsdWrite(11, " Save configuration", menusub == 9, 0); + OsdWrite(12, " Load configuration", menusub == 10, 0); + OsdWrite(13, "", 0, 0); + OsdWrite(14, user_io_minimig_get_adjust() ? " Finish screen adjusting" : " Adjust screen position", menusub == 11, 0); - OsdWrite(15, STD_EXIT, menusub == 11, 0); + OsdWrite(15, STD_EXIT, menusub == 12, 0); menustate = MENU_MAIN2; parentstate = MENU_MAIN1; @@ -2400,6 +2399,11 @@ void HandleUI(void) menustate = MENU_LOADCONFIG_1; } else if (menusub == 11) + { + menustate = MENU_NONE1; + user_io_minimig_set_adjust(!user_io_minimig_get_adjust()); + } + else if (menusub == 12) menustate = MENU_NONE1; } else if (c == KEY_BACKSPACE) // eject all floppies diff --git a/releases/MiSTer_20181208 b/releases/MiSTer_20181208 new file mode 100644 index 0000000..8b8e8ec Binary files /dev/null and b/releases/MiSTer_20181208 differ diff --git a/user_io.cpp b/user_io.cpp index 161ca63..55d2a27 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -55,10 +55,12 @@ static unsigned long mouse_timer; #define LED_FREQ 100 // 100 ms static unsigned long led_timer; -char keyboard_leds = 0; -bool caps_status = 0; -bool num_status = 0; -bool scrl_status = 0; +static char keyboard_leds = 0; +static bool caps_status = 0; +static bool num_status = 0; +static bool scrl_status = 0; + +static char minimig_adjust = 0; static uint32_t uart_mode; uint32_t user_io_get_uart_mode() @@ -511,36 +513,28 @@ void user_io_init(const char *path) { if (!strlen(path) || !user_io_file_tx(path, 0, 0, 0, 1)) { - // check for multipart rom - sprintf(mainpath, "%s/boot0.rom", user_io_get_core_name()); - if (!is_cpc_core() && user_io_file_tx(mainpath)) + if (!is_cpc_core()) { - sprintf(mainpath, "%s/boot1.rom", user_io_get_core_name()); - if (user_io_file_tx(mainpath, 0x40)) + // check for multipart rom + for (char i = 0; i < 4; i++) { - sprintf(mainpath, "%s/boot2.rom", user_io_get_core_name()); - if (user_io_file_tx(mainpath, 0x80)) - { - sprintf(mainpath, "%s/boot3.rom", user_io_get_core_name()); - user_io_file_tx(mainpath, 0xC0); - } + sprintf(mainpath, "%s/boot%i.rom", user_io_get_core_name(), i); + user_io_file_tx(mainpath, i<<6); } } - else + + // legacy style of rom + sprintf(mainpath, "%s/boot.rom", user_io_get_core_name()); + if (!user_io_file_tx(mainpath)) { - // legacy style of rom - sprintf(mainpath, "%s/boot.rom", user_io_get_core_name()); - if (!user_io_file_tx(mainpath)) + strcpy(name + strlen(name) - 3, "ROM"); + sprintf(mainpath, "%s/%s", get_rbf_dir(), name); + if (!get_rbf_dir()[0] || !user_io_file_tx(mainpath)) { - strcpy(name + strlen(name) - 3, "ROM"); - sprintf(mainpath, "%s/%s", get_rbf_dir(), name); - if (!get_rbf_dir()[0] || !user_io_file_tx(mainpath)) + if (!user_io_file_tx(name)) { - if (!user_io_file_tx(name)) - { - sprintf(mainpath, "bootrom/%s", name); - user_io_file_tx(mainpath); - } + sprintf(mainpath, "bootrom/%s", name); + user_io_file_tx(mainpath); } } } @@ -824,7 +818,7 @@ static unsigned short kbd_fifo[KBD_FIFO_SIZE]; static unsigned char kbd_fifo_r = 0, kbd_fifo_w = 0; static long kbd_timer = 0; -static void kbd_fifo_minimig_send(unsigned short code) +static void kbd_fifo_minimig_send(uint32_t code) { spi_uio_cmd8((code&OSD) ? UIO_KBD_OSD : UIO_KEYBOARD, code & 0xff); kbd_timer = GetTimer(10); // next key after 10ms earliest @@ -1462,6 +1456,7 @@ static int coldreset_req = 0; static int adjust_video_mode(uint32_t vtime); static uint32_t show_video_info(int force); +static uint32_t res_timer = 0; void user_io_poll() { @@ -2024,7 +2019,6 @@ void user_io_poll() keyboard_leds = leds; } - static uint32_t res_timer = 0; if (!res_timer) { res_timer = GetTimer(1000); @@ -2032,12 +2026,15 @@ void user_io_poll() else if(CheckTimer(res_timer)) { res_timer = GetTimer(500); - uint32_t vtime = show_video_info(0); - if (vtime && cfg.vsync_adjust && !is_menu_core()) + if (!minimig_adjust) { - adjust_video_mode(vtime); - usleep(100000); - show_video_info(1); + uint32_t vtime = show_video_info(0); + if (vtime && cfg.vsync_adjust && !is_menu_core()) + { + adjust_video_mode(vtime); + usleep(100000); + show_video_info(1); + } } } @@ -2081,6 +2078,19 @@ char user_io_user_button() return((!user_io_menu_button() && (fpga_get_buttons() & BUTTON_USR)) ? 1 : 0); } +static void adjust_vsize(char force); +static void store_vsize(); +void user_io_minimig_set_adjust(char n) +{ + if (minimig_adjust & !n) store_vsize(); + minimig_adjust = n; +} + +char user_io_minimig_get_adjust() +{ + return minimig_adjust; +} + static void send_keycode(unsigned short key, int press) { if (core_type == CORE_TYPE_MINIMIG2) @@ -2111,6 +2121,25 @@ static void send_keycode(unsigned short key, int press) } code &= 0xff; + if (minimig_adjust) + { + if (code == 0x44) + { + store_vsize(); + res_timer = 0; + return; + } + + if (code == 0x45) + { + Info("Canceled"); + res_timer = 0; + minimig_adjust = 0; + adjust_vsize(1); + return; + } + code |= OSD; + } // send immediately if possible if (CheckTimer(kbd_timer) && (kbd_fifo_w == kbd_fifo_r)) @@ -2725,10 +2754,12 @@ char* user_io_get_scaler_coeff() return scaler_flt_cfg + 1; } +static char scaler_cfg[128] = { 0 }; + void user_io_set_scaler_flt(int n) { scaler_flt_cfg[0] = (char)n; - FileSaveConfig("scaler.cfg", &scaler_flt_cfg, sizeof(scaler_flt_cfg)); + FileSaveConfig(scaler_cfg, &scaler_flt_cfg, sizeof(scaler_flt_cfg)); spi_uio_cmd8(UIO_SET_FLTNUM, scaler_flt_cfg[0]); spi_uio_cmd(UIO_SET_FLTCOEF); } @@ -2736,14 +2767,15 @@ void user_io_set_scaler_flt(int n) void user_io_set_scaler_coeff(char *name) { strcpy(scaler_flt_cfg + 1, name); - FileSaveConfig("scaler.cfg", &scaler_flt_cfg, sizeof(scaler_flt_cfg)); + FileSaveConfig(scaler_cfg, &scaler_flt_cfg, sizeof(scaler_flt_cfg)); setScaler(); user_io_send_buttons(1); } static void loadScalerCfg() { - if (!FileLoadConfig("scaler.cfg", &scaler_flt_cfg, sizeof(scaler_flt_cfg) - 1) || scaler_flt_cfg[0]>4) + sprintf(scaler_cfg, "%s_scaler.cfg", user_io_get_core_name_ex()); + if (!FileLoadConfig(scaler_cfg, &scaler_flt_cfg, sizeof(scaler_flt_cfg) - 1) || scaler_flt_cfg[0]>4) { memset(scaler_flt_cfg, 0, sizeof(scaler_flt_cfg)); } @@ -2875,9 +2907,119 @@ static int adjust_video_mode(uint32_t vtime) user_io_send_buttons(1); } +typedef struct +{ + uint32_t mode; + uint32_t hpos; + uint32_t vpos; + uint32_t reserved; +} vmode_adjust_t; + +vmode_adjust_t vmodes_adj[64] = { 0 }; + +static void adjust_vsize(char force) +{ + static uint16_t nres = 0; + spi_uio_cmd_cont(UIO_GET_VMODE); + uint16_t res = spi_w(0); + if ((res & 0x8000) && (nres != res || force)) + { + nres = res; + uint16_t scr_hsize = spi_w(0); + uint16_t scr_vsize = spi_w(0); + DisableIO(); + + printf("\033[1;37mVMODE: resolution: %u x %u, mode: %u\033[0m\n", scr_hsize, scr_vsize, res & 255); + + static int loaded = 0; + if (~loaded) + { + FileLoadConfig("minimig_vadjust.dat", vmodes_adj, sizeof(vmodes_adj)); + loaded = 1; + } + + uint32_t mode = scr_hsize | (scr_vsize << 12) | ((res & 0xFF) << 24); + if (mode) + { + int applied = 0; + int empty = -1; + for (int i = 0; i < sizeof(vmodes_adj) / sizeof(vmodes_adj[0]); i++) + { + if (vmodes_adj[i].mode == mode) + { + spi_uio_cmd_cont(UIO_SET_VPOS); + spi_w(vmodes_adj[i].hpos >> 16); + spi_w(vmodes_adj[i].hpos); + spi_w(vmodes_adj[i].vpos >> 16); + spi_w(vmodes_adj[i].vpos); + printf("\033[1;37mVMODE: set positions: [%u-%u, %u-%u]\033[0m\n", vmodes_adj[i].hpos >> 16, (uint16_t)vmodes_adj[i].hpos, vmodes_adj[i].vpos >> 16, (uint16_t)vmodes_adj[i].vpos); + DisableIO(); + return; + } + } + printf("\033[1;37mVMODE: preset not found.\033[0m\n"); + spi_uio_cmd_cont(UIO_SET_VPOS); spi_w(0); spi_w(0); spi_w(0); spi_w(0); + DisableIO(); + } + } + else + { + DisableIO(); + } +} + +static void store_vsize() +{ + Info("Stored"); + minimig_adjust = 0; + + spi_uio_cmd_cont(UIO_GET_VMODE); + uint16_t res = spi_w(0); + uint16_t scr_hsize = spi_w(0); + uint16_t scr_vsize = spi_w(0); + uint16_t scr_hbl_l = spi_w(0); + uint16_t scr_hbl_r = spi_w(0); + uint16_t scr_vbl_t = spi_w(0); + uint16_t scr_vbl_b = spi_w(0); + DisableIO(); + + printf("\033[1;37mVMODE: store position: [%u-%u, %u-%u]\033[0m\n", scr_hbl_l, scr_hbl_r, scr_vbl_t, scr_vbl_b); + + uint32_t mode = scr_hsize | (scr_vsize << 12) | ((res & 0xFF) << 24); + if (mode) + { + int applied = 0; + int empty = -1; + for (int i = 0; i < sizeof(vmodes_adj) / sizeof(vmodes_adj[0]); i++) + { + if (vmodes_adj[i].mode == mode) + { + vmodes_adj[i].hpos = (scr_hbl_l << 16) | scr_hbl_r; + vmodes_adj[i].vpos = (scr_vbl_t << 16) | scr_vbl_b; + applied = 1; + } + if (empty < 0 && !vmodes_adj[i].mode) empty = i; + } + + if (!applied && empty >= 0) + { + vmodes_adj[empty].mode = mode; + vmodes_adj[empty].hpos = (scr_hbl_l << 16) | scr_hbl_r; + vmodes_adj[empty].vpos = (scr_vbl_t << 16) | scr_vbl_b; + applied = 1; + } + + if (applied) + { + FileSaveConfig("minimig_vadjust.dat", vmodes_adj, sizeof(vmodes_adj)); + } + } +} + static int api1_5 = 0; static uint32_t show_video_info(int force) { + uint32_t ret = 0; static uint8_t nres = 0; spi_uio_cmd_cont(UIO_GET_VRES); uint8_t res = spi_in(); @@ -2916,7 +3058,15 @@ static uint32_t show_video_info(int force) Info(str, cfg.video_info * 1000); } - if (cfg.vscale_integer && height && (height <= vitems[5])) + if (cfg.vscale_border && height && (height <= vitems[5])) + { + uint32_t border = cfg.vscale_border * 2; + if ((border + 100) > vitems[5]) border = vitems[5] - 100; + height = vitems[5] - border; + printf("Set vertical scaling to : %d\n", height); + spi_uio_cmd16(UIO_SETHEIGHT, height); + } + else if (cfg.vscale_integer && height && (height <= vitems[5])) { uint32_t mag = vitems[5] / height; height *= mag; @@ -2928,13 +3078,14 @@ static uint32_t show_video_info(int force) spi_uio_cmd16(UIO_SETHEIGHT, 0); } - if (vtime && vtimeh) return vtime; + if (vtime && vtimeh) ret = vtime; } else { DisableIO(); } + adjust_vsize(0); return 0; } diff --git a/user_io.h b/user_io.h index c31e69a..0eaf22e 100644 --- a/user_io.h +++ b/user_io.h @@ -64,6 +64,8 @@ #define UIO_GET_STATUS 0x29 // Update status from the core #define UIO_SET_FLTCOEF 0x2A // Set Scaler polyphase coefficients #define UIO_SET_FLTNUM 0x2B // Set Scaler predefined filter +#define UIO_GET_VMODE 0x2C // Get video mode parameters +#define UIO_SET_VPOS 0x2D // Set video positions // codes as used by 8bit for file loading from OSD #define UIO_FILE_TX 0x53 @@ -241,6 +243,9 @@ char* user_io_get_scaler_coeff(); void user_io_set_scaler_flt(int n); void user_io_set_scaler_coeff(char *name); +void user_io_minimig_set_adjust(char n); +char user_io_minimig_get_adjust(); + #define HomeDir (is_minimig() ? "Amiga" : is_archie() ? "Archie" : user_io_get_core_name()) #endif // USER_IO_H