diff --git a/menu.cpp b/menu.cpp index 37ad774..4461de7 100644 --- a/menu.cpp +++ b/menu.cpp @@ -419,76 +419,11 @@ void SelectFile(const char* path, const char* pFileExt, int Options, unsigned ch menustate = MENU_FILE_SELECT1; } -int substrcpy(char *d, const char *s, char idx) -{ - char p = 0; - char *b = d; - - while (*s) - { - if ((p == idx) && *s && (*s != ',')) *d++ = *s; - - if (*s == ',') - { - if (p == idx) break; - p++; - } - - s++; - } - - *d = 0; - return (int)(d - b); -} - #define STD_EXIT " exit" #define STD_BACK " back" #define STD_SPACE_EXIT " SPACE to exit" #define STD_COMBO_EXIT " Ctrl+ESC to exit" -int getOptIdx(char *opt) -{ - if ((opt[1] >= '0') && (opt[1] <= '9')) return opt[1] - '0'; - if ((opt[1] >= 'A') && (opt[1] <= 'V')) return opt[1] - 'A' + 10; - return 0; // basically 0 cannot be valid because used as a reset. Thus can be used as a error. -} - -uint32_t getStatus(char *opt, uint32_t status) -{ - char idx1 = getOptIdx(opt); - char idx2 = getOptIdx(opt + 1); - uint32_t x = (status & (1 << idx1)) ? 1 : 0; - - if (idx2>idx1) { - x = status >> idx1; - x = x & ~(0xffffffff << (idx2 - idx1 + 1)); - } - - return x; -} - -uint32_t setStatus(char *opt, uint32_t status, uint32_t value) -{ - unsigned char idx1 = getOptIdx(opt); - unsigned char idx2 = getOptIdx(opt + 1); - uint32_t x = 1; - - if (idx2>idx1) x = ~(0xffffffff << (idx2 - idx1 + 1)); - x = x << idx1; - - return (status & ~x) | ((value << idx1) & x); -} - -uint32_t getStatusMask(char *opt) -{ - char idx1 = getOptIdx(opt); - char idx2 = getOptIdx(opt + 1); - uint32_t x = 1; - - if (idx2 > idx1) x = ~(0xffffffff << (idx2 - idx1 + 1)); - return x; -} - // conversion table of Amiga keyboard scan codes to ASCII codes static const uint8_t keycode_table[128] = { @@ -1111,13 +1046,13 @@ void HandleUI(void) if (menu_visible > 0) { menu_visible = 0; - video_menu_bg((user_io_status(0, 0) & 0xE) >> 1, 1); + video_menu_bg(user_io_status_get("[3:1]"), 1); OsdMenuCtl(0); } else if (!menu_visible) { menu_visible--; - video_menu_bg((user_io_status(0, 0) & 0xE) >> 1, 2); + video_menu_bg(user_io_status_get("[3:1]"), 2); } } @@ -1128,7 +1063,7 @@ void HandleUI(void) { c = 0; menu_visible = 1; - video_menu_bg((user_io_status(0, 0) & 0xE) >> 1); + video_menu_bg(user_io_status_get("[3:1]")); OsdMenuCtl(1); } } @@ -1153,17 +1088,16 @@ void HandleUI(void) case KEY_F12: menu = true; menu_key_set(KEY_F12 | UPSTROKE); - if(video_fb_state()) video_menu_bg((user_io_status(0, 0) & 0xE) >> 1); + if(video_fb_state()) video_menu_bg(user_io_status_get("[3:1]")); video_fb_enable(0); break; case KEY_F1: if (is_menu() && cfg.fb_terminal) { - unsigned long status = (user_io_status(0, 0)+ 2) & 0xE; - user_io_status(status, 0xE); - FileSaveConfig(user_io_create_config_name(), &status, 4); - video_menu_bg(status >> 1); + user_io_status_set("[3:1]", user_io_status_get("[3:1]") + 1); + user_io_status_save(user_io_create_config_name()); + video_menu_bg(user_io_status_get("[3:1]")); } break; @@ -1659,7 +1593,7 @@ void HandleUI(void) //Hide or Disable flag (small letter - opposite action) while ((p[0] == 'H' || p[0] == 'D' || p[0] == 'h' || p[0] == 'd') && strlen(p) > 2) { - int flg = (hdmask & (1 << getOptIdx(p))) ? 1 : 0; + int flg = (hdmask & (1 << user_io_hd_mask(p + 1))) ? 1 : 0; if (p[0] == 'H') h |= flg; if (p[0] == 'h') h |= (flg ^ 1); if (p[0] == 'D') d |= flg; @@ -1803,13 +1737,9 @@ void HandleUI(void) // check for 'O'ption strings if ((p[0] == 'O') || (p[0] == 'o')) { - int ex = (p[0] == 'o'); - uint32_t status = user_io_status(0, 0, ex); // 0,0 gets status - - //option handled by ARM + //option handled by HPS if (p[1] == 'X') p++; - - uint32_t x = getStatus(p, status); + uint32_t x = user_io_status_get(p + 1, p[0] == 'o'); // get currently active option substrcpy(s, p, 2 + x); @@ -2005,7 +1935,7 @@ void HandleUI(void) //Hide or Disable flag while ((p[0] == 'H' || p[0] == 'D' || p[0] == 'h' || p[0] == 'd') && strlen(p) > 2) { - int flg = (hdmask & (1 << getOptIdx(p))) ? 1 : 0; + int flg = (hdmask & (1 << user_io_hd_mask(p + 1))) ? 1 : 0; if (p[0] == 'H') h |= flg; if (p[0] == 'h') h |= (flg ^ 1); if (p[0] == 'D') d |= flg; @@ -2164,9 +2094,9 @@ void HandleUI(void) p++; } - uint32_t status = user_io_status(0, 0, ex); // 0,0 gets status - uint32_t x = minus ? (getStatus(p, status) - 1) : (getStatus(p, status) + 1); - uint32_t mask = getStatusMask(p); + uint32_t x = user_io_status_get(p + 1, ex); + x = minus ? (x - 1) : (x + 1); + uint32_t mask = user_io_status_mask(p + 1); x &= mask; if (byarm && is_x86() && p[1] == '2') x86_set_fdd_boot(!(x & 1)); @@ -2187,7 +2117,7 @@ void HandleUI(void) if (!strlen(s) || get_arc(s) < 0) x = 0; } - user_io_status(setStatus(p, status, x), 0xffffffff, ex); + user_io_status_set(p + 1, x, ex); if (is_x86() && p[1] == 'A') { @@ -2202,36 +2132,37 @@ void HandleUI(void) } else if (((p[0] == 'T') || (p[0] == 'R') || (p[0] == 't') || (p[0] == 'r')) && select) { + int bit; int ex = (p[0] == 't') || (p[0] == 'r'); - - // determine which status bit is affected - uint32_t mask = 1 << getOptIdx(p); - if (mask == 1 && is_x86()) + if (user_io_status_bits(p + 1, &bit, 0, ex) == 1) { - x86_init(); - ResetUART(); - menustate = MENU_NONE1; - } - else - { - if (is_megacd()) + const char *opt = p + 1; + if (!bit && is_x86()) { - if (mask == 1) mcd_set_image(0, ""); - if (mask == 2) - { - mcd_reset(); - mask = 1; - } + x86_init(); + ResetUART(); + menustate = MENU_NONE1; } + else + { + if (is_megacd()) + { + if (!bit) mcd_set_image(0, ""); + if (bit == 1) + { + mcd_reset(); + opt = "[0]"; + } + } - if (is_pce() && mask == 1) pcecd_reset(); + if (is_pce() && !bit) pcecd_reset(); - uint32_t status = user_io_status(0, 0, ex); + user_io_status_set(opt, 1, ex); + user_io_status_set(opt, 0, ex); - user_io_status(status ^ mask, mask, ex); - user_io_status(status, mask, ex); - menustate = MENU_GENERIC_MAIN1; - if (p[0] == 'R' || p[0] == 'r') menustate = MENU_NONE1; + menustate = MENU_GENERIC_MAIN1; + if (p[0] == 'R' || p[0] == 'r') menustate = MENU_NONE1; + } } } } @@ -2574,9 +2505,8 @@ void HandleUI(void) else { char *filename = user_io_create_config_name(); - uint32_t status[2] = { user_io_status(0, 0, 0), user_io_status(0, 0, 1) }; printf("Saving config to %s\n", filename); - FileSaveConfig(filename, status, 8); + user_io_status_save(filename); if (is_x86()) x86_config_save(); if (is_arcade()) arcade_nvm_save(); } @@ -2918,7 +2848,7 @@ void HandleUI(void) { if (c & UPSTROKE) { - video_menu_bg((user_io_status(0, 0) & 0xE) >> 1); + video_menu_bg(user_io_status_get("[3:1]")); video_fb_enable(0); menustate = MENU_NONE1; menusub = 3; @@ -3009,8 +2939,8 @@ void HandleUI(void) if (!dipv) { arcade_sw_save(dipv); - user_io_status(UIO_STATUS_RESET, UIO_STATUS_RESET); - user_io_status(0, UIO_STATUS_RESET); + user_io_status_set("[0]", 1); + user_io_status_set("[0]", 0); menustate = MENU_NONE1; } else @@ -5139,10 +5069,10 @@ void HandleUI(void) } else { + user_io_status_reset(); char *filename = user_io_create_config_name(); - uint32_t status[2] = { user_io_status(0, 0xffffffff, 0), user_io_status(0, 0xffffffff, 1) }; printf("Saving config to %s\n", filename); - FileSaveConfig(filename, status, 8); + user_io_status_save(filename); menustate = MENU_GENERIC_MAIN1; for (int n = 0; n < 2; n++) { @@ -5150,8 +5080,8 @@ void HandleUI(void) { arcade_sw(n)->dip_cur = arcade_sw(n)->dip_def; arcade_sw_send(n); - user_io_status(UIO_STATUS_RESET, UIO_STATUS_RESET); - user_io_status(0, UIO_STATUS_RESET); + user_io_status_set("[0]", 1); + user_io_status_set("[0]", 0); arcade_sw_save(n); } } @@ -6387,7 +6317,7 @@ void HandleUI(void) { if (c & UPSTROKE) { - video_menu_bg((user_io_status(0, 0) & 0xE) >> 1); + video_menu_bg(user_io_status_get("[3:1]")); video_fb_enable(0); menustate = MENU_SYSTEM1; menusub = 3; diff --git a/menu.h b/menu.h index 19a5960..5f6cb4f 100644 --- a/menu.h +++ b/menu.h @@ -3,7 +3,6 @@ #include - void SelectFile(const char* path, const char* pFileExt, int Options, unsigned char MenuSelect, unsigned char MenuCancel); void HandleUI(void); @@ -17,11 +16,6 @@ void InfoMessage(const char *message, int timeout = 2000, const char *title = "M void Info(const char *message, int timeout = 2000, int width = 0, int height = 0, int frame = 0); void MenuHide(); -int getOptIdx(char *opt); -uint32_t getStatus(char *opt, uint32_t status); -uint32_t getStatusMask(char *opt); -int substrcpy(char *d, const char *s, char idx); - void open_joystick_setup(); int menu_lightgun_cb(int idx, uint16_t type, uint16_t code, int value); diff --git a/support/archie/archie.cpp b/support/archie/archie.cpp index 46e94fd..5ce8fd7 100644 --- a/support/archie/archie.cpp +++ b/support/archie/archie.cpp @@ -81,7 +81,7 @@ void archie_set_ar(char i) { config.system_ctrl &= ~0b11000000; config.system_ctrl |= (i & 3) << 6; - user_io_status(config.system_ctrl, 0b11000000); + user_io_status_set("[7:6]", config.system_ctrl >> 6); } int archie_get_ar() @@ -93,7 +93,7 @@ void archie_set_scale(char i) { config.system_ctrl &= ~0b1100000000; config.system_ctrl |= (i & 3) << 8; - user_io_status(config.system_ctrl, 0b1100000000); + user_io_status_set("[9:8]", config.system_ctrl >> 8); } int archie_get_scale() @@ -103,26 +103,26 @@ int archie_get_scale() void archie_set_60(char i) { - if (i) config.system_ctrl |= 0b1000; - else config.system_ctrl &= ~0b1000; - user_io_status(config.system_ctrl, 0b10000); + if (i) config.system_ctrl |= 0b10000; + else config.system_ctrl &= ~0b10000; + user_io_status_set("[4]", config.system_ctrl >> 4); } int archie_get_60() { - return config.system_ctrl & 0b1000; + return config.system_ctrl & 0b10000; } void archie_set_afix(char i) { - if (i) config.system_ctrl |= 0b10000; - else config.system_ctrl &= ~0b10000; - user_io_status(config.system_ctrl, 0b100000); + if (i) config.system_ctrl |= 0b100000; + else config.system_ctrl &= ~0b100000; + user_io_status_set("[5]", config.system_ctrl >> 5); } int archie_get_afix() { - return config.system_ctrl & 0b10000; + return config.system_ctrl & 0b100000; } static int mswap = 0; @@ -139,7 +139,7 @@ int archie_get_mswap() void archie_set_amix(char i) { config.system_ctrl = (config.system_ctrl & ~0b110) | ((i & 3)<<1); - user_io_status(config.system_ctrl << 1, 0b1100); + user_io_status_set("[3:2]", config.system_ctrl>>1); } int archie_get_amix() @@ -295,7 +295,7 @@ inline int hdd_open(int unit, char *filename) void archie_init() { archie_debugf("init"); - user_io_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_status_set("[0]", 1); // set config defaults config.system_ctrl = 0; @@ -338,7 +338,7 @@ void archie_init() load_cmos(); - user_io_status(~UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_status_set("[0]", 0); /* int i; diff --git a/support/megacd/megacd.cpp b/support/megacd/megacd.cpp index 4ae4d56..f22e48c 100644 --- a/support/megacd/megacd.cpp +++ b/support/megacd/megacd.cpp @@ -124,8 +124,8 @@ void mcd_set_image(int num, const char *filename) { mcd_mount_save(""); - user_io_status(1, 1); - user_io_status(0, 1); + user_io_status_set("[0]", 1); + user_io_status_set("[0]", 0); mcd_reset(); loaded = 0; diff --git a/support/neogeo/neogeo_loader.cpp b/support/neogeo/neogeo_loader.cpp index bc01183..9a4b296 100644 --- a/support/neogeo/neogeo_loader.cpp +++ b/support/neogeo/neogeo_loader.cpp @@ -1043,14 +1043,14 @@ int neogeo_romset_tx(char* name) int system_type; static char full_path[1024]; - system_type = (user_io_status(0, 0) >> 1) & 3; + system_type = user_io_status_get("[2:1]") & 3; printf("System type: %u\n", system_type); spi_uio_cmd_cont(UIO_GET_OSDMASK); uint16_t mask = spi_w(0); DisableIO(); - user_io_status(1, 1); // Maintain reset + user_io_status_set("[0]", 1); // Maintain reset crom_sz_max = 0; crom_start = 0; @@ -1140,7 +1140,7 @@ int neogeo_romset_tx(char* name) FileGenerateSavePath((system_type & 2) ? "ngcd" : name, (char*)full_path); user_io_file_mount((char*)full_path, 0, 1); - user_io_status(0, 1); // Release reset + user_io_status_set("[0]", 0); // Release reset return 1; } diff --git a/support/pcecd/pcecd.cpp b/support/pcecd/pcecd.cpp index 199c191..c8bfc12 100644 --- a/support/pcecd/pcecd.cpp +++ b/support/pcecd/pcecd.cpp @@ -113,9 +113,9 @@ static void notify_mount(int load) if (!load) { - user_io_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_status_set("[0]", 1); usleep(100000); - user_io_status(0, UIO_STATUS_RESET); + user_io_status_set("[0]", 0); } } diff --git a/support/psx/psx.cpp b/support/psx/psx.cpp index 4160598..f628157 100644 --- a/support/psx/psx.cpp +++ b/support/psx/psx.cpp @@ -703,7 +703,7 @@ void psx_mount_cd(int f_index, int s_index, const char *filename) } - if (!(user_io_status(0, 0, 1) >> 31)) psx_mount_save(last_dir); + if (!(user_io_status_get("[63]"))) psx_mount_save(last_dir); } } diff --git a/support/sharpmz/sharpmz.cpp b/support/sharpmz/sharpmz.cpp index 2b81db8..e23b171 100644 --- a/support/sharpmz/sharpmz.cpp +++ b/support/sharpmz/sharpmz.cpp @@ -60,6 +60,27 @@ static sharpmz_tape_header_t tapeHeader; static tape_queue_t tapeQueue; static unsigned char debugEnabled = 0; +static uint32_t set_status(uint32_t new_status, uint32_t mask, int ex = 0) +{ + static uint32_t status[2] = { 0, 0 }; + if (ex) ex = 1; + + // if mask is 0 just return the current status + if (mask) { + // keep everything not masked + status[ex] &= ~mask; + // updated masked bits + status[ex] |= new_status & mask; + + spi_uio_cmd_cont(UIO_SET_STATUS2); + spi32_w(status[0]); + spi32_w(status[1]); + DisableIO(); + } + + return status[ex]; +} + // Method to open a file for writing. // int sharpmz_file_write(fileTYPE *file, const char *fileName) @@ -118,7 +139,7 @@ void sharpmz_reset(unsigned long preResetSleep, unsigned long postResetSleep) // Set the reset bit. // config.system_ctrl |= 1; - user_io_status(config.system_ctrl, (1)); + set_status(config.system_ctrl, (1)); // Sleep and hold device in reset for given period. // @@ -128,7 +149,7 @@ void sharpmz_reset(unsigned long preResetSleep, unsigned long postResetSleep) // Remove reset. // config.system_ctrl &= ~(1); - user_io_status(config.system_ctrl, (1)); + set_status(config.system_ctrl, (1)); // Sleep and hold device in reset for given period. // @@ -204,7 +225,7 @@ int sharpmz_reset_config(short setStatus) // if(setStatus) { - user_io_status(config.system_ctrl, 0xffffffff); + set_status(config.system_ctrl, 0xffffffff); // Set the registers. // @@ -248,7 +269,7 @@ int sharpmz_reload_config(short setStatus) // if(setStatus && success) { - user_io_status(config.system_ctrl, 0xffffffff); + set_status(config.system_ctrl, 0xffffffff); // Set the registers. // @@ -286,7 +307,7 @@ void sharpmz_init(void) // Setup the status values based on the config. // - user_io_status(config.system_ctrl, 0xffffffff); + set_status(config.system_ctrl, 0xffffffff); // Set the control registers according to config. // @@ -797,7 +818,7 @@ void sharpmz_set_aspect_ratio(short on, short setStatus) config.system_ctrl |= (on == 1 ? 1 << 1 : 0); if(setStatus) - user_io_status(config.system_ctrl, (1 << 1)); + set_status(config.system_ctrl, (1 << 1)); } // Return Scan doubler fx status bits. Bits 2,3,4 of systemctrl. @@ -827,7 +848,7 @@ void sharpmz_set_scandoubler_fx(short doubler, short setStatus) config.system_ctrl |= (doubler & 0x07) << 2; if(setStatus) - user_io_status(config.system_ctrl, (0x07 << 2)); + set_status(config.system_ctrl, (0x07 << 2)); } // Return VRAM wait state mode status bit. Bit 6 of system_reg, 0 = Off, 1 = On diff --git a/support/x86/x86.cpp b/support/x86/x86.cpp index a5c9334..c76af68 100644 --- a/support/x86/x86.cpp +++ b/support/x86/x86.cpp @@ -297,7 +297,7 @@ static uint8_t bin2bcd(unsigned val) void x86_init() { - user_io_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_status_set("[0]", 1); const char *home = HomeDir(); @@ -421,7 +421,7 @@ void x86_init() for (unsigned int i = 0; i < sizeof(cmos) / sizeof(cmos[0]); i++) IOWR(RTC_BASE, i, cmos[i]); x86_share_reset(); - user_io_status(0, UIO_STATUS_RESET); + user_io_status_set("[0]", 0); } static void fdd_io(uint8_t read) diff --git a/user_io.cpp b/user_io.cpp index 549b590..e267e2d 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -325,6 +325,137 @@ void user_io_read_core_name() printf("Core name is \"%s\"\n", core_name); } +int substrcpy(char *d, const char *s, char idx) +{ + char p = 0; + char *b = d; + + while (*s) + { + if ((p == idx) && *s && (*s != ',')) *d++ = *s; + + if (*s == ',') + { + if (p == idx) break; + p++; + } + + s++; + } + + *d = 0; + return (int)(d - b); +} + +static char cur_status[16] = {}; + +int user_io_status_bits(const char *opt, int *s, int *e, int ex, int single) +{ + uint32_t start = 0, end = 0; + if (opt[0] == '[') + { + if (!single && sscanf(opt, "[%u:%u]", &end, &start) == 2) + { + if (start > 127 || end > 127 || end <= start) return 0; + } + else if (sscanf(opt, "[%u]", &start) == 1) + { + if (start > 127) return 0; + end = start; + } + else return 0; + } + else + { + if ((opt[0] >= '0') && (opt[0] <= '9')) start = opt[0] - '0'; + else if ((opt[0] >= 'A') && (opt[0] <= 'V')) start = opt[0] - 'A' + 10; + else return 0; + + if (!single && (opt[1] >= '0') && (opt[1] <= '9')) end = opt[1] - '0'; + else if (!single && (opt[1] >= 'A') && (opt[1] <= 'V')) end = opt[1] - 'A' + 10; + else + { + single = 1; + end = start; + } + + if (ex) + { + start += 32; + end += 32; + } + + if (start > 127 || end > 127 || (!single && end <= start)) return 0; + } + + //max 8 bits per option + if (end - start > 8) return 0; + + if (s) *s = (int)start; + if (e) *e = (int)end; + return 1 + end - start; +} + +uint32_t user_io_status_get(const char *opt, int ex) +{ + int start, end; + int size = user_io_status_bits(opt, &start, &end, ex); + if (!size) return 0; + + uint32_t x = (cur_status[end / 8] << 8) | cur_status[start / 8]; + x >>= start % 8; + return x & ~(0xffffffff << size); +} + +uint32_t user_io_status_mask(const char *opt) +{ + return ~(0xffffffff << user_io_status_bits(opt, 0, 0, 0)); +} + +uint32_t user_io_hd_mask(const char *opt) +{ + int start; + int size = user_io_status_bits(opt, &start, 0, 0, 1); + if (!size) return 0; + return start; +} + +void user_io_status_set(const char *opt, uint32_t value, int ex) +{ + int start, end; + int size = user_io_status_bits(opt, &start, &end, ex); + if (!size) return; + + int s = start / 8; + int e = end / 8; + + uint32_t mask = ~(0xffffffff << size); + mask <<= start % 8; + uint32_t x = (cur_status[e] << 8) | cur_status[s]; + x = (x & ~mask) | ((value << (start % 8)) & mask); + + cur_status[s] = (char)x; + if (e != s) cur_status[e] = (char)(x >> 8); + + if (!is_st()) + { + spi_uio_cmd_cont(UIO_SET_STATUS2); + for (uint32_t i = 0; i < sizeof(cur_status); i += 2) spi_w((cur_status[i + 1] << 8) | cur_status[i]); + DisableIO(); + } +} + +int user_io_status_save(const char *filename) +{ + return FileSaveConfig(filename, cur_status, sizeof(cur_status)); +} + +void user_io_status_reset() +{ + memset(cur_status, 0, sizeof(cur_status)); + user_io_status_set("[0]", 0); +} + static void set_kbd_led(int led, int state) { if (led & HID_LED_CAPS_LOCK) @@ -412,8 +543,9 @@ static char defmra[1024] = {}; static void parse_config() { - uint64_t mask = 0; - uint64_t overlap = 0; + char mask[sizeof(cur_status) * 8] = {}; + char overlap[sizeof(cur_status) * 8] = {}; + int start, end, sz; int i = 0; char *p; @@ -552,34 +684,37 @@ static void parse_config() } if (p[0] == 'P') p += 2; - if (p[0] == 'R' || p[0] == 'T') + if (p[0] == 'R' || p[0] == 'T' || p[0] == 'r' || p[0] == 't') { - uint64_t x = 1 << getOptIdx(p); - overlap |= mask & x; - mask |= x; + sz = user_io_status_bits(p + 1, &start, &end, p[0] == 'r' || p[0] == 't'); + if (sz == 1) + { + overlap[start] |= mask[start]; + mask[start] |= 1; + } + else + { + printf("Invalid OSD option: %s\n", p); + } } - if (p[0] == 'r' || p[0] == 't') + else if (p[0] == 'O' || p[0] == 'o') { - uint64_t x = 1 << getOptIdx(p); - x <<= 32; - overlap |= mask & x; - mask |= x; - } - if (p[0] == 'O') - { - char *opt = (p[1] == 'X') ? p + 1 : p; - uint64_t x = getStatusMask(opt); - x <<= getOptIdx(opt); - overlap |= mask & x; - mask |= x; - } - if (p[0] == 'o') - { - char *opt = (p[1] == 'X') ? p + 1 : p; - uint64_t x = getStatusMask(opt); - x <<= 32 + getOptIdx(opt); - overlap |= mask & x; - mask |= x; + char *opt = (p[1] == 'X') ? (p + 2) : (p + 1); + sz = user_io_status_bits(opt, &start, &end, p[0] == 'o'); + if (sz) + { + while (sz) + { + overlap[start] |= mask[start]; + mask[start] |= 1; + sz--; + start++; + } + } + else + { + printf("Invalid OSD option: %s\n", p); + } } if (p[0] == 'J') @@ -598,10 +733,8 @@ static void parse_config() if (p[0] == 'O' && p[1] == 'X') { - uint32_t status = user_io_status(0, 0); - printf("found OX option: %s, 0x%08X\n", p, status); - - unsigned long x = getStatus(p + 1, status); + int x = user_io_status_get(p + 2); + printf("found OX option: %s: %d\n", p, x); if (is_x86()) { @@ -702,7 +835,7 @@ static void parse_config() i++; } while (p || i<3); - mask |= 1; // reset is always on bit 0 + mask[0] = 1; // reset is always on bit 0 printf("\n// Status Bit Map:\n"); printf("// Upper Lower\n"); printf("// 0 1 2 3 4 5 6 \n"); @@ -710,24 +843,59 @@ static void parse_config() printf("// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV\n"); char str[128]; strcpy(str, "// "); - for (int i = 0; i < 32; i++) strcat(str, (mask & (1ULL << i)) ? "X" : " "); + for (int i = 0; i < 32; i++) strcat(str, mask[i] ? "X" : " "); strcat(str, " "); - for (int i = 32; i < 64; i++) strcat(str, (mask & (1ULL << i)) ? "X" : " "); + for (int i = 32; i < 64; i++) strcat(str, mask[i] ? "X" : " "); strcat(str, "\n"); printf(str); - if (overlap) + int ovr = 0; + for (int i = 0; i < 64; i++) ovr |= overlap[i]; + + if (ovr) { strcpy(str, "// "); - for (int i = 0; i < 32; i++) strcat(str, (overlap & (1ULL << i)) ? "^" : " "); + for (int i = 0; i < 32; i++) strcat(str, overlap[i] ? "^" : " "); strcat(str, " "); - for (int i = 32; i < 64; i++) strcat(str, (overlap & (1ULL << i)) ? "^" : " "); + for (int i = 32; i < 64; i++) strcat(str, overlap[i] ? "^" : " "); strcat(str, "\n"); printf(str); - printf("// *Overlapped bits!* (can be intentional):\n"); + printf("// *Overlapped bits!* (can be intentional)\n"); } printf("\n"); + ovr = 0; + for (int i = 64; i < 128; i++) ovr |= mask[i]; + + if (ovr) + { + printf("// 0 0 0 0 1 1 1 \n"); + printf("// 6 7 8 9 0 1 2 \n"); + printf("// 45678901234567890123456789012345 67890123456789012345678901234567\n"); + strcpy(str, "// "); + for (int i = 64; i < 96; i++) strcat(str, mask[i] ? "X" : " "); + strcat(str, " "); + for (int i = 96; i < 128; i++) strcat(str, mask[i] ? "X" : " "); + strcat(str, "\n"); + printf(str); + + ovr = 0; + for (int i = 64; i < 128; i++) ovr |= overlap[i]; + + if (ovr) + { + strcpy(str, "// "); + for (int i = 64; i < 96; i++) strcat(str, overlap[i] ? "^" : " "); + strcat(str, " "); + for (int i = 96; i < 128; i++) strcat(str, overlap[i] ? "^" : " "); + strcat(str, "\n"); + printf(str); + printf("// *Overlapped bits!* (can be intentional)\n"); + } + printf("\n"); + } + + // legacy GBA versions if (is_gba() && !ss_base) { @@ -1096,7 +1264,7 @@ void user_io_init(const char *path, const char *xml) spi_uio_cmd16(UIO_SET_MEMSZ, sdram_sz(-1)); // send a reset - user_io_status(UIO_STATUS_RESET, UIO_STATUS_RESET); + user_io_status_set("[0]", 1); } else if (core_type == CORE_TYPE_SHARPMZ) { @@ -1162,23 +1330,21 @@ void user_io_init(const char *path, const char *xml) name = user_io_create_config_name(); if (strlen(name) > 0) { - uint32_t status[2] = { 0, 0 }; if (!is_st() && !is_minimig()) { printf("Loading config %s\n", name); - if (FileLoadConfig(name, status, 8)) + memset(cur_status, 0, sizeof(cur_status)); + if (FileLoadConfig(name, cur_status, sizeof(cur_status))) { - printf("Found config: %08X-%08X\n", status[0], status[1]); + printf("Found config:\n"); + hexdump(cur_status, sizeof(cur_status)); } else { - status[0] = 0; - status[1] = 0; + memset(cur_status, 0, sizeof(cur_status)); } - status[0] &= ~UIO_STATUS_RESET; - user_io_status(status[0], ~UIO_STATUS_RESET, 0); - user_io_status(status[1], 0xffffffff, 1); + user_io_status_set("[0]", 1); } if (is_st()) @@ -1188,9 +1354,9 @@ void user_io_init(const char *path, const char *xml) } else if (is_menu()) { - user_io_status((cfg.menu_pal) ? 0x10 : 0, 0x10); - if (cfg.fb_terminal) video_menu_bg((status[0] >> 1) & 7); - else user_io_status(0, 0xE); + user_io_status_set("[4]", (cfg.menu_pal) ? 1 : 0); + if (cfg.fb_terminal) video_menu_bg(user_io_status_get("[3:1]")); + else user_io_status_set("[3:1]", 0); } else { @@ -1307,7 +1473,7 @@ void user_io_init(const char *path, const char *xml) send_rtc(3); // release reset - if (!is_minimig() && !is_st()) user_io_status(0, UIO_STATUS_RESET); + if (!is_minimig() && !is_st()) user_io_status_set("[0]", 0); if (xml && isXmlName(xml) == 1) arcade_check_error(); break; } @@ -2104,11 +2270,14 @@ static void check_status_change() if ((stchg & 0xF0) == 0xA0 && last_status_change != (stchg & 0xF)) { last_status_change = (stchg & 0xF); - uint32_t st0 = spi32_w(0); - uint32_t st1 = spi32_w(0); + for (uint i = 0; i < sizeof(cur_status); i += 2) + { + uint16_t x = spi_w(0); + cur_status[i] = (char)x; + cur_status[i + 1] = (char)(x >> 8); + } DisableIO(); - user_io_status(st0, ~UIO_STATUS_RESET, 0); - user_io_status(st1, 0xFFFFFFFF, 1); + user_io_status_set("[0]", 0); } else { @@ -2448,38 +2617,6 @@ char *user_io_get_confstr(int index) return buffer; } -uint32_t user_io_status(uint32_t new_status, uint32_t mask, int ex) -{ - static uint32_t status[2] = { 0, 0 }; - if (ex) ex = 1; - - // if mask is 0 just return the current status - if (mask) { - // keep everything not masked - status[ex] &= ~mask; - // updated masked bits - status[ex] |= new_status & mask; - - if (!is_st()) - { - if (!io_ver) - { - spi_uio_cmd8(UIO_SET_STATUS, status[0]); - spi_uio_cmd32(UIO_SET_STATUS2, status[0], 0); - } - else - { - spi_uio_cmd_cont(UIO_SET_STATUS2); - spi32_w(status[0]); - spi32_w(status[1]); - DisableIO(); - } - } - } - - return status[ex]; -} - static char cur_btn = 0; char user_io_menu_button() { diff --git a/user_io.h b/user_io.h index e730f52..d97bbab 100644 --- a/user_io.h +++ b/user_io.h @@ -153,33 +153,6 @@ #define CORE_TYPE_SHARPMZ 0xa7 // Sharp MZ Series #define CORE_TYPE_8BIT2 0xa8 // generic core using dual SDRAM -#define UART_FLG_PPP 0x0001 -#define UART_FLG_TERM 0x0002 -#define UART_FLG_RTSCTS 0x0004 -#define UART_FLG_DTRDSR 0x0008 -#define UART_FLG_DSRDCD 0x0010 -#define UART_FLG_9600 0x0100 -#define UART_FLG_19200 0x0200 -#define UART_FLG_38400 0x0400 -#define UART_FLG_57600 0x0800 -#define UART_FLG_115200 0x1000 - -// user io status bits (currently only used by 8bit) -#define UIO_STATUS_RESET 0x01 - -#define UIO_STOP_BIT_1 0 -#define UIO_STOP_BIT_1_5 1 -#define UIO_STOP_BIT_2 2 - -#define UIO_PARITY_NONE 0 -#define UIO_PARITY_ODD 1 -#define UIO_PARITY_EVEN 2 -#define UIO_PARITY_MARK 3 -#define UIO_PARITY_SPACE 4 - -#define UIO_PRIORITY_KEYBOARD 0 -#define UIO_PRIORITY_GAMEPAD 1 - #define EMU_NONE 0 #define EMU_MOUSE 1 #define EMU_JOY0 2 @@ -192,12 +165,21 @@ void user_io_poll(); char user_io_menu_button(); char user_io_user_button(); void user_io_osd_key_enable(char); -void user_io_read_confstr(); -char *user_io_get_confstr(int index); -uint32_t user_io_status(uint32_t, uint32_t, int ex = 0); int user_io_get_kbd_reset(); void user_io_set_kbd_reset(int reset); +int substrcpy(char *d, const char *s, char idx); + +void user_io_read_confstr(); +char *user_io_get_confstr(int index); +int user_io_status_bits(const char *opt, int *s, int *e, int ex = 0, int single = 0); +uint32_t user_io_status_mask(const char *opt); +uint32_t user_io_hd_mask(const char *opt); +uint32_t user_io_status_get(const char *opt, int ex = 0); +void user_io_status_set(const char *opt, uint32_t value, int ex = 0); +int user_io_status_save(const char *filename); +void user_io_status_reset(); + uint32_t user_io_get_file_crc(); int user_io_file_mount(const char *name, unsigned char index = 0, char pre = 0, int pre_size = 0); void user_io_bufferinvalidate(unsigned char index); diff --git a/video.cpp b/video.cpp index 0e0d25c..3f8d500 100644 --- a/video.cpp +++ b/video.cpp @@ -1404,7 +1404,7 @@ void video_fb_enable(int enable, int n) DisableIO(); if (cfg.direct_video) set_vga_fb(enable); - if (is_menu()) user_io_status((fb_enabled && !fb_num) ? 0x160 : 0, 0x1E0); + if (is_menu()) user_io_status_set("[8:5]", (fb_enabled && !fb_num) ? 0x160 : 0); } }