mirror of https://github.com/inolen/redream.git
rename exception struct to exception_state to resolve collison in <math.h>
don't write out flash modifications until program exit
This commit is contained in:
parent
9328cd3eb5
commit
d106733ee0
|
@ -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;
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define REDREAM_MATH_H
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <math.h>
|
||||
#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"
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
#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"
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
#include <stdio.h>
|
||||
#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 */
|
||||
|
|
|
@ -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 <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <math.h>
|
||||
#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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue