diff --git a/file_io.cpp b/file_io.cpp index aeea21b..82aa240 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -517,20 +517,24 @@ int de_cmp(const void *e1, const void *e2) return strcasecmp(de1->d_name, de2->d_name); } -void AdjustDirectory(char *path) +static int get_stmode(const char *path) { sprintf(full_path, "%s/%s", getRootDir(), path); - struct stat64 st; - int ret = stat64(full_path, &st); - if (ret < 0) + return (stat64(full_path, &st) < 0) ? 0 : st.st_mode; +} + +void AdjustDirectory(char *path) +{ + int stmode = get_stmode(path); + if (!stmode) { - printf("AdjustDirectory(stat) path:%s, error: %d.\n", full_path, ret); + printf("AdjustDirectory(stat) path:%s, error.\n", path); path[0] = 0; return; } - if (st.st_mode & S_IFDIR) return; + if (stmode & S_IFDIR) return; char *p = strrchr(path, '/'); if (p) @@ -543,8 +547,10 @@ void AdjustDirectory(char *path) } } -int ScanDirectory(const char* path, int mode, const char *extension, int options, const char *prefix) +int ScanDirectory(char* path, int mode, const char *extension, int options, const char *prefix) { + static char file_name[1024]; + int has_trd = 0; const char *ext = extension; while (*ext) @@ -559,6 +565,28 @@ int ScanDirectory(const char* path, int mode, const char *extension, int options if (mode == SCAN_INIT) { + file_name[0] = 0; + if (get_stmode(path) & S_IFREG) + { + char *p = strrchr(path, '/'); + if (p) + { + strcpy(file_name, p + 1); + *p = 0; + } + else + { + strcpy(file_name, path); + path[0] = 0; + } + } + + if (!(get_stmode(path) & S_IFDIR)) + { + path[0] = 0; + file_name[0] = 0; + } + sprintf(full_path, "%s/%s", getRootDir(), path); printf("Start to scan dir: %s\n", full_path); @@ -652,6 +680,20 @@ int ScanDirectory(const char* path, int mode, const char *extension, int options if (!nDirEntries) return 0; qsort(DirItem, nDirEntries, sizeof(struct dirent), de_cmp); + if (file_name[0]) + { + for (int i = 0; i < nDirEntries; i++) + { + if (!strcmp(file_name, DirItem[i].d_name)) + { + iSelectedEntry = i; + if (iSelectedEntry + (OsdGetSize() / 2) - 1 >= nDirEntries) iFirstEntry = nDirEntries - OsdGetSize(); + else iFirstEntry = iSelectedEntry - (OsdGetSize() / 2) + 1; + if (iFirstEntry < 0) iFirstEntry = 0; + break; + } + } + } return nDirEntries; } else diff --git a/file_io.h b/file_io.h index 27c3dd2..fc93f07 100644 --- a/file_io.h +++ b/file_io.h @@ -71,7 +71,7 @@ int FileSaveConfig(const char *name, void *pBuffer, int size); int FileLoadConfig(const char *name, void *pBuffer, int size); // supply pBuffer = 0 to get the file size without loading void AdjustDirectory(char *path); -int ScanDirectory(const char* path, int mode, const char *extension, int options, const char *prefix = NULL); +int ScanDirectory(char* path, int mode, const char *extension, int options, const char *prefix = NULL); const char *getStorageDir(int dev); const char *getRootDir(); diff --git a/fpga_io.cpp b/fpga_io.cpp index e3e8c00..e2b9cfd 100644 --- a/fpga_io.cpp +++ b/fpga_io.cpp @@ -507,7 +507,7 @@ int fpga_load_rbf(const char *name, const char *cfg) } } close(rbf); - app_restart(); + app_restart(!strcasecmp(name, "menu.rbf") ? NULL : path); return ret; } @@ -612,14 +612,14 @@ char *getappname() return dest; } -void app_restart() +void app_restart(const char *path) { sync(); fpga_core_reset(1); char *appname = getappname(); printf("restarting the %s\n", appname); - execve(appname, NULL, NULL); + execl(appname, appname, path, NULL); printf("Something went wrong. Rebooting...\n"); reboot(0); diff --git a/fpga_io.h b/fpga_io.h index 8a8a0e4..dfc3cdb 100644 --- a/fpga_io.h +++ b/fpga_io.h @@ -31,7 +31,7 @@ int fpga_get_io_version(); int fpga_load_rbf(const char *name, const char *cfg = NULL); void reboot(int cold); -void app_restart(); +void app_restart(const char *path); char *getappname(); #endif diff --git a/main.cpp b/main.cpp index ce72c44..148893c 100644 --- a/main.cpp +++ b/main.cpp @@ -61,6 +61,8 @@ int main(int argc, char *argv[]) printf("Version %s\n\n", version + 5); + if (argc > 1) printf("Core path: %s\n", argv[1]); + if (!is_fpga_ready(1)) { printf("\nGPI[31]==1. FPGA is uninitialized or incompatible core loaded.\n"); @@ -69,7 +71,7 @@ int main(int argc, char *argv[]) } FindStorage(); - user_io_init(); + user_io_init((argc > 1) ? argv[1] : ""); while(1) { diff --git a/menu.cpp b/menu.cpp index e2af6c2..426fb58 100644 --- a/menu.cpp +++ b/menu.cpp @@ -262,12 +262,10 @@ int changeDir(char *dir) return 1; } +// this function displays file selection menu static void SelectFile(const char* pFileExt, unsigned char Options, unsigned char MenuSelect, unsigned char MenuCancel, char chdir, char *prefix = NULL) { - // this function displays file selection menu - printf("%s - %s\n", pFileExt, fs_pFileExt); - AdjustDirectory(SelectedPath); if (strncmp(pFileExt, fs_pFileExt, 12) != 0 || !strlen(SelectedPath) || (Options & (SCAN_ROOT|SCAN_HERE))) // check desired file extension { // if different from the current one go to the root directory and init entry buffer @@ -289,6 +287,10 @@ static void SelectFile(const char* pFileExt, unsigned char Options, unsigned cha Options &= ~(SCAN_ROOT|SCAN_HERE); } } + else + { + AdjustDirectory(SelectedPath); + } printf("pFileExt = %3s\n", pFileExt); strcpy(fs_pFileExt, pFileExt); @@ -799,8 +801,17 @@ void HandleUI(void) case MENU_NONE2: if (menu) { - if (get_key_mod() & (LALT|RALT)) //Alt+Menu - SelectFile("RBF", SCAN_SDIR | SCAN_ROOT, MENU_FIRMWARE_CORE_FILE_SELECTED1, MENU_NONE1, 0); + OsdSetSize(16); + if(!is_menu_core() && (get_key_mod() & (LALT | RALT))) //Alt+Menu + { + strcpy(SelectedPath, get_rbf_dir()); + if (strlen(get_rbf_name())) + { + strcat(SelectedPath,"/"); + strcat(SelectedPath, get_rbf_name()); + } + SelectFile("RBF", SCAN_SDIR | SCAN_HERE, MENU_FIRMWARE_CORE_FILE_SELECTED1, MENU_NONE1, 0); + } else if (user_io_core_type() == CORE_TYPE_MINIMIG2) menustate = MENU_MAIN1; else if (user_io_core_type() == CORE_TYPE_MIST) @@ -826,7 +837,6 @@ void HandleUI(void) } } } - OsdSetSize(16); menusub = 0; OsdClear(); OsdEnable(DISABLE_KEYBOARD); diff --git a/user_io.cpp b/user_io.cpp index 3940b2e..38474fc 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -29,7 +29,7 @@ #include "minimig_hdd.h" #include "brightness.h" -#define BREAK 0x8000 +static char core_path[1024]; uint8_t vol_att = 0; unsigned long vol_set_timeout = 0; @@ -356,10 +356,33 @@ void send_rtc(int type) } } -void user_io_init() +const char* get_rbf_dir() +{ + static char str[1024]; + + const char *root = getRootDir(); + int len = strlen(root); + if (!strlen(core_path) || strncmp(root, core_path, len)) return ""; + + strcpy(str, core_path + len + 1); + char *p = strrchr(str, '/'); + if (!p) return ""; + *p = 0; + return str; +} + +const char* get_rbf_name() +{ + if (!strlen(core_path)) return ""; + char *p = strrchr(core_path, '/'); + if (!p) return core_path; + return p+1; +} + +void user_io_init(const char *path) { char *name; - char mainpath[64]; + static char mainpath[512]; core_name[0] = 0; disable_osd = 0; @@ -367,6 +390,7 @@ void user_io_init() ikbd_init(); tos_config_init(); + strcpy(core_path, path); core_type = (fpga_core_id() & 0xFF); fio_size = fpga_get_fio_size(); io_ver = fpga_get_io_version(); @@ -480,21 +504,29 @@ void user_io_init() if (!user_io_file_tx(mainpath, 0)) { strcpy(name + strlen(name) - 3, "ROM"); - if (!user_io_file_tx(name, 0)) + sprintf(mainpath, "%s/%s", get_rbf_dir(), name); + if (!get_rbf_dir()[0] || !user_io_file_tx(mainpath, 0)) { - sprintf(mainpath, "bootrom/%s", name); - user_io_file_tx(mainpath, 0); + if (!user_io_file_tx(name, 0)) + { + sprintf(mainpath, "bootrom/%s", name); + user_io_file_tx(mainpath, 0); + } } } } - // check if there's a .vhd present + // check if vhd present sprintf(mainpath, "%s/boot.vhd", user_io_get_core_name()); user_io_set_index(0); if (!user_io_file_mount(0, mainpath)) { strcpy(name + strlen(name) - 3, "VHD"); - user_io_file_mount(0, name); + sprintf(mainpath, "%s/%s", get_rbf_dir(), name); + if (!get_rbf_dir()[0] || !user_io_file_mount(0, mainpath)) + { + user_io_file_mount(0, name); + } } } } @@ -996,7 +1028,8 @@ void user_io_send_buttons(char force) { if ((key_map & BUTTON2) && !(map & BUTTON2)) { - fpga_load_rbf("Archie.rbf"); + const char *name = get_rbf_name(); + fpga_load_rbf(name[0] ? name : "Archie.rbf"); } } key_map = map; diff --git a/user_io.h b/user_io.h index d143d25..082ca39 100644 --- a/user_io.h +++ b/user_io.h @@ -171,7 +171,7 @@ typedef struct { uint8_t fifo_stat; // space in cores input fifo } __attribute__((packed)) serial_status_t; -void user_io_init(); +void user_io_init(const char *path); unsigned char user_io_core_type(); char is_minimig(); char is_archie(); @@ -228,4 +228,7 @@ void user_io_rtc_reset(); void parse_video_mode(); int hasAPI1_5(); +const char* get_rbf_dir(); +const char* get_rbf_name(); + #endif // USER_IO_H