X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=config_file%2Fconfig_file.c;h=12ba4b4e99955384a09dc5f833f954bc1ec14c63;hb=f415c021c3f5a52909a1bc06552fd323a0869ae6;hp=76d0bb6011e565a53636d56e5e02ac242964f316;hpb=20b1a1fa0b8142b5be8e8dbbbbd6d71a9f2a931e;p=pistorm diff --git a/config_file/config_file.c b/config_file/config_file.c index 76d0bb6..12ba4b4 100644 --- a/config_file/config_file.c +++ b/config_file/config_file.c @@ -1,8 +1,12 @@ -#include "../platforms/platforms.h" +// SPDX-License-Identifier: MIT + +#include "platforms/platforms.h" #include #include #include +#include "rominfo.h" + #define M68K_CPU_TYPES M68K_CPU_TYPE_SCC68070 const char *cpu_types[M68K_CPU_TYPES] = { @@ -23,6 +27,7 @@ const char *map_type_names[MAPTYPE_NUM] = { "rom", "ram", "register", + "ram (no alloc)", }; const char *config_item_names[CONFITEM_NUM] = { @@ -34,6 +39,7 @@ const char *config_item_names[CONFITEM_NUM] = { "keyboard", "platform", "setvar", + "kbfile", }; const char *mapcmd_names[MAPCMD_NUM] = { @@ -45,6 +51,8 @@ const char *mapcmd_names[MAPCMD_NUM] = { "file", "ovl", "id", + "autodump_file", + "autodump_mem", }; int get_config_item_type(char *cmd) { @@ -60,12 +68,12 @@ int get_config_item_type(char *cmd) { unsigned int get_m68k_cpu_type(char *name) { for (int i = 0; i < M68K_CPU_TYPES; i++) { if (strcmp(name, cpu_types[i]) == 0) { - printf("Set CPU type to %s.\n", cpu_types[i]); + printf("[CFG] Set CPU type to %s.\n", cpu_types[i]); return i + 1; } } - printf ("Invalid CPU type %s specified, defaulting to 68000.\n", name); + printf("[CFG] Invalid CPU type %s specified, defaulting to 68000.\n", name); return M68K_CPU_TYPE_68000; } @@ -118,7 +126,7 @@ unsigned int get_int(char *str) { case 'M': ret_int = ret_int * SIZE_MEGA; break; case 'G': ret_int = ret_int * SIZE_GIGA; break; default: - printf("Unknown character %c in hex value.\n", str[i]); + printf("[CFG] Unknown character %c in hex value.\n", str[i]); break; } } @@ -139,7 +147,7 @@ unsigned int get_int(char *str) { } void get_next_string(char *str, char *str_out, int *strpos, char separator) { - int str_pos = 0, out_pos = 0; + int str_pos = 0, out_pos = 0, startquote = 0, endstring = 0; if (!str_out) return; @@ -147,19 +155,36 @@ void get_next_string(char *str, char *str_out, int *strpos, char separator) { if (strpos) str_pos = *strpos; - while (str[str_pos] == ' ' && str[str_pos] == '\t' && str_pos < (int)strlen(str)) { + while ((str[str_pos] == ' ' || str[str_pos] == '\t') && str_pos < (int)strlen(str)) { + str_pos++; + } + + if (str[str_pos] == '\"') { str_pos++; + startquote = 1; } + for (int i = str_pos; i < (int)strlen(str); i++) { str_out[out_pos] = str[i]; - if ((separator == ' ' && (str[i] == ' ' || str[i] == '\t')) || str[i] == separator) { + + if (startquote) { + if (str[i] == '\"') + endstring = 1; + } else { + if ((separator == ' ' && (str[i] == ' ' || str[i] == '\t')) || str[i] == separator) { + endstring = 1; + } + } + + if (endstring) { str_out[out_pos] = '\0'; if (strpos) { *strpos = i + 1; } break; } + out_pos++; if (i + 1 == (int)strlen(str) && strpos) { *strpos = i + 1; @@ -168,7 +193,7 @@ void get_next_string(char *str, char *str_out, int *strpos, char separator) { } } -void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int addr, unsigned int size, int mirr_addr, char *filename, char *map_id) { +void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int addr, unsigned int size, int mirr_addr, char *filename, char *map_id, unsigned int autodump) { unsigned int index = 0, file_size = 0; FILE *in = NULL; @@ -178,7 +203,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad index++; } if (index == MAX_NUM_MAPPED_ITEMS) { - printf("Unable to map item, only %d items can be mapped with current binary.\n", MAX_NUM_MAPPED_ITEMS); + printf("[CFG] Unable to map item, only %d items can be mapped with current binary.\n", MAX_NUM_MAPPED_ITEMS); return; } @@ -193,11 +218,15 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad } switch(type) { + case MAPTYPE_RAM_NOALLOC: + printf("[CFG] Adding %d byte (%d MB) RAM mapping %s...\n", size, size / 1024 / 1024, map_id); + cfg->map_data[index] = (unsigned char *)filename; + break; case MAPTYPE_RAM: - printf("Allocating %d bytes for RAM mapping (%d MB)...\n", size, size / 1024 / 1024); + printf("[CFG] Allocating %d bytes for RAM mapping (%d MB)...\n", size, size / 1024 / 1024); cfg->map_data[index] = (unsigned char *)malloc(size); if (!cfg->map_data[index]) { - printf("ERROR: Unable to allocate memory for mapped RAM!\n"); + printf("[CFG] ERROR: Unable to allocate memory for mapped RAM!\n"); goto mapping_failed; } memset(cfg->map_data[index], 0x00, size); @@ -205,32 +234,56 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad case MAPTYPE_ROM: in = fopen(filename, "rb"); if (!in) { - printf("Failed to open file %s for ROM mapping.\n", filename); - goto mapping_failed; + if (!autodump) { + printf("[CFG] Failed to open file %s for ROM mapping. Using onboard ROM instead, if available.\n", filename); + goto mapping_failed; + } else if (autodump == MAPCMD_AUTODUMP_FILE) { + printf("[CFG] Could not open file %s for ROM mapping. Autodump flag is set, dumping to file.\n", filename); + dump_range_to_file(cfg->map_offset[index], cfg->map_size[index], filename); + in = fopen(filename, "rb"); + if (in == NULL) { + printf("[CFG] Could not open dumped file for reading. Using onboard ROM instead, if available.\n"); + goto mapping_failed; + } + } else if (autodump == MAPCMD_AUTODUMP_MEM) { + printf("[CFG] Could not open file %s for ROM mapping. Autodump flag is set, dumping to memory.\n", filename); + cfg->map_data[index] = dump_range_to_memory(cfg->map_offset[index], cfg->map_size[index]); + cfg->rom_size[index] = cfg->map_size[index]; + if (cfg->map_data[index] == NULL) { + printf("[CFG] Could not dump range to memory. Using onboard ROM instead, if available.\n"); + goto mapping_failed; + } + goto skip_file_ops; + } } fseek(in, 0, SEEK_END); file_size = (int)ftell(in); if (size == 0) { cfg->map_size[index] = file_size; + cfg->map_high[index] = addr + cfg->map_size[index]; } fseek(in, 0, SEEK_SET); cfg->map_data[index] = (unsigned char *)calloc(1, cfg->map_size[index]); cfg->rom_size[index] = (cfg->map_size[index] <= file_size) ? cfg->map_size[index] : file_size; if (!cfg->map_data[index]) { - printf("ERROR: Unable to allocate memory for mapped ROM!\n"); + printf("[CFG] ERROR: Unable to allocate memory for mapped ROM!\n"); goto mapping_failed; } memset(cfg->map_data[index], 0x00, cfg->map_size[index]); fread(cfg->map_data[index], cfg->rom_size[index], 1, in); - fclose(in); + if (in) + fclose(in); +skip_file_ops: + displayRomInfo(cfg->map_data[index], cfg->rom_size[index]); + if (cfg->map_size[index] == cfg->rom_size[index]) + m68k_add_rom_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]); break; case MAPTYPE_REGISTER: default: break; - break; } - printf("[MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_offset[index] + cfg->map_size[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None"); + printf("[CFG] [MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_high[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None"); return; @@ -240,10 +293,48 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad fclose(in); } +void free_config_file(struct emulator_config *cfg) { + if (!cfg) { + printf("[CFG] Tried to free NULL config, aborting.\n"); + } + + if (cfg->platform) { + cfg->platform->shutdown(cfg); + free(cfg->platform); + cfg->platform = NULL; + } + + for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) { + if (cfg->map_data[i]) { + if (cfg->map_type[i] != MAPTYPE_RAM_NOALLOC) { + free(cfg->map_data[i]); + } + cfg->map_data[i] = NULL; + } + if (cfg->map_id[i]) { + free(cfg->map_id[i]); + cfg->map_id[i] = NULL; + } + } + + if (cfg->mouse_file) { + free(cfg->mouse_file); + cfg->mouse_file = NULL; + } + if (cfg->keyboard_file) { + free(cfg->keyboard_file); + cfg->keyboard_file = NULL; + } + + m68k_clear_ranges(); + + printf("[CFG] Config file freed. Maybe.\n"); +} + struct emulator_config *load_config_file(char *filename) { FILE *in = fopen(filename, "rb"); if (in == NULL) { - printf("Failed to open config file %s for reading.\n", filename); + printf("[CFG] Failed to open config file %s for reading.\n", filename); return NULL; } @@ -254,12 +345,12 @@ struct emulator_config *load_config_file(char *filename) { parse_line = (char *)calloc(1, 512); if (!parse_line) { - printf("Failed to allocate memory for config file line buffer.\n"); + printf("[CFG] Failed to allocate memory for config file line buffer.\n"); return NULL; } cfg = (struct emulator_config *)calloc(1, sizeof(struct emulator_config)); if (!cfg) { - printf("Failed to allocate memory for temporary emulator config.\n"); + printf("[CFG] Failed to allocate memory for temporary emulator config.\n"); goto load_failed; } @@ -275,7 +366,7 @@ struct emulator_config *load_config_file(char *filename) { goto skip_line; trim_whitespace(parse_line); - + get_next_string(parse_line, cur_cmd, &str_pos, ' '); switch (get_config_item_type(cur_cmd)) { @@ -283,8 +374,8 @@ struct emulator_config *load_config_file(char *filename) { cfg->cpu_type = get_m68k_cpu_type(parse_line + str_pos); break; case CONFITEM_MAP: { - unsigned int maptype = 0, mapsize = 0, mapaddr = 0; - int mirraddr = -1; + unsigned int maptype = 0, mapsize = 0, mapaddr = 0, autodump = 0; + unsigned int mirraddr = ((unsigned int)-1); char mapfile[128], mapid[128]; memset(mapfile, 0x00, 128); memset(mapid, 0x00, 128); @@ -328,18 +419,22 @@ struct emulator_config *load_config_file(char *filename) { get_next_string(parse_line, cur_cmd, &str_pos, ' '); mirraddr = get_int(cur_cmd); break; + case MAPCMD_AUTODUMP_FILE: + case MAPCMD_AUTODUMP_MEM: + autodump = get_map_cmd(cur_cmd); + break; default: - printf("Unknown/unhandled map argument %s on line %d.\n", cur_cmd, cur_line); + printf("[CFG] Unknown/unhandled map argument %s on line %d.\n", cur_cmd, cur_line); break; } } - add_mapping(cfg, maptype, mapaddr, mapsize, mirraddr, mapfile, mapid); + add_mapping(cfg, maptype, mapaddr, mapsize, mirraddr, mapfile, mapid, autodump); break; } case CONFITEM_LOOPCYCLES: cfg->loop_cycles = get_int(parse_line + str_pos); - printf("Set CPU loop cycles to %d.\n", cfg->loop_cycles); + printf("[CFG] Set CPU loop cycles to %d.\n", cfg->loop_cycles); break; case CONFITEM_MOUSE: get_next_string(parse_line, cur_cmd, &str_pos, ' '); @@ -347,20 +442,37 @@ struct emulator_config *load_config_file(char *filename) { strcpy(cfg->mouse_file, cur_cmd); get_next_string(parse_line, cur_cmd, &str_pos, ' '); cfg->mouse_toggle_key = cur_cmd[0]; + get_next_string(parse_line, cur_cmd, &str_pos, ' '); + cfg->mouse_autoconnect = (strcmp(cur_cmd, "autoconnect") == 0) ? 1 : 0; cfg->mouse_enabled = 1; - printf("Enabled mouse event forwarding from file %s, toggle key %c.\n", cfg->mouse_file, cfg->mouse_toggle_key); + printf("[CFG] Enabled mouse event forwarding from file %s, toggle key %c.\n", cfg->mouse_file, cfg->mouse_toggle_key); break; case CONFITEM_KEYBOARD: get_next_string(parse_line, cur_cmd, &str_pos, ' '); cfg->keyboard_toggle_key = cur_cmd[0]; - printf("Enabled keyboard event forwarding, toggle key %c.\n", cfg->keyboard_toggle_key); + get_next_string(parse_line, cur_cmd, &str_pos, ' '); + cfg->keyboard_grab = (strcmp(cur_cmd, "grab") == 0) ? 1 : 0; + get_next_string(parse_line, cur_cmd, &str_pos, ' '); + cfg->keyboard_autoconnect = (strcmp(cur_cmd, "autoconnect") == 0) ? 1 : 0; + printf("[CFG] Enabled keyboard event forwarding, toggle key %c", cfg->keyboard_toggle_key); + if (cfg->keyboard_grab) + printf(", locking from host when connected"); + if (cfg->keyboard_autoconnect) + printf(", connected to guest at startup"); + printf(".\n"); + break; + case CONFITEM_KBFILE: + get_next_string(parse_line, cur_cmd, &str_pos, ' '); + cfg->keyboard_file = (char *)calloc(1, strlen(cur_cmd) + 1); + strcpy(cfg->keyboard_file, cur_cmd); + printf("[CFG] Set keyboard event source file to %s.\n", cfg->keyboard_file); break; case CONFITEM_PLATFORM: { char platform_name[128], platform_sub[128]; memset(platform_name, 0x00, 128); memset(platform_sub, 0x00, 128); get_next_string(parse_line, platform_name, &str_pos, ' '); - printf("Setting platform to %s", platform_name); + printf("[CFG] Setting platform to %s", platform_name); get_next_string(parse_line, platform_sub, &str_pos, ' '); if (strlen(platform_sub)) printf(" (sub: %s)", platform_sub); @@ -370,7 +482,7 @@ struct emulator_config *load_config_file(char *filename) { } case CONFITEM_SETVAR: { if (!cfg->platform) { - printf("Warning: esetvar used in config file with no platform specified.\n"); + printf("[CFG] Warning: setvar used in config file with no platform specified.\n"); break; } @@ -379,17 +491,17 @@ struct emulator_config *load_config_file(char *filename) { memset(var_value, 0x00, 128); get_next_string(parse_line, var_name, &str_pos, ' '); get_next_string(parse_line, var_value, &str_pos, ' '); - cfg->platform->setvar(var_name, var_value); + cfg->platform->setvar(cfg, var_name, var_value); break; } case CONFITEM_NONE: default: - printf("Unknown config item %s on line %d.\n", cur_cmd, cur_line); + printf("[CFG] Unknown config item %s on line %d.\n", cur_cmd, cur_line); break; } - - skip_line:; + + skip_line: cur_line++; } goto load_successful; @@ -424,3 +536,29 @@ int get_named_mapped_item(struct emulator_config *cfg, char *name) { return -1; } + +int get_mapped_item_by_address(struct emulator_config *cfg, uint32_t address) { + for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) { + if (cfg->map_type[i] == MAPTYPE_NONE || !cfg->map_data[i]) + continue; + else if (address >= cfg->map_offset[i] && address < cfg->map_high[i]) { + if (cfg->map_type[i] == MAPTYPE_RAM || cfg->map_type[i] == MAPTYPE_RAM_NOALLOC || cfg->map_type[i] == MAPTYPE_ROM) + return i; + } + } + + return -1; +} + +uint8_t *get_mapped_data_pointer_by_address(struct emulator_config *cfg, uint32_t address) { + for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) { + if (cfg->map_type[i] == MAPTYPE_NONE || !cfg->map_data[i]) + continue; + else if (address >= cfg->map_offset[i] && address < cfg->map_high[i]) { + if (cfg->map_type[i] == MAPTYPE_RAM || cfg->map_type[i] == MAPTYPE_RAM_NOALLOC || cfg->map_type[i] == MAPTYPE_ROM) + return cfg->map_data[i] + (address - cfg->map_offset[i]); + } + } + + return NULL; +}