From 4d2ec790b460c4fb10fbea6d96874362007dc5f6 Mon Sep 17 00:00:00 2001 From: Logan McNaughton Date: Tue, 15 Dec 2020 16:59:43 +0000 Subject: [PATCH] update core --- mupen64plus-core/projects/unix/Makefile | 33 ++++++++--------- .../src/backends/api/storage_backend.h | 2 +- mupen64plus-core/src/backends/file_storage.c | 24 ++++++++++--- mupen64plus-core/src/backends/file_storage.h | 1 + mupen64plus-core/src/device/cart/eeprom.c | 2 +- mupen64plus-core/src/device/cart/flashram.c | 8 +++-- mupen64plus-core/src/device/cart/sram.c | 4 +-- .../src/device/controllers/paks/mempak.c | 2 +- .../src/device/dd/dd_controller.c | 4 +-- mupen64plus-core/src/device/dd/disk.c | 4 +-- mupen64plus-core/src/device/gb/gb_cart.c | 2 +- .../device/r4300/new_dynarec/new_dynarec.c | 6 ++-- mupen64plus-core/src/main/util.c | 35 ++++++++++++++++++- mupen64plus-core/src/main/util.h | 8 ++++- mupen64plus-core/src/osal/files.h | 4 +-- mupen64plus-core/src/osal/files_unix.c | 10 +++--- mupen64plus-core/src/osal/files_win32.c | 4 +-- 17 files changed, 104 insertions(+), 49 deletions(-) diff --git a/mupen64plus-core/projects/unix/Makefile b/mupen64plus-core/projects/unix/Makefile index 7f38c00..f7d4ad3 100755 --- a/mupen64plus-core/projects/unix/Makefile +++ b/mupen64plus-core/projects/unix/Makefile @@ -139,18 +139,18 @@ ifeq ("$(CPU)","NONE") $(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'https://github.com/mupen64plus/mupen64plus-core/issues') endif -# base CFLAGS, LDLIBS, and LDFLAGS -OPTFLAGS ?= -O3 -flto -WARNFLAGS ?= -Wall -CFLAGS += -fno-strict-aliasing -fvisibility=hidden -I../../src -I../../src/asm_defines -DM64P_PARALLEL -CXXFLAGS += -fvisibility-inlines-hidden -LDLIBS += -lm - # directory paths SRCDIR = ../../src OBJDIR = _obj$(POSTFIX) SUBDIR = ../../subprojects +# base CFLAGS, LDLIBS, and LDFLAGS +OPTFLAGS ?= -O3 -flto +WARNFLAGS ?= -Wall +CFLAGS += -fno-strict-aliasing -fvisibility=hidden -I$(SRCDIR) -I$(SRCDIR)/asm_defines -DM64P_PARALLEL +CXXFLAGS += -fvisibility-inlines-hidden +LDLIBS += -lm + # Since we are building a shared library, we must compile with -fPIC on some architectures # On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch ifeq ($(PIC), 1) @@ -192,7 +192,7 @@ ifeq ($(OS), LINUX) LDFLAGS += -Wl,-Bsymbolic -shared -Wl,-export-dynamic -Wl,-soname,$(SONAME) LDLIBS += -ldl # only export api symbols - LDFLAGS += -Wl,-version-script,../../src/api/api_export.ver + LDFLAGS += -Wl,-version-script,$(SRCDIR)/api/api_export.ver ifeq ($(ARCH_DETECTED), 64BITS) ASFLAGS = -f elf64 else @@ -211,11 +211,12 @@ ifeq ($(OS), OSX) ASFLAGS = -f macho -d LEADING_UNDERSCORE endif + CXXFLAGS += '-stdlib=libc++' ifeq ($(CPU), X86) ifeq ($(ARCH_DETECTED), 64BITS) - CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=10.6 -isysroot $(OSX_SDK_PATH) + CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=10.7 -isysroot $(OSX_SDK_PATH) else - CFLAGS += -pipe -mmmx -msse -arch i686 -mmacosx-version-min=10.6 -isysroot $(OSX_SDK_PATH) + CFLAGS += -pipe -mmmx -msse -arch i686 -mmacosx-version-min=10.7 -isysroot $(OSX_SDK_PATH) ifneq ($(PROFILE), 1) CFLAGS += -fomit-frame-pointer endif @@ -227,7 +228,7 @@ ifeq ($(OS), MINGW) TARGET = mupen64plus$(POSTFIX).dll LDFLAGS += -Wl,-Bsymbolic -shared -Wl,-export-all-symbols # only export api symbols - LDFLAGS += -Wl,-version-script,../../src/api/api_export.ver + LDFLAGS += -Wl,-version-script,$(SRCDIR)/api/api_export.ver LDLIBS += -lpthread ifeq ($(ARCH_DETECTED), 64BITS) ASFLAGS = -f win64 -d WIN64 @@ -241,7 +242,7 @@ ifeq ($(PIC), 1) endif # assembler also needs base include directories -ASFLAGS += -I../../src/ -I../../src/asm_defines/ +ASFLAGS += -I$(SRCDIR) -I$(SRCDIR)/asm_defines/ ifeq ($(CPU_ENDIANNESS), BIG) CFLAGS += -DM64P_BIG_ENDIAN @@ -750,9 +751,9 @@ install: $(TARGET) $(INSTALL) -d "$(DESTDIR)$(LIBDIR)" $(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(LIBDIR)" $(INSTALL) -d "$(DESTDIR)$(SHAREDIR)" - $(INSTALL) -m 0644 ../../data/* "$(DESTDIR)$(SHAREDIR)" + $(INSTALL) -m 0644 $(SRCDIR)/../data/* "$(DESTDIR)$(SHAREDIR)" $(INSTALL) -d "$(DESTDIR)$(INCDIR)" - $(INSTALL) -m 0644 ../../src/api/m64p_*.h "$(DESTDIR)$(INCDIR)" + $(INSTALL) -m 0644 $(SRCDIR)/api/m64p_*.h "$(DESTDIR)$(INCDIR)" -$(LDCONFIG) "$(DESTDIR)$(LIBDIR)" if [ ! -e "$(DESTDIR)$(LIBDIR)/$(SONAME)" ]; then ln -sf "$(TARGET)" "$(DESTDIR)$(LIBDIR)/$(SONAME)"; fi @@ -780,8 +781,8 @@ $(ASM_DEFINES_OBJ): $(SRCDIR)/asm_defines/asm_defines.c # Script hackery for generating ASM include files for the new dynarec assembly code $(SRCDIR)/asm_defines/asm_defines_gas.h: $(SRCDIR)/asm_defines/asm_defines_nasm.h -$(SRCDIR)/asm_defines/asm_defines_nasm.h: $(ASM_DEFINES_OBJ) ../../tools/gen_asm_script.sh - sh ../../tools/gen_asm_script.sh "$(SRCDIR)/asm_defines" "$(ASM_DEFINES_OBJ)" +$(SRCDIR)/asm_defines/asm_defines_nasm.h: $(ASM_DEFINES_OBJ) $(SRCDIR)/../tools/gen_asm_script.sh + sh $(SRCDIR)/../tools/gen_asm_script.sh "$(SRCDIR)/asm_defines" "$(ASM_DEFINES_OBJ)" # standard build rules $(OBJDIR)/%.o: $(SRCDIR)/%.asm $(SRCDIR)/asm_defines/asm_defines_nasm.h diff --git a/mupen64plus-core/src/backends/api/storage_backend.h b/mupen64plus-core/src/backends/api/storage_backend.h index d80edf3..e0b5f36 100644 --- a/mupen64plus-core/src/backends/api/storage_backend.h +++ b/mupen64plus-core/src/backends/api/storage_backend.h @@ -37,7 +37,7 @@ struct storage_backend_interface /* Notify the storage backend that data should be persisted */ - void (*save)(void* storage); + void (*save)(void* storage, size_t start, size_t size); }; #endif diff --git a/mupen64plus-core/src/backends/file_storage.c b/mupen64plus-core/src/backends/file_storage.c index 7ebdaf3..e169403 100644 --- a/mupen64plus-core/src/backends/file_storage.c +++ b/mupen64plus-core/src/backends/file_storage.c @@ -35,6 +35,7 @@ int open_file_storage(struct file_storage* fstorage, size_t size, const char* fi /* ! Take ownership of filename ! */ fstorage->filename = filename; fstorage->size = size; + fstorage->first_access = 1; /* allocate memory for holding data */ fstorage->data = malloc(fstorage->size); @@ -58,6 +59,7 @@ int open_rom_file_storage(struct file_storage* fstorage, const char* filename) fstorage->data = NULL; fstorage->size = 0; fstorage->filename = NULL; + fstorage->first_access = 1; file_status_t err = load_file(filename, (void**)&fstorage->data, &fstorage->size); @@ -88,14 +90,26 @@ static size_t file_storage_size(const void* storage) return fstorage->size; } -static void file_storage_save(void* storage) +static void file_storage_save(void* storage, size_t start, size_t size) { if (netplay_is_init() && netplay_get_controller(0) == -1) return; struct file_storage* fstorage = (struct file_storage*)storage; - switch(write_to_file(fstorage->filename, fstorage->data, fstorage->size)) + file_status_t err; + + /* On first save access ignore start/size and write full storage content, + * otherwise write only updated chunk */ + if (fstorage->first_access) { + fstorage->first_access = 0; + err = write_to_file(fstorage->filename, fstorage->data, fstorage->size); + } + else { + err = write_chunk_to_file(fstorage->filename, fstorage->data + start, size, start); + } + + switch(err) { case file_open_error: DebugMessage(M64MSG_WARNING, "couldn't open storage file '%s' for writing", fstorage->filename); @@ -108,13 +122,13 @@ static void file_storage_save(void* storage) } } -static void file_storage_parent_save(void* storage) +static void file_storage_parent_save(void* storage, size_t start, size_t size) { struct file_storage* fstorage = (struct file_storage*)((struct file_storage*)storage)->filename; - file_storage_save(fstorage); + file_storage_save(fstorage, start, size); } -static void dummy_save(void* storage) +static void dummy_save(void* storage, size_t start, size_t size) { /* do nothing */ } diff --git a/mupen64plus-core/src/backends/file_storage.h b/mupen64plus-core/src/backends/file_storage.h index d31f7b2..f247a51 100644 --- a/mupen64plus-core/src/backends/file_storage.h +++ b/mupen64plus-core/src/backends/file_storage.h @@ -30,6 +30,7 @@ struct file_storage uint8_t* data; size_t size; const char* filename; + int first_access; }; diff --git a/mupen64plus-core/src/device/cart/eeprom.c b/mupen64plus-core/src/device/cart/eeprom.c index af9b1a2..2f1e825 100644 --- a/mupen64plus-core/src/device/cart/eeprom.c +++ b/mupen64plus-core/src/device/cart/eeprom.c @@ -72,7 +72,7 @@ void eeprom_write_block(struct eeprom* eeprom, if (address < eeprom->istorage->size(eeprom->storage)) { memcpy(eeprom->istorage->data(eeprom->storage) + address, data, EEPROM_BLOCK_SIZE); - eeprom->istorage->save(eeprom->storage); + eeprom->istorage->save(eeprom->storage, address, EEPROM_BLOCK_SIZE); *status = 0x00; } else diff --git a/mupen64plus-core/src/device/cart/flashram.c b/mupen64plus-core/src/device/cart/flashram.c index c472587..3b838fe 100644 --- a/mupen64plus-core/src/device/cart/flashram.c +++ b/mupen64plus-core/src/device/cart/flashram.c @@ -58,15 +58,17 @@ static void flashram_command(struct flashram* flashram, uint32_t command) /* do chip/sector erase */ if (flashram->mode == FLASHRAM_MODE_SECTOR_ERASE) { - memset(mem + (flashram->erase_page & 0xff80) * 128, 0xff, 128*128); + offset = (flashram->erase_page & 0xff80) * 128; + memset(mem + offset, 0xff, 128*128); + flashram->istorage->save(flashram->storage, offset, 128*128); } else if (flashram->mode == FLASHRAM_MODE_CHIP_ERASE){ memset(mem, 0xff, FLASHRAM_SIZE); + flashram->istorage->save(flashram->storage, 0, FLASHRAM_SIZE); } else { DebugMessage(M64MSG_WARNING, "Unexpected erase command (mode=%x)", flashram->mode); } - flashram->istorage->save(flashram->storage); /* clear erase busy flag, set erase success flag, transition to status mode */ flashram->status &= ~UINT32_C(0x02); @@ -83,7 +85,7 @@ static void flashram_command(struct flashram* flashram, uint32_t command) for (i = 0; i < 128; ++i) { mem[(offset+i)^S8] = flashram->page_buf[i]; } - flashram->istorage->save(flashram->storage); + flashram->istorage->save(flashram->storage, offset, 128); /* clear program busy flag, set program success flag, transition to status mode */ flashram->status &= ~UINT32_C(0x01); diff --git a/mupen64plus-core/src/device/cart/sram.c b/mupen64plus-core/src/device/cart/sram.c index d421e2c..508447f 100644 --- a/mupen64plus-core/src/device/cart/sram.c +++ b/mupen64plus-core/src/device/cart/sram.c @@ -54,7 +54,7 @@ unsigned int sram_dma_read(void* opaque, const uint8_t* dram, uint32_t dram_addr mem[(cart_addr+i)^S8] = dram[(dram_addr+i)^S8]; } - sram->istorage->save(sram->storage); + sram->istorage->save(sram->storage, cart_addr, length); return /* length / 8 */0x1000; } @@ -93,5 +93,5 @@ void write_sram(void* opaque, uint32_t address, uint32_t value, uint32_t mask) masked_write((uint32_t*)(mem + address), value, mask); - sram->istorage->save(sram->storage); + sram->istorage->save(sram->storage, address, sizeof(value)); } diff --git a/mupen64plus-core/src/device/controllers/paks/mempak.c b/mupen64plus-core/src/device/controllers/paks/mempak.c index 0e78f4c..30e53f5 100644 --- a/mupen64plus-core/src/device/controllers/paks/mempak.c +++ b/mupen64plus-core/src/device/controllers/paks/mempak.c @@ -100,7 +100,7 @@ static void write_mempak(void* pak, uint16_t address, const uint8_t* data, size_ if (address < 0x8000) { memcpy(mpk->istorage->data(mpk->storage) + address, data, size); - mpk->istorage->save(mpk->storage); + mpk->istorage->save(mpk->storage, address, size); } else { diff --git a/mupen64plus-core/src/device/dd/dd_controller.c b/mupen64plus-core/src/device/dd/dd_controller.c index dd8ec3f..e02c323 100644 --- a/mupen64plus-core/src/device/dd/dd_controller.c +++ b/mupen64plus-core/src/device/dd/dd_controller.c @@ -192,9 +192,7 @@ static void write_sector(struct dd_controller* dd) disk_sec[i] = dd->ds_buf[i ^ 3]; } -#if 0 /* disabled for now, because it causes too much slowdowns */ - dd->idisk->save(dd->disk); -#endif + //dd->idisk->save(dd->disk, disk_sec - dd->idisk->data(dd->disk), length); } void dd_update_bm(void* opaque) diff --git a/mupen64plus-core/src/device/dd/disk.c b/mupen64plus-core/src/device/dd/disk.c index 9372d78..14127e5 100644 --- a/mupen64plus-core/src/device/dd/disk.c +++ b/mupen64plus-core/src/device/dd/disk.c @@ -39,14 +39,14 @@ static size_t storage_disk_size(const void* storage) return disk->istorage->size(disk->storage); } -static void storage_disk_save(void* storage) +static void storage_disk_save(void* storage, size_t start, size_t size) { struct dd_disk* disk = (struct dd_disk*)storage; // XXX: you have now access to all disk members // and can handle the various format specificities here - disk->istorage->save(disk->storage); + disk->istorage->save(disk->storage, start, size); } const struct storage_backend_interface g_istorage_disk = diff --git a/mupen64plus-core/src/device/gb/gb_cart.c b/mupen64plus-core/src/device/gb/gb_cart.c index cd95cb5..a641417 100644 --- a/mupen64plus-core/src/device/gb/gb_cart.c +++ b/mupen64plus-core/src/device/gb/gb_cart.c @@ -135,7 +135,7 @@ static void write_ram(void* ram_storage, const struct storage_backend_interface* dst[i] &= mask; } } - iram_storage->save(ram_storage); + iram_storage->save(ram_storage, address, size); } diff --git a/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c b/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c index 0c5e7ba..233fafb 100644 --- a/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c +++ b/mupen64plus-core/src/device/r4300/new_dynarec/new_dynarec.c @@ -430,7 +430,7 @@ static void lsn(u_char hsn[], int i, int *preferred_reg) } if(itype[i+j]==UJUMP||itype[i+j]==RJUMP||(source[i+j]>>16)==0x1000) { - // Don't go past an unconditonal jump + // Don't go past an unconditional jump j++; break; } @@ -528,7 +528,7 @@ static int needed_again(int r, int i) } if(itype[i+j]==UJUMP||itype[i+j]==RJUMP||(source[i+j]>>16)==0x1000) { - // Don't go past an unconditonal jump + // Don't go past an unconditional jump j++; break; } @@ -583,7 +583,7 @@ static int loop_reg(int i, int r, int hr) } if(itype[i+j]==UJUMP||itype[i+j]==RJUMP||(source[i+j]>>16)==0x1000) { - // Don't go past an unconditonal jump + // Don't go past an unconditional jump j++; break; } diff --git a/mupen64plus-core/src/main/util.c b/mupen64plus-core/src/main/util.c index e73b06e..05de862 100644 --- a/mupen64plus-core/src/main/util.c +++ b/mupen64plus-core/src/main/util.c @@ -76,13 +76,46 @@ file_status_t write_to_file(const char *filename, const void *data, size_t size) if (fwrite(data, 1, size, f) != size) { fclose(f); - return file_read_error; + return file_write_error; } fclose(f); return file_ok; } + +file_status_t write_chunk_to_file(const char *filename, const void *data, size_t size, size_t offset) +{ + FILE *f; + + /* first try to open with rb+ to avoid wiping existing content, + * otherwise create file */ + if ((f = fopen(filename, "rb+")) == NULL) { + if ((f = fopen(filename, "wb")) == NULL) { + return file_open_error; + } + } + + /* According to POSIX fseek past file size is supported and will fill with zeros bytes + * (and use sparse file if supported). + * So we can use it to position next write operation at desired offset. + */ + if (fseek(f, offset, SEEK_SET)) { + fclose(f); + return file_open_error; + } + + if (fwrite(data, 1, size, f) != size) + { + fclose(f); + return file_write_error; + } + + fclose(f); + return file_ok; +} + + file_status_t load_file(const char* filename, void** buffer, size_t* size) { FILE* fd; diff --git a/mupen64plus-core/src/main/util.h b/mupen64plus-core/src/main/util.h index c18c952..957592b 100644 --- a/mupen64plus-core/src/main/util.h +++ b/mupen64plus-core/src/main/util.h @@ -58,9 +58,15 @@ file_status_t read_from_file(const char *filename, void *data, size_t size); /** write_to_file * opens a file and writes the specified number of bytes. * returns zero on success, nonzero on failure - */ + */ file_status_t write_to_file(const char *filename, const void *data, size_t size); +/** write_chunk_to_file + * opens a file, seek to offset and writes the specified number of bytes. + * returns zero on success, nonzero on failure + */ +file_status_t write_chunk_to_file(const char *filename, const void *data, size_t size, size_t offset); + /** load_file * load the file content into a newly allocated buffer. * returns zero on success, nonzero on failure diff --git a/mupen64plus-core/src/osal/files.h b/mupen64plus-core/src/osal/files.h index ff93454..c2fdc15 100644 --- a/mupen64plus-core/src/osal/files.h +++ b/mupen64plus-core/src/osal/files.h @@ -8,7 +8,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * This program is distributed in the hope that it will be useful, * + * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - + /* This file contains the declarations for OS-dependent file handling * functions */ diff --git a/mupen64plus-core/src/osal/files_unix.c b/mupen64plus-core/src/osal/files_unix.c index 2207167..d457ce0 100644 --- a/mupen64plus-core/src/osal/files_unix.c +++ b/mupen64plus-core/src/osal/files_unix.c @@ -8,7 +8,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * This program is distributed in the hope that it will be useful, * + * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - + /* This file contains the definitions for the unix-specific file handling * functions */ @@ -173,7 +173,7 @@ const char * osal_get_user_configpath(void) { static char retpath[PATH_MAX]; int rval; - + /* first, try the XDG_CONFIG_HOME environment variable */ rval = get_xdg_dir(retpath, "XDG_CONFIG_HOME", "mupen64plus/"); if (rval == 0) @@ -194,7 +194,7 @@ const char * osal_get_user_datapath(void) { static char retpath[PATH_MAX]; int rval; - + /* first, try the XDG_DATA_HOME environment variable */ rval = get_xdg_dir(retpath, "XDG_DATA_HOME", "mupen64plus/"); if (rval == 0) @@ -215,7 +215,7 @@ const char * osal_get_user_cachepath(void) { static char retpath[PATH_MAX]; int rval; - + /* first, try the XDG_CACHE_HOME environment variable */ rval = get_xdg_dir(retpath, "XDG_CACHE_HOME", "mupen64plus/"); if (rval == 0) diff --git a/mupen64plus-core/src/osal/files_win32.c b/mupen64plus-core/src/osal/files_win32.c index 0ef5e99..97af7e3 100644 --- a/mupen64plus-core/src/osal/files_win32.c +++ b/mupen64plus-core/src/osal/files_win32.c @@ -8,7 +8,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * This program is distributed in the hope that it will be useful, * + * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - + /* This file contains the definitions for the unix-specific file handling * functions */