diff --git a/src/core/exception_handler.c b/src/core/exception_handler.c index a608e624..15c371f8 100644 --- a/src/core/exception_handler.c +++ b/src/core/exception_handler.c @@ -57,7 +57,7 @@ void exception_handler_remove(struct exception_handler *handler) { } } -int exception_handler_handle(struct exception *ex) { +int exception_handler_handle(struct exception_state *ex) { list_for_each_entry(handler, &live_handlers, struct exception_handler, it) { if (handler->cb(handler->data, ex)) { return 1; diff --git a/src/core/exception_handler.h b/src/core/exception_handler.h index deebacc0..0288348c 100644 --- a/src/core/exception_handler.h +++ b/src/core/exception_handler.h @@ -3,10 +3,10 @@ #include -struct exception; +struct exception_state; struct exception_handler; -typedef int (*exception_handler_cb)(void *data, struct exception *ex); +typedef int (*exception_handler_cb)(void *, struct exception_state *); enum exception_type { EX_ACCESS_VIOLATION, @@ -21,7 +21,7 @@ union thread_state { uint64_t r[17]; }; -struct exception { +struct exception_state { enum exception_type type; uintptr_t fault_addr; uintptr_t pc; @@ -34,6 +34,6 @@ void exception_handler_uninstall_platform(); struct exception_handler *exception_handler_add(void *data, exception_handler_cb cb); void exception_handler_remove(struct exception_handler *handler); -int exception_handler_handle(struct exception *ex); +int exception_handler_handle(struct exception_state *ex); #endif diff --git a/src/core/exception_handler_linux.c b/src/core/exception_handler_linux.c index 87f53835..8db63cc9 100644 --- a/src/core/exception_handler_linux.c +++ b/src/core/exception_handler_linux.c @@ -49,7 +49,7 @@ static void signal_handler(int signo, siginfo_t *info, void *ctx) { ucontext_t *uctx = ctx; /* convert signal to internal exception */ - struct exception ex; + struct exception_state ex; ex.type = signo == SIGSEGV ? EX_ACCESS_VIOLATION : EX_INVALID_INSTRUCTION; ex.fault_addr = (uintptr_t)info->si_addr; ex.pc = uctx->uc_mcontext.gregs[REG_RIP]; diff --git a/src/core/exception_handler_mac.c b/src/core/exception_handler_mac.c index b6124d83..e0748570 100644 --- a/src/core/exception_handler_mac.c +++ b/src/core/exception_handler_mac.c @@ -86,7 +86,7 @@ kern_return_t catch_exception_raise(mach_port_t exception_port, } /* convert mach exception to internal exception */ - struct exception ex; + struct exception_state ex; ex.type = exception == EXC_BAD_ACCESS ? EX_ACCESS_VIOLATION : EX_INVALID_INSTRUCTION; ex.fault_addr = exc_state.__faultvaddr; diff --git a/src/core/exception_handler_win.c b/src/core/exception_handler_win.c index 3c8741d8..a0bff245 100644 --- a/src/core/exception_handler_win.c +++ b/src/core/exception_handler_win.c @@ -48,7 +48,7 @@ static LONG CALLBACK exception_handler(PEXCEPTION_POINTERS ex_info) { } /* convert signal to internal exception */ - struct exception ex; + struct exception_state ex; ex.type = code == STATUS_ACCESS_VIOLATION ? EX_ACCESS_VIOLATION : EX_INVALID_INSTRUCTION; ex.fault_addr = ex_info->ExceptionRecord->ExceptionInformation[1]; diff --git a/src/core/math.h b/src/core/math.h index 98c45f91..c6fca74e 100644 --- a/src/core/math.h +++ b/src/core/math.h @@ -2,6 +2,7 @@ #define REDREAM_MATH_H #include +#include #include #define MIN(a, b) (((a) < (b)) ? (a) : (b)) diff --git a/src/core/memory.c b/src/core/memory.c index be421111..91c5f81d 100644 --- a/src/core/memory.c +++ b/src/core/memory.c @@ -26,7 +26,7 @@ struct memory_watcher { static struct memory_watcher *watcher; -static int watcher_handle_exception(void *ctx, struct exception *ex); +static int watcher_handle_exception(void *ctx, struct exception_state *ex); static void watcher_create() { watcher = calloc(1, sizeof(struct memory_watcher)); @@ -47,7 +47,7 @@ static void watcher_destroy() { watcher = NULL; } -static int watcher_handle_exception(void *ctx, struct exception *ex) { +static int watcher_handle_exception(void *ctx, struct exception_state *ex) { int handled = 0; struct interval_tree_it it; diff --git a/src/core/memory.h b/src/core/memory.h index 321dcf9d..6514d244 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -3,7 +3,7 @@ #include -struct exception; +struct exception_state; /* * page protection @@ -43,7 +43,7 @@ enum memory_watch_type { WATCH_SINGLE_WRITE, }; -typedef void (*memory_watch_cb)(const struct exception *, void *); +typedef void (*memory_watch_cb)(const struct exception_state *, void *); struct memory_watch *add_single_write_watch(const void *ptr, size_t size, memory_watch_cb cb, void *data); diff --git a/src/emulator.c b/src/emulator.c index 6e25f337..0447166b 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -151,7 +151,7 @@ static void emu_dirty_modified_textures(struct emu *emu) { list_clear(&emu->modified_textures); } -static void emu_texture_modified(const struct exception *ex, void *data) { +static void emu_texture_modified(const struct exception_state *ex, void *data) { struct emu_texture *tex = data; tex->texture_watch = NULL; @@ -161,7 +161,7 @@ static void emu_texture_modified(const struct exception *ex, void *data) { } } -static void emu_palette_modified(const struct exception *ex, void *data) { +static void emu_palette_modified(const struct exception_state *ex, void *data) { struct emu_texture *tex = data; tex->palette_watch = NULL; diff --git a/src/hw/aica/aica.c b/src/hw/aica/aica.c index a906c997..a5329de4 100644 --- a/src/hw/aica/aica.c +++ b/src/hw/aica/aica.c @@ -1,7 +1,7 @@ -#include #include "hw/aica/aica.h" #include "core/filesystem.h" #include "core/log.h" +#include "core/math.h" #include "core/option.h" #include "core/profiler.h" #include "dreamcast.h" diff --git a/src/hw/pvr/tr.c b/src/hw/pvr/tr.c index bd05fae3..4762c571 100644 --- a/src/hw/pvr/tr.c +++ b/src/hw/pvr/tr.c @@ -1,8 +1,7 @@ -#include -#include #include "hw/pvr/tr.h" #include "core/assert.h" #include "core/core.h" +#include "core/math.h" #include "core/profiler.h" #include "core/sort.h" #include "hw/pvr/pixel_convert.h" diff --git a/src/hw/rom/boot.c b/src/hw/rom/boot.c index fda0e28f..02669f26 100644 --- a/src/hw/rom/boot.c +++ b/src/hw/rom/boot.c @@ -1,16 +1,14 @@ -#include #include "hw/rom/boot.h" +#include "core/filesystem.h" #include "core/md5.h" #include "core/option.h" #include "dreamcast.h" DEFINE_OPTION_STRING(bios, "dc_boot.bin", "Path to boot rom"); -#define BIOS_SIZE 0x00200000 - struct boot { struct device; - uint8_t rom[BIOS_SIZE]; + uint8_t rom[0x00200000]; }; static uint32_t boot_rom_read(struct boot *boot, uint32_t addr, @@ -29,7 +27,7 @@ static int boot_validate(struct boot *boot) { /* compare the rom's md5 against known good bios roms */ MD5_CTX md5_ctx; MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, boot->rom, BIOS_SIZE); + MD5_Update(&md5_ctx, boot->rom, sizeof(boot->rom)); char result[33]; MD5_Final(result, &md5_ctx); @@ -42,8 +40,10 @@ static int boot_validate(struct boot *boot) { return 0; } -static int boot_load_rom(struct boot *boot, const char *path) { - FILE *fp = fopen(path, "rb"); +static int boot_load_rom(struct boot *boot) { + const char *filename = OPTION_bios; + + FILE *fp = fopen(filename, "rb"); if (!fp) { return 0; } @@ -52,8 +52,9 @@ static int boot_load_rom(struct boot *boot, const char *path) { int size = ftell(fp); fseek(fp, 0, SEEK_SET); - if (size != BIOS_SIZE) { - LOG_WARNING("Boot rom size mismatch, is %d, expected %d", size, BIOS_SIZE); + if (size != (int)sizeof(boot->rom)) { + LOG_WARNING("boot rom size mismatch, is %d, expected %d", size, + sizeof(boot->rom)); fclose(fp); return 0; } @@ -63,7 +64,18 @@ static int boot_load_rom(struct boot *boot, const char *path) { fclose(fp); if (!boot_validate(boot)) { - LOG_WARNING("Invalid BIOS file"); + LOG_WARNING("invalid BIOS file"); + return 0; + } + + return 1; +} + +static int boot_init(struct device *dev) { + struct boot *boot = (struct boot *)dev; + + if (!boot_load_rom(boot)) { + LOG_WARNING("failed to load boot rom"); return 0; } @@ -74,22 +86,10 @@ void boot_destroy(struct boot *boot) { dc_destroy_device((struct device *)boot); } -static int boot_init(struct device *dev) { - struct boot *boot = (struct boot *)dev; - - if (!boot_load_rom(boot, OPTION_bios)) { - LOG_WARNING("Failed to load boot rom"); - return 0; - } - - return 1; -} - struct boot *boot_create(struct dreamcast *dc) { struct boot *boot = dc_create_device(dc, sizeof(struct boot), "boot", &boot_init); return boot; - ; } /* clang-format off */ diff --git a/src/hw/rom/flash.c b/src/hw/rom/flash.c index b0911b1b..7ec52719 100644 --- a/src/hw/rom/flash.c +++ b/src/hw/rom/flash.c @@ -1,16 +1,14 @@ -/* there doesn't seem to be any documentation on the flash rom used by the - dreamcast, but it appears to implement the JEDEC CFI standard */ - #include #include "hw/rom/flash.h" #include "core/filesystem.h" #include "core/option.h" #include "dreamcast.h" -DEFINE_OPTION_STRING(flash, "dc_flash.bin", "Path to flash rom"); - #define FLASH_SIZE 0x00020000 #define FLASH_SECTOR_SIZE 0x4000 + +/* there doesn't seem to be any documentation on the flash rom used by the + dreamcast, but it appears to implement the JEDEC CFI standard */ #define FLASH_CMD_NONE 0x0 #define FLASH_CMD_ERASE 0x80 #define FLASH_CMD_ERASE_CHIP 0x10 @@ -19,12 +17,15 @@ DEFINE_OPTION_STRING(flash, "dc_flash.bin", "Path to flash rom"); struct flash { struct device; + + uint8_t rom[FLASH_SIZE]; + /* cmd parsing state */ int cmd; int cmd_state; }; -const char *flash_bin_path() { +static const char *flash_bin_path() { static char filename[PATH_MAX]; if (!filename[0]) { @@ -36,93 +37,65 @@ const char *flash_bin_path() { return filename; } -static void flash_read_bin(int offset, void *buffer, int size) { - const char *flash_path = flash_bin_path(); - FILE *file = fopen(flash_path, "rb"); - CHECK_NOTNULL(file, "Failed to open %s", flash_path); - int r = fseek(file, offset, SEEK_SET); - CHECK_NE(r, -1); - r = (int)fread(buffer, 1, size, file); - CHECK_EQ(r, size); - fclose(file); -} - -static void flash_write_bin(int offset, const void *buffer, int size) { - const char *flash_path = flash_bin_path(); - FILE *file = fopen(flash_path, "r+b"); - CHECK_NOTNULL(file, "Failed to open %s", flash_path); - int r = fseek(file, offset, SEEK_SET); - CHECK_NE(r, -1); - r = (int)fwrite(buffer, 1, size, file); - CHECK_EQ(r, size); - fclose(file); -} - -static int flash_init_bin() { - /* check to see if a persistent flash rom exists in the app directory */ - const char *flash_path = flash_bin_path(); - if (fs_exists(flash_path)) { - return 1; - } - - /* if it doesn't, read the original flash rom from the command line path */ - uint8_t rom[FLASH_SIZE]; - - LOG_INFO("Initializing flash rom from %s", OPTION_flash); - - FILE *src = fopen(OPTION_flash, "rb"); - if (!src) { - LOG_WARNING("Failed to load %s", OPTION_flash); - return 0; - } - - fseek(src, 0, SEEK_END); - int size = ftell(src); - fseek(src, 0, SEEK_SET); - - if (size != FLASH_SIZE) { - LOG_WARNING("Flash size mismatch, is %d, expected %d", size, FLASH_SIZE); - fclose(src); - return 0; - } - - int n = (int)fread(rom, 1, size, src); - CHECK_EQ(n, size); - fclose(src); - - /* and copy it to the app directory */ - FILE *dst = fopen(flash_path, "wb"); - CHECK_NOTNULL("Failed to open %s", flash_path); - int r = (int)fwrite(rom, 1, size, dst); - CHECK_EQ(r, size); - fclose(dst); - - return 1; -} - static uint32_t flash_cmd_read(struct flash *flash, uint32_t addr, uint32_t data_mask) { int size = DATA_SIZE(); uint32_t mem; - flash_read_bin(addr, &mem, size); + flash_read(flash, addr, &mem, size); return mem & data_mask; } +static void flash_save_rom(struct flash *flash) { + const char *filename = flash_bin_path(); + + FILE *fp = fopen(filename, "wb"); + int n = (int)fwrite(flash->rom, 1, sizeof(flash->rom), fp); + CHECK_EQ(n, (int)sizeof(flash->rom)); + fclose(fp); +} + +static int flash_load_rom(struct flash *flash) { + const char *filename = flash_bin_path(); + + FILE *fp = fopen(filename, "rb"); + if (!fp) { + LOG_WARNING("failed to load %s", filename); + return 0; + } + + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if (size != sizeof(flash->rom)) { + LOG_WARNING("flash size mismatch, is %d, expected %d", size, + (int)sizeof(flash->rom)); + fclose(fp); + return 0; + } + + int n = (int)fread(flash->rom, 1, size, fp); + CHECK_EQ(n, size); + fclose(fp); + + return 1; +} + static void flash_cmd_program(struct flash *flash, uint32_t addr, uint32_t data, uint32_t data_mask) { /* programming can only clear bits to 0 */ int size = DATA_SIZE(); uint32_t mem; - flash_read_bin(addr, &mem, size); + flash_read(flash, addr, &mem, size); mem &= data; - flash_write_bin(addr, &mem, size); + flash_write(flash, addr, &mem, size); } static void flash_cmd_erase_chip(struct flash *flash) { /* erasing resets bits to 1 */ uint8_t empty_chip[FLASH_SIZE]; memset(empty_chip, 0xff, sizeof(empty_chip)); - flash_write_bin(0, empty_chip, sizeof(empty_chip)); + flash_write(flash, 0, empty_chip, sizeof(empty_chip)); } static void flash_cmd_erase_sector(struct flash *flash, uint32_t addr) { @@ -132,7 +105,7 @@ static void flash_cmd_erase_sector(struct flash *flash, uint32_t addr) { /* erasing resets bits to 1 */ uint8_t empty_sector[FLASH_SECTOR_SIZE]; memset(empty_sector, 0xff, sizeof(empty_sector)); - flash_write_bin(addr, empty_sector, sizeof(empty_sector)); + flash_write(flash, addr, empty_sector, sizeof(empty_sector)); } static uint32_t flash_rom_read(struct flash *flash, uint32_t addr, @@ -189,7 +162,7 @@ static void flash_rom_write(struct flash *flash, uint32_t addr, uint32_t data, } break; default: - LOG_FATAL("Unexpected flash command state %d", flash->cmd_state); + LOG_FATAL("unexpected flash command state %d", flash->cmd_state); break; } } @@ -197,21 +170,30 @@ static void flash_rom_write(struct flash *flash, uint32_t addr, uint32_t data, static int flash_init(struct device *dev) { struct flash *flash = (struct flash *)dev; - if (!flash_init_bin()) { - LOG_WARNING("Failed to load flash rom"); + if (!flash_load_rom(flash)) { return 0; } return 1; } +void flash_write(struct flash *flash, int offset, const void *data, int size) { + memcpy(&flash->rom[offset], data, size); +} + +void flash_read(struct flash *flash, int offset, void *data, int size) { + memcpy(data, &flash->rom[offset], size); +} + void flash_destroy(struct flash *flash) { + flash_save_rom(flash); dc_destroy_device((struct device *)flash); } struct flash *flash_create(struct dreamcast *dc) { struct flash *flash = dc_create_device(dc, sizeof(struct flash), "flash", &flash_init); + return flash; } diff --git a/src/hw/rom/flash.h b/src/hw/rom/flash.h index c9598400..6510d71c 100644 --- a/src/hw/rom/flash.h +++ b/src/hw/rom/flash.h @@ -1,5 +1,5 @@ -#ifndef FLASH_H -#define FLASH_H +#ifndef FLASHROM_H +#define FLASHROM_H #include "memory.h" @@ -11,4 +11,7 @@ AM_DECLARE(flash_rom_map); struct flash *flash_create(struct dreamcast *dc); void flash_destroy(struct flash *flash); +void flash_read(struct flash *flash, int offset, void *data, int size); +void flash_write(struct flash *flash, int offset, const void *data, int size); + #endif diff --git a/src/hw/sh4/sh4.c b/src/hw/sh4/sh4.c index ad79b188..c83dafca 100644 --- a/src/hw/sh4/sh4.c +++ b/src/hw/sh4/sh4.c @@ -12,7 +12,6 @@ #include "jit/frontend/sh4/sh4_fallback.h" #include "jit/frontend/sh4/sh4_frontend.h" #include "jit/frontend/sh4/sh4_guest.h" -#include "jit/ir/ir.h" #include "jit/jit.h" #include "memory.h" #include "render/imgui.h" diff --git a/src/jit/backend/interp/interp_backend.c b/src/jit/backend/interp/interp_backend.c index 2526e029..3d1e85fb 100644 --- a/src/jit/backend/interp/interp_backend.c +++ b/src/jit/backend/interp/interp_backend.c @@ -42,7 +42,7 @@ static void interp_backend_run_code(struct jit_backend *base, int cycles) { } static int interp_backend_handle_exception(struct jit_backend *base, - struct exception *ex) { + struct exception_state *ex) { return 0; } diff --git a/src/jit/backend/jit_backend.h b/src/jit/backend/jit_backend.h index 6ab4f984..ed445fcb 100644 --- a/src/jit/backend/jit_backend.h +++ b/src/jit/backend/jit_backend.h @@ -3,7 +3,7 @@ #include -struct exception; +struct exception_state; struct ir; struct jit; struct jit_block; @@ -27,7 +27,7 @@ struct jit_backend { void (*reset)(struct jit_backend *); int (*assemble_code)(struct jit_backend *, struct jit_block *, struct ir *); void (*dump_code)(struct jit_backend *, const uint8_t *, int); - int (*handle_exception)(struct jit_backend *, struct exception *); + int (*handle_exception)(struct jit_backend *, struct exception_state *); /* dispatch interface */ void (*run_code)(struct jit_backend *, int); diff --git a/src/jit/backend/x64/x64_backend.cc b/src/jit/backend/x64/x64_backend.cc index 2b426637..62fda04a 100644 --- a/src/jit/backend/x64/x64_backend.cc +++ b/src/jit/backend/x64/x64_backend.cc @@ -500,7 +500,7 @@ static void x64_backend_emit_constants(struct x64_backend *backend) { } static int x64_backend_handle_exception(struct jit_backend *base, - struct exception *ex) { + struct exception_state *ex) { struct x64_backend *backend = container_of(base, struct x64_backend, base); struct jit_guest *guest = backend->base.jit->guest; diff --git a/src/jit/frontend/sh4/sh4_fallback.c b/src/jit/frontend/sh4/sh4_fallback.c index 6d61dd08..8677b1e3 100644 --- a/src/jit/frontend/sh4/sh4_fallback.c +++ b/src/jit/frontend/sh4/sh4_fallback.c @@ -1,7 +1,7 @@ -#include #include "jit/frontend/sh4/sh4_fallback.h" #include "core/assert.h" #include "core/log.h" +#include "core/math.h" #include "jit/frontend/sh4/sh4_context.h" #include "jit/frontend/sh4/sh4_frontend.h" #include "jit/frontend/sh4/sh4_guest.h" diff --git a/src/jit/jit.c b/src/jit/jit.c index bcf335c3..574ceaeb 100644 --- a/src/jit/jit.c +++ b/src/jit/jit.c @@ -334,7 +334,7 @@ void jit_compile_block(struct jit *jit, uint32_t guest_addr) { PROF_LEAVE(); } -static int jit_handle_exception(void *data, struct exception *ex) { +static int jit_handle_exception(void *data, struct exception_state *ex) { struct jit *jit = data; /* see if there is a cached block corresponding to the current pc */