From 9ae346e1ee94524372020b73e67b9126355df1c7 Mon Sep 17 00:00:00 2001 From: Arignir Date: Mon, 21 Aug 2023 14:54:53 +0200 Subject: [PATCH] Regroup all backup-storage-related fields of `struct memory` into a common sub-struct. --- include/gba/memory.h | 26 ++++++----- source/common/game.c | 10 ++--- source/gba/gba.c | 10 ++--- source/gba/memory/memory.c | 20 ++++----- source/gba/memory/storage/eeprom.c | 10 ++--- source/gba/memory/storage/flash.c | 24 +++++----- source/gba/memory/storage/storage.c | 69 +++++++++++++++-------------- source/gba/quicksave.c | 6 +-- 8 files changed, 88 insertions(+), 87 deletions(-) diff --git a/include/gba/memory.h b/include/gba/memory.h index 84a38bda..b48a8afa 100644 --- a/include/gba/memory.h +++ b/include/gba/memory.h @@ -219,17 +219,21 @@ struct memory { uint8_t rom[CART_SIZE]; size_t rom_size; - // Backup Storage - uint8_t *backup_storage_data; - enum backup_storage_types backup_storage_type; - enum backup_storage_sources backup_storage_source; - atomic_bool backup_storage_dirty; - - // Flash memory - struct flash flash; - - // EEPROM memory - struct eeprom eeprom; + struct { + struct { + // Flash memory + struct flash flash; + + // EEPROM memory + struct eeprom eeprom; + } chip; + uint8_t *data; + size_t size; + enum backup_storage_types type; + enum backup_storage_sources source; + + atomic_bool dirty; + } backup_storage; // Prefetch struct prefetch_buffer pbuffer; diff --git a/source/common/game.c b/source/common/game.c index e2d11fd5..d966e847 100644 --- a/source/common/game.c +++ b/source/common/game.c @@ -360,18 +360,18 @@ app_game_write_backup( struct app *app ) { if ( app->file.backup_file - && app->emulation.gba->memory.backup_storage_data - && app->emulation.gba->memory.backup_storage_dirty + && app->emulation.gba->memory.backup_storage.data + && app->emulation.gba->memory.backup_storage.dirty ) { fseek(app->file.backup_file, 0, SEEK_SET); fwrite( - app->emulation.gba->memory.backup_storage_data, - backup_storage_sizes[app->emulation.gba->memory.backup_storage_type], + app->emulation.gba->memory.backup_storage.data, + backup_storage_sizes[app->emulation.gba->memory.backup_storage.type], 1, app->file.backup_file ); } - app->emulation.gba->memory.backup_storage_dirty = false; + app->emulation.gba->memory.backup_storage.dirty = false; } void diff --git a/source/gba/gba.c b/source/gba/gba.c index 882c3bdd..c1dda3bc 100644 --- a/source/gba/gba.c +++ b/source/gba/gba.c @@ -142,11 +142,11 @@ gba_main_loop( struct message_data *message_data; message_data = (struct message_data *)message; - memset(gba->memory.backup_storage_data, 0, backup_storage_sizes[gba->memory.backup_storage_type]); + memset(gba->memory.backup_storage.data, 0, backup_storage_sizes[gba->memory.backup_storage.type]); memcpy( - gba->memory.backup_storage_data, + gba->memory.backup_storage.data, message_data->data, - min(message_data->size, backup_storage_sizes[gba->memory.backup_storage_type]) + min(message_data->size, backup_storage_sizes[gba->memory.backup_storage.type]) ); if (message_data->cleanup) { message_data->cleanup(message_data->data); @@ -165,8 +165,8 @@ gba_main_loop( if (message_backup_type->type == BACKUP_AUTO_DETECT) { mem_backup_storage_detect(gba); } else { - gba->memory.backup_storage_type = message_backup_type->type; - gba->memory.backup_storage_source = BACKUP_SOURCE_MANUAL; + gba->memory.backup_storage.type = message_backup_type->type; + gba->memory.backup_storage.source = BACKUP_SOURCE_MANUAL; } mem_backup_storage_init(gba); break; diff --git a/source/gba/memory/memory.c b/source/gba/memory/memory.c index 07dc7c8a..7ec8064d 100644 --- a/source/gba/memory/memory.c +++ b/source/gba/memory/memory.c @@ -61,13 +61,13 @@ mem_reset( memset(memory->vram, 0, sizeof(memory->vram)); memset(memory->oam, 0, sizeof(memory->oam)); memset(&memory->pbuffer, 0, sizeof(memory->pbuffer)); - memset(&memory->flash, 0, sizeof(memory->flash)); + memset(&memory->backup_storage.chip.flash, 0, sizeof(memory->backup_storage.chip.flash)); memory->gamepak_bus_in_use = false; memory->bios_bus = 0; - memory->eeprom.state = EEPROM_STATE_READY; - memory->eeprom.transfer_address = 0; - memory->eeprom.transfer_data = 0; - memory->eeprom.transfer_len = 0; + memory->backup_storage.chip.eeprom.state = EEPROM_STATE_READY; + memory->backup_storage.chip.eeprom.transfer_address = 0; + memory->backup_storage.chip.eeprom.transfer_data = 0; + memory->backup_storage.chip.eeprom.transfer_len = 0; } /* @@ -333,9 +333,8 @@ mem_openbus_read( break; \ case CART_REGION_START ... CART_REGION_END: { \ if (unlikely( \ - (_addr & (gba)->memory.eeprom.mask) == (gba)->memory.eeprom.range \ - && ((gba)->memory.backup_storage_type == BACKUP_EEPROM_4K \ - || (gba)->memory.backup_storage_type == BACKUP_EEPROM_64K) \ + ((gba)->memory.backup_storage.type == BACKUP_EEPROM_4K || (gba)->memory.backup_storage.type == BACKUP_EEPROM_64K) \ + && (_addr & (gba)->memory.backup_storage.chip.eeprom.mask) == (gba)->memory.backup_storage.chip.eeprom.range \ )) { \ _ret = mem_eeprom_read8(gba); \ } else if (unlikely(_addr >= GPIO_REG_START && _addr <= GPIO_REG_END && (gba)->gpio.readable)) { \ @@ -475,9 +474,8 @@ mem_openbus_read( break; \ }; \ case CART_REGION_START ... CART_REGION_END: { \ - if ( (_addr & (gba)->memory.eeprom.mask) == (gba)->memory.eeprom.range \ - && ((gba)->memory.backup_storage_type == BACKUP_EEPROM_4K \ - || (gba)->memory.backup_storage_type == BACKUP_EEPROM_64K) \ + if (((gba)->memory.backup_storage.type == BACKUP_EEPROM_4K || (gba)->memory.backup_storage.type == BACKUP_EEPROM_64K) \ + && (_addr & (gba)->memory.backup_storage.chip.eeprom.mask) == (gba)->memory.backup_storage.chip.eeprom.range \ ) { \ mem_eeprom_write8((gba), (val) & 1); \ } else if (_addr >= GPIO_REG_START && _addr <= GPIO_REG_END) { \ diff --git a/source/gba/memory/storage/eeprom.c b/source/gba/memory/storage/eeprom.c index 58f37b7d..baf5e742 100644 --- a/source/gba/memory/storage/eeprom.c +++ b/source/gba/memory/storage/eeprom.c @@ -16,7 +16,7 @@ mem_eeprom_read8( ) { struct eeprom *eeprom; - eeprom = &gba->memory.eeprom; + eeprom = &gba->memory.backup_storage.chip.eeprom; if (eeprom->cmd == EEPROM_CMD_READ) { if (eeprom->state == EEPROM_STATE_TRANSFER_JUNK) { @@ -57,7 +57,7 @@ mem_eeprom_write8( ) { struct eeprom *eeprom; - eeprom = &gba->memory.eeprom; + eeprom = &gba->memory.backup_storage.chip.eeprom; switch (eeprom->state) { case EEPROM_STATE_READY: { @@ -96,7 +96,7 @@ mem_eeprom_write8( eeprom->transfer_data = 0; for (i = 0; i < 8; ++i) { eeprom->transfer_data <<= 8; - eeprom->transfer_data |= gba->memory.backup_storage_data[eeprom->transfer_address + i]; + eeprom->transfer_data |= gba->memory.backup_storage.data[eeprom->transfer_address + i]; } break; @@ -122,9 +122,9 @@ mem_eeprom_write8( eeprom->transfer_len = 0; for (i = 0; i < 8; ++i) { - gba->memory.backup_storage_data[eeprom->transfer_address + i] = (eeprom->transfer_data >> (56 - 8 * i)) & 0xFF; + gba->memory.backup_storage.data[eeprom->transfer_address + i] = (eeprom->transfer_data >> (56 - 8 * i)) & 0xFF; } - gba->memory.backup_storage_dirty = true; + gba->memory.backup_storage.dirty = true; eeprom->state = EEPROM_STATE_END; } diff --git a/source/gba/memory/storage/flash.c b/source/gba/memory/storage/flash.c index 3a427058..c9d0f0b8 100644 --- a/source/gba/memory/storage/flash.c +++ b/source/gba/memory/storage/flash.c @@ -18,18 +18,18 @@ mem_flash_read8( ) { struct flash const *flash; - flash = &gba->memory.flash; + flash = &gba->memory.backup_storage.chip.flash; addr &= FLASH_MASK; if (flash->identity_mode) { /* Use Panasonic (0x1b32) for Flash 64k and Sanyo (0x1362) for Flash 128k. */ if (addr == 0x0) { - return (gba->memory.backup_storage_type == BACKUP_FLASH64 ? 0x32 : 0x62); + return (gba->memory.backup_storage.type == BACKUP_FLASH64 ? 0x32 : 0x62); } else if (addr == 0x1) { - return (gba->memory.backup_storage_type == BACKUP_FLASH64 ? 0x1b : 0x13); + return (gba->memory.backup_storage.type == BACKUP_FLASH64 ? 0x1b : 0x13); } } - return (gba->memory.backup_storage_data[addr + flash->bank * FLASH64_SIZE]); + return (gba->memory.backup_storage.data[addr + flash->bank * FLASH64_SIZE]); } void @@ -40,7 +40,7 @@ mem_flash_write8( ) { struct flash *flash; - flash = &gba->memory.flash; + flash = &gba->memory.backup_storage.chip.flash; addr &= FLASH_MASK; if (addr == 0x5555 && val == 0xAA && flash->state == FLASH_STATE_READY) { @@ -55,14 +55,14 @@ mem_flash_write8( case FLASH_CMD_PREP_ERASE: flash->state = FLASH_STATE_ERASE; break; case FLASH_CMD_ERASE_CHIP: { if (flash->state == FLASH_STATE_ERASE) { - memset(gba->memory.backup_storage_data, 0xFF, backup_storage_sizes[gba->memory.backup_storage_type]); - gba->memory.backup_storage_dirty = true; + memset(gba->memory.backup_storage.data, 0xFF, backup_storage_sizes[gba->memory.backup_storage.type]); + gba->memory.backup_storage.dirty = true; } break; }; case FLASH_CMD_WRITE: flash->state = FLASH_STATE_WRITE; break; case FLASH_CMD_SET_BANK: { - if (gba->memory.backup_storage_type == BACKUP_FLASH128) { + if (gba->memory.backup_storage.type == BACKUP_FLASH128) { flash->state = FLASH_STATE_BANK; } break; @@ -72,12 +72,12 @@ mem_flash_write8( // Erase the desired sector addr &= 0xF000; - memset(gba->memory.backup_storage_data + addr + flash->bank * FLASH64_SIZE, 0xFF, 0x1000); - gba->memory.backup_storage_dirty = true; + memset(gba->memory.backup_storage.data + addr + flash->bank * FLASH64_SIZE, 0xFF, 0x1000); + gba->memory.backup_storage.dirty = true; flash->state = FLASH_STATE_READY; } else if (flash->state == FLASH_STATE_WRITE) { - gba->memory.backup_storage_data[addr + flash->bank * FLASH64_SIZE] = val; - gba->memory.backup_storage_dirty = true; + gba->memory.backup_storage.data[addr + flash->bank * FLASH64_SIZE] = val; + gba->memory.backup_storage.dirty = true; flash->state = FLASH_STATE_READY; } else if (flash->state == FLASH_STATE_BANK && addr == 0x0) { flash->bank = val; diff --git a/source/gba/memory/storage/storage.c b/source/gba/memory/storage/storage.c index c53326a2..2314c95e 100644 --- a/source/gba/memory/storage/storage.c +++ b/source/gba/memory/storage/storage.c @@ -58,35 +58,35 @@ mem_backup_storage_detect( ) { /* Prioritize the game database. */ if (gba->game_entry) { - gba->memory.backup_storage_type = gba->game_entry->storage; - gba->memory.backup_storage_source = BACKUP_SOURCE_DATABASE; + gba->memory.backup_storage.type = gba->game_entry->storage; + gba->memory.backup_storage.source = BACKUP_SOURCE_DATABASE; return ; } - gba->memory.backup_storage_source = BACKUP_SOURCE_AUTO_DETECT; + gba->memory.backup_storage.source = BACKUP_SOURCE_AUTO_DETECT; /* Auto-detection algorithm are very simple: they look for a bunch of strings in the game's ROM. */ if (array_search(gba->memory.rom, sizeof(gba->memory.rom), "EEPROM_V", 7)) { logln(HS_INFO, "Detected EEPROM 64K memory."); logln(HS_WARNING, "If you are having issues with corrupted saves, try EEPROM 8K instead."); - gba->memory.backup_storage_type = BACKUP_EEPROM_64K; + gba->memory.backup_storage.type = BACKUP_EEPROM_64K; } else if ( array_search(gba->memory.rom, sizeof(gba->memory.rom), "SRAM_V", 5) || array_search(gba->memory.rom, sizeof(gba->memory.rom), "SRAM_F_V", 5) ) { logln(HS_INFO, "Detected SRAM memory"); - gba->memory.backup_storage_type = BACKUP_SRAM; + gba->memory.backup_storage.type = BACKUP_SRAM; } else if (array_search(gba->memory.rom, sizeof(gba->memory.rom), "FLASH1M_V", 8)) { logln(HS_INFO, "Detected Flash 128 kilobytes / 1 megabit"); - gba->memory.backup_storage_type = BACKUP_FLASH128; + gba->memory.backup_storage.type = BACKUP_FLASH128; } else if ( array_search(gba->memory.rom, sizeof(gba->memory.rom), "FLASH_V", 6) || array_search(gba->memory.rom, sizeof(gba->memory.rom), "FLASH512_V", 9) ) { logln(HS_INFO, "Detected Flash 64 kilobytes / 512 kilobits"); - gba->memory.backup_storage_type = BACKUP_FLASH64; + gba->memory.backup_storage.type = BACKUP_FLASH64; } else { - gba->memory.backup_storage_type = BACKUP_NONE; + gba->memory.backup_storage.type = BACKUP_NONE; } } @@ -94,24 +94,25 @@ void mem_backup_storage_init( struct gba *gba ) { - free(gba->memory.backup_storage_data); + free(gba->memory.backup_storage.data); - if (gba->memory.backup_storage_type > BACKUP_NONE) { + if (gba->memory.backup_storage.type > BACKUP_NONE) { logln( HS_INFO, "Backup memory is %s%s%s (%s).", g_light_magenta, - backup_storage_names[gba->memory.backup_storage_type], + backup_storage_names[gba->memory.backup_storage.type], g_reset, - backup_storage_sources_str[gba->memory.backup_storage_source] + backup_storage_sources_str[gba->memory.backup_storage.source] ); } else { - logln(HS_INFO, "No backup storage (%s).", backup_storage_sources_str[gba->memory.backup_storage_source]); + logln(HS_INFO, "No backup storage (%s).", backup_storage_sources_str[gba->memory.backup_storage.source]); } - if ( gba->memory.backup_storage_type == BACKUP_EEPROM_4K - || gba->memory.backup_storage_type == BACKUP_EEPROM_64K + if ( gba->memory.backup_storage.type == BACKUP_EEPROM_4K + || gba->memory.backup_storage.type == BACKUP_EEPROM_64K ) { + struct eeprom *eeprom; /* ** Those are masks applied to the address of any ROM data transfers @@ -120,29 +121,29 @@ mem_backup_storage_init( ** ** A data transfer is going to the EEPROM iff (addr & eeprom.mask) == eeprom.range. */ - + eeprom = &gba->memory.backup_storage.chip.eeprom; if (gba->memory.rom_size > 16 * 1024 * 1024) { - gba->memory.eeprom.mask = 0x01FFFF00; - gba->memory.eeprom.range = 0x01FFFF00; + eeprom->mask = 0x01FFFF00; + eeprom->range = 0x01FFFF00; } else { - gba->memory.eeprom.mask = 0xFF000000; - gba->memory.eeprom.range = 0x0d000000; + eeprom->mask = 0xFF000000; + eeprom->range = 0x0d000000; } - if (gba->memory.backup_storage_type == BACKUP_EEPROM_4K) { - gba->memory.eeprom.address_mask = EEPROM_4K_ADDR_MASK; - gba->memory.eeprom.address_len = EEPROM_4K_ADDR_LEN; + if (gba->memory.backup_storage.type == BACKUP_EEPROM_4K) { + eeprom->address_mask = EEPROM_4K_ADDR_MASK; + eeprom->address_len = EEPROM_4K_ADDR_LEN; } else { // EEPROM_64K - gba->memory.eeprom.address_mask = EEPROM_64K_ADDR_MASK; - gba->memory.eeprom.address_len = EEPROM_64K_ADDR_LEN; + eeprom->address_mask = EEPROM_64K_ADDR_MASK; + eeprom->address_len = EEPROM_64K_ADDR_LEN; } } - if (gba->memory.backup_storage_type > BACKUP_NONE) { - gba->memory.backup_storage_data = calloc(1, backup_storage_sizes[gba->memory.backup_storage_type]); - hs_assert(gba->memory.backup_storage_data); + if (gba->memory.backup_storage.type > BACKUP_NONE) { + gba->memory.backup_storage.data = calloc(1, backup_storage_sizes[gba->memory.backup_storage.type]); + hs_assert(gba->memory.backup_storage.data); } else { - gba->memory.backup_storage_data = NULL; + gba->memory.backup_storage.data = NULL; } } @@ -151,13 +152,13 @@ mem_backup_storage_read8( struct gba const *gba, uint32_t addr ) { - switch (gba->memory.backup_storage_type) { + switch (gba->memory.backup_storage.type) { case BACKUP_FLASH64: case BACKUP_FLASH128: return (mem_flash_read8(gba, addr)); break; case BACKUP_SRAM: - return (gba->memory.backup_storage_data[addr & SRAM_MASK]); + return (gba->memory.backup_storage.data[addr & SRAM_MASK]); break; default: return (0); @@ -170,14 +171,14 @@ mem_backup_storage_write8( uint32_t addr, uint8_t val ) { - switch (gba->memory.backup_storage_type) { + switch (gba->memory.backup_storage.type) { case BACKUP_FLASH64: case BACKUP_FLASH128: mem_flash_write8(gba, addr, val); break; case BACKUP_SRAM: - gba->memory.backup_storage_data[addr & SRAM_MASK] = val; - gba->memory.backup_storage_dirty = true; + gba->memory.backup_storage.data[addr & SRAM_MASK] = val; + gba->memory.backup_storage.dirty = true; break; default: break; diff --git a/source/gba/quicksave.c b/source/gba/quicksave.c index 14f98ec7..9faa9b5a 100644 --- a/source/gba/quicksave.c +++ b/source/gba/quicksave.c @@ -38,9 +38,8 @@ quicksave( || fwrite(gba->memory.palram, sizeof(gba->memory.palram), 1, file) != 1 || fwrite(gba->memory.vram, sizeof(gba->memory.vram), 1, file) != 1 || fwrite(gba->memory.oam, sizeof(gba->memory.oam), 1, file) != 1 + || fwrite(&gba->memory.backup_storage.chip, sizeof(gba->memory.backup_storage.chip), 1, file) != 1 || fwrite(&gba->memory.pbuffer, sizeof(gba->memory.pbuffer), 1, file) != 1 - || fwrite(&gba->memory.flash, sizeof(gba->memory.flash), 1, file) != 1 - || fwrite(&gba->memory.eeprom, sizeof(gba->memory.eeprom), 1, file) != 1 || fwrite(&gba->memory.bios_bus, sizeof(gba->memory.bios_bus), 1, file) != 1 || fwrite(&gba->memory.gamepak_bus_in_use, sizeof(gba->memory.gamepak_bus_in_use), 1, file) != 1 || fwrite(&gba->io, sizeof(gba->io), 1, file) != 1 @@ -120,9 +119,8 @@ quickload( || fread(gba->memory.palram, sizeof(gba->memory.palram), 1, file) != 1 || fread(gba->memory.vram, sizeof(gba->memory.vram), 1, file) != 1 || fread(gba->memory.oam, sizeof(gba->memory.oam), 1, file) != 1 + || fread(&gba->memory.backup_storage.chip, sizeof(gba->memory.backup_storage.chip), 1, file) != 1 || fread(&gba->memory.pbuffer, sizeof(gba->memory.pbuffer), 1, file) != 1 - || fread(&gba->memory.flash, sizeof(gba->memory.flash), 1, file) != 1 - || fread(&gba->memory.eeprom, sizeof(gba->memory.eeprom), 1, file) != 1 || fread(&gba->memory.bios_bus, sizeof(gba->memory.bios_bus), 1, file) != 1 || fread(&gba->memory.gamepak_bus_in_use, sizeof(gba->memory.gamepak_bus_in_use), 1, file) != 1 || fread(&gba->io, sizeof(gba->io), 1, file) != 1