diff --git a/main.c b/main.c index 284863d..d767689 100644 --- a/main.c +++ b/main.c @@ -154,7 +154,7 @@ int main(void) { // while(1) { if(mos_input(&cmd, sizeof(cmd)) == 13) { - int err = mos_exec(&cmd); + int err = mos_exec(&cmd, TRUE); if(err > 0) { mos_error(err); } diff --git a/src/mos.c b/src/mos.c index ddc74b9..d630aa1 100644 --- a/src/mos.c +++ b/src/mos.c @@ -171,16 +171,17 @@ UINT24 mos_input(char * buffer, int bufferLength) { // Returns: // - Function pointer, or 0 if command not found // -void * mos_getCommand(char * ptr) { +t_mosCommand *mos_getCommand(char * ptr) { int i; t_mosCommand * cmd; for(i = 0; i < mosCommands_count; i++) { cmd = &mosCommands[i]; if(mos_cmp(cmd->name, ptr) == 0) { - return cmd->func; + //return cmd->func; + return cmd; } } - return 0; + return NULL; } // Case insensitive commpare with abbreviations @@ -329,18 +330,20 @@ BOOL mos_parseString(char * ptr, char ** p_Value) { // Returns: // - MOS error code // -int mos_exec(char * buffer) { +int mos_exec(char * buffer, BOOL in_mos) { char * ptr; int fr = 0; int (*func)(char * ptr); char path[256]; UINT8 mode; + t_mosCommand *cmd; ptr = mos_trim(buffer); ptr = mos_strtok(ptr, " "); if(ptr != NULL) { - func = mos_getCommand(ptr); - if(func != 0) { + cmd = mos_getCommand(ptr); + func = cmd->func; + if(cmd != NULL && func != 0) { fr = func(ptr); } else { @@ -363,7 +366,48 @@ int mos_exec(char * buffer) { fr = 21; break; } + return fr; } + + if (in_mos) { + + sprintf(path, "%s.bin", ptr); + fr = mos_LOAD(path, MOS_defaultLoadAddress, 0); + if(fr == 0) { + mode = mos_execMode((UINT8 *)MOS_defaultLoadAddress); + switch(mode) { + case 0: // Z80 mode + fr = exec16(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + case 1: // ADL mode + fr = exec24(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + default: // Unrecognised header + fr = 21; + break; + } + return fr; + } + + sprintf(path, "/bin/%s.bin", ptr); + fr = mos_LOAD(path, MOS_defaultLoadAddress, 0); + if(fr == 0) { + mode = mos_execMode((UINT8 *)MOS_defaultLoadAddress); + switch(mode) { + case 0: // Z80 mode + fr = exec16(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + case 1: // ADL mode + fr = exec24(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + default: // Unrecognised header + fr = 21; + break; + } + return fr; + } + + } else { if(fr == 4) { fr = 20; @@ -1024,7 +1068,7 @@ UINT24 mos_BOOT(char * filename, char * buffer, UINT24 size) { if(fr == FR_OK) { while(!f_eof(&fil)) { f_gets(buffer, size, &fil); - mos_exec(buffer); + mos_exec(buffer, TRUE); } } f_close(&fil); @@ -1210,7 +1254,7 @@ void mos_GETERROR(UINT8 errno, UINT24 address, UINT24 size) { // UINT24 mos_OSCLI(char * cmd) { UINT24 fr; - fr = mos_exec(cmd); + fr = mos_exec(cmd, FALSE); return fr; } diff --git a/src/mos.h b/src/mos.h index 0a7f7dc..14697a1 100644 --- a/src/mos.h +++ b/src/mos.h @@ -53,12 +53,12 @@ void mos_error(int error); BYTE mos_getkey(void); UINT24 mos_input(char * buffer, int bufferLength); -void * mos_getCommand(char * ptr); +t_mosCommand *mos_getCommand(char * ptr); BOOL mos_cmp(char *p1, char *p2); char * mos_trim(char * s); char * mos_strtok(char *s1, char * s2); char * mos_strtok_r(char *s1, const char *s2, char **ptr); -int mos_exec(char * buffer); +int mos_exec(char * buffer, BOOL in_mos); UINT8 mos_execMode(UINT8 * ptr); int mos_mount(void); diff --git a/src/mos_editor.c b/src/mos_editor.c index 9d06c95..d3c1d6f 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -326,6 +326,148 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { } } } break; + + case 0x09: { // Tab + char *search_term; + char *path; + + FRESULT fr; + DIR dj; + FILINFO fno; + t_mosCommand *cmd; + const char *searchTermStart; + const char *lastSpace = strrchr(buffer, ' '); + const char *lastSlash = strrchr(buffer, '/'); + + if (lastSlash == NULL && lastSpace == NULL) { //Try commands first before fatfs completion + + search_term = (char*) malloc(strlen(buffer) + 6); + + strcpy(search_term, buffer); + strcat(search_term, "."); + + cmd = mos_getCommand(search_term); + if (cmd != NULL) { //First try internal MOS commands + + printf("%s ", cmd->name + strlen(buffer)); + strcat(buffer, cmd->name + strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + + } + + strcpy(search_term, buffer); + strcat(search_term, "*.bin"); + fr = f_findfirst(&dj, &fno, "/mos/", search_term); + if (fr == FR_OK && fno.fname[0]) { //Now try MOSlets + + printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); + strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + + } + + //Try local .bin + fr = f_findfirst(&dj, &fno, "", search_term); + if ((fr == FR_OK && fno.fname[0])) { + printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); + strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + } + + //Otherwise try /bin/ + fr = f_findfirst(&dj, &fno, "/bin/", search_term); + if ((fr == FR_OK && fno.fname[0])) { + printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); + strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + } + + + } + + if (lastSlash != NULL) { + int pathLength = 1; + + if (lastSpace != NULL && lastSlash > lastSpace) { + pathLength = lastSlash - lastSpace; // Path starts after the last space and includes the slash + } + if (lastSpace == NULL) { + lastSpace = buffer; + pathLength = lastSlash - lastSpace; + + } + + path = (char*) malloc(pathLength + 1); // +1 for null terminator + if (path == NULL) { + break; + } + strncpy(path, lastSpace + 1, pathLength); // Start after the last space + path[pathLength] = '\0'; // Null-terminate the string + + // Determine the start of the search term + searchTermStart = lastSlash + 1; + if (lastSpace != NULL && lastSpace > lastSlash) { + searchTermStart = lastSpace + 1; + } + search_term = (char*) malloc(strlen(searchTermStart) + 2); // +2 for '*' and null terminator + } else { + + path = (char*) malloc(1); + if (path == NULL) { + break; + } + path[0] = '\0'; // Path is empty (current dir, essentially). + + searchTermStart = lastSpace ? lastSpace + 1 : buffer; + search_term = (char*) malloc(strlen(searchTermStart) + 2); // +2 for '*' and null terminator + } + + if (search_term == NULL) { + free(path); + break; + } + + strcpy(search_term, lastSpace && lastSlash > lastSpace ? lastSlash + 1 : lastSpace ? lastSpace + 1 : buffer); + strcat(search_term, "*"); + + //printf("Path:\"%s\" Pattern:\"%s\"\r\n", path, search_term); + fr = f_findfirst(&dj, &fno, path, search_term); + + if (fr == FR_OK && fno.fname[0]) { + + if (fno.fattrib & AM_DIR) printf("%s/", fno.fname + strlen(search_term) - 1); + else printf("%s", fno.fname + strlen(search_term) - 1); + + strcat(buffer, fno.fname + strlen(search_term) - 1); + if (fno.fattrib & AM_DIR) strcat(buffer, "/"); + + len = strlen(buffer); + insertPos = strlen(buffer); + + } + + // Free the allocated memory + free(search_term); + free(path); + + } break; + case 0x7F: { // Backspace if (deleteCharacter(buffer, insertPos, len)) { insertPos--; diff --git a/src_fatfs/ffconf.h b/src_fatfs/ffconf.h index f9b060b..561a174 100644 --- a/src_fatfs/ffconf.h +++ b/src_fatfs/ffconf.h @@ -39,7 +39,7 @@ / 3: f_lseek() function is removed in addition to 2. */ -#define FF_USE_FIND 0 +#define FF_USE_FIND 1 /* This option switches filtered directory read functions, f_findfirst() and / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */