diff --git a/build_win_dbg.sh b/build_win_dbg.sh index 7311921a..f730d590 100755 --- a/build_win_dbg.sh +++ b/build_win_dbg.sh @@ -2,8 +2,8 @@ # NOTE: -gdwarf-2 needed for my version of wine to recognize the symbols. -x86_64-w64-mingw32-gcc -Wall -W -Werror \ - -g -gdwarf-2 -o beebjit.exe \ +x86_64-w64-mingw32-gcc -Wall -W -Werror -Wno-error=address-of-packed-member \ + -D__MSVCRT_VERSION__=0x1300 -g -gdwarf-2 -o beebjit.exe \ main.c config.c bbc.c defs_6502.c state.c video.c via.c \ emit_6502.c interp.c inturbo.c state_6502.c sound.c timing.c \ jit_compiler.c cpu_driver.c \ diff --git a/build_win_opt.sh b/build_win_opt.sh index 0b81e091..c3aebca3 100755 --- a/build_win_opt.sh +++ b/build_win_opt.sh @@ -2,8 +2,8 @@ # NOTE: -gdwarf-2 needed for my version of wine to recognize the symbols. -x86_64-w64-mingw32-gcc -Wall -W -Werror \ - -O3 -DNDEBUG -o beebjit.exe \ +x86_64-w64-mingw32-gcc -Wall -W -Werror -Wno-error=address-of-packed-member \ + -O3 -DNDEBUG -D__MSVCRT_VERSION__=0x1300 -o beebjit.exe \ main.c config.c bbc.c defs_6502.c state.c video.c via.c \ emit_6502.c interp.c inturbo.c state_6502.c sound.c timing.c \ jit_compiler.c cpu_driver.c \ diff --git a/main.c b/main.c index 35e39a67..e4ea4ee8 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,7 @@ #include "keyboard.h" #include "log.h" #include "os_channel.h" +#include "os_file.h" #include "os_poller.h" #include "os_sound.h" #include "os_terminal.h" @@ -59,7 +60,6 @@ main_save_frame(const char* p_frames_dir, int main(int argc, const char* argv[]) { int i_args; - size_t read_ret; uint8_t os_rom[k_bbc_rom_size]; uint8_t load_rom[k_bbc_rom_size]; uint32_t i; @@ -129,10 +129,14 @@ main(int argc, const char* argv[]) { uint64_t frame_cycles = 0; uint32_t max_frames = 1; int is_exit_on_max_frames_flag = 0; + char* executable_path = NULL; + char* rom_full_name = NULL; p_opt_flags = util_mallocz(1); p_log_flags = util_mallocz(1); + executable_path = os_file_get_executable_path(); + for (i_args = 1; i_args < argc; ++i_args) { const char* arg = argv[i_args]; int has_1 = 0; @@ -372,10 +376,12 @@ main(int argc, const char* argv[]) { (void) memset(os_rom, '\0', k_bbc_rom_size); (void) memset(load_rom, '\0', k_bbc_rom_size); - read_ret = util_file_read_fully(os_rom_name, os_rom, k_bbc_rom_size); - if (read_ret != k_bbc_rom_size) { + rom_full_name = util_file_name_join(executable_path, os_rom_name); + if (util_file_read_fully(rom_full_name, os_rom, k_bbc_rom_size) != k_bbc_rom_size) { util_bail("can't load OS rom"); } + util_free(rom_full_name); + rom_full_name = NULL; if (terminal_flag) { /* If we're in terminal mode and it appears to be an OS v1.2 MOS ROM, @@ -465,7 +471,10 @@ main(int argc, const char* argv[]) { const char* p_rom_name = rom_names[i]; if (p_rom_name != NULL) { (void) memset(load_rom, '\0', k_bbc_rom_size); - (void) util_file_read_fully(p_rom_name, load_rom, k_bbc_rom_size); + rom_full_name = util_file_name_join(executable_path, p_rom_name); + (void) util_file_read_fully(rom_full_name, load_rom, k_bbc_rom_size); + util_free(rom_full_name); + rom_full_name = NULL; bbc_load_rom(p_bbc, i, load_rom); } if (sideways_ram[i]) { @@ -473,6 +482,9 @@ main(int argc, const char* argv[]) { } } + util_free(executable_path); + executable_path = NULL; + if (load_name != NULL) { state_load(p_bbc, load_name); } diff --git a/os.c b/os.c index c10d9a33..f076a521 100644 --- a/os.c +++ b/os.c @@ -6,6 +6,7 @@ #include "os_alloc_posix.c" #include "os_channel_posix.c" #include "os_fault_posix.c" +#include "os_file_posix.c" #include "os_poller_posix.c" #include "os_terminal_posix.c" #include "os_thread_linux.c" @@ -29,6 +30,7 @@ #include "os_alloc_windows.c" #include "os_channel_windows.c" #include "os_fault_windows.c" +#include "os_file_windows.c" #include "os_poller_windows.c" #include "os_sound_windows.c" #include "os_terminal_windows.c" diff --git a/os_file.h b/os_file.h new file mode 100644 index 00000000..57c7a64f --- /dev/null +++ b/os_file.h @@ -0,0 +1,9 @@ +#ifndef BEEBJIT_OS_FILE_H +#define BEEBJIT_OS_FILE_H + +#include + +char* os_file_get_executable_path(void); +char os_file_get_separator_char(void); + +#endif /* BEEBJIT_OS_FILE_H */ diff --git a/os_file_posix.c b/os_file_posix.c new file mode 100644 index 00000000..3afc8de4 --- /dev/null +++ b/os_file_posix.c @@ -0,0 +1,12 @@ +#include "os_file.h" + + +char* +os_file_get_executable_path(void) { + return NULL; +} + +char +os_file_get_separator_char(void) { + return '/'; +} diff --git a/os_file_windows.c b/os_file_windows.c new file mode 100644 index 00000000..4acdbef5 --- /dev/null +++ b/os_file_windows.c @@ -0,0 +1,25 @@ +#include "os_file.h" +#include + + +char* +os_file_get_executable_path(void) { + char* executable_path = util_malloc(MAX_PATH); + if (GetModuleFileNameA(NULL, executable_path, MAX_PATH) < MAX_PATH) { + char* path_leaf = strrchr(executable_path, '\\'); + if (path_leaf) { + *path_leaf = 0; + } else { + *executable_path = 0; + } + } else { + util_bail("Could not get Win32 executable path"); + } + + return executable_path; +} + +char +os_file_get_separator_char(void) { + return '\\'; +} diff --git a/util.c b/util.c index 46d5312f..3f59bcda 100644 --- a/util.c +++ b/util.c @@ -1,4 +1,5 @@ #include "util.h" +#include "os_file.h" #include #include @@ -58,7 +59,7 @@ util_strdup2(const char* p_str1, const char* p_str2) { util_bail("integer overflow"); } - p_ret = malloc(len + 1); + p_ret = util_malloc(len + 1); (void) memcpy(p_ret, p_str1, len1); (void) memcpy((p_ret + len1), p_str2, len2); p_ret[len] = '\0'; @@ -66,6 +67,19 @@ util_strdup2(const char* p_str1, const char* p_str2) { return p_ret; } +char* +util_strndup(const char *s, size_t n) { + char *p; + size_t n1; + + for (n1 = 0; n1 < n && s[n1] != '\0'; n1++) + continue; + p = util_malloc(n1 + 1); + memcpy(p, s, n1); + p[n1] = '\0'; + return p; +} + struct util_buffer { uint8_t* p_mem; size_t length; @@ -269,10 +283,10 @@ util_file_name_split(char** p_file_name_base, size_t len; const char* p_sep = NULL; const char* p_str = p_full_file_name; + char separator_char = os_file_get_separator_char(); - /* TODO: respect Windows separator? */ while (*p_str != '\0') { - if (*p_str == '/') { + if (*p_str == separator_char) { p_sep = p_str; } p_str++; @@ -284,7 +298,7 @@ util_file_name_split(char** p_file_name_base, } len = (p_sep - p_full_file_name); - *p_file_name_base = strndup(p_full_file_name, len); + *p_file_name_base = util_strndup(p_full_file_name, len); *p_file_name = strdup(p_sep + 1); } @@ -296,11 +310,11 @@ util_file_name_join(const char* p_file_name_base, const char* p_file_name) { return strdup(p_file_name); } - /* TODO: respect Windows separator? */ (void) snprintf(file_name_buf, sizeof(file_name_buf), - "%s/%s", + "%s%c%s", p_file_name_base, + os_file_get_separator_char(), p_file_name); return strdup(&file_name_buf[0]); } diff --git a/util.h b/util.h index 6bfa7c61..7bd3382f 100644 --- a/util.h +++ b/util.h @@ -10,6 +10,7 @@ void* util_mallocz(size_t size); void util_free(void* p); char* util_strdup(const char* p_str); char* util_strdup2(const char* p_str1, const char* p_str2); +char* util_strndup(const char *s, size_t n); /* Buffer. */ struct util_buffer;