From 6e59ca6795d634b2ccb99d33bb8b3bae3e6fc910 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Thu, 14 Sep 2023 00:22:55 +0200 Subject: [PATCH] Improve EEPROM reads/writes and ROM reads Unmapped areas read a value closer to what hardware produces. Ensure that 32MB games can do EEPROM reads. --- gba_memory.c | 36 ++++++++++++++++++++++++------------ x86/x86_stub.S | 8 +++++--- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/gba_memory.c b/gba_memory.c index 7a37bd4..9ffdfa0 100644 --- a/gba_memory.c +++ b/gba_memory.c @@ -469,6 +469,12 @@ u8 read_backup(u32 address) #define read_backup32() \ value = 0 \ +#define write_eeprom8(addr, value) + +#define write_eeprom16(addr, value) \ + write_eeprom(addr, value) + +#define write_eeprom32(addr, value) // EEPROM is 512 bytes by default; it is autodetecte as 8KB if // 14bit address DMAs are made (this is done in the DMA handler). @@ -561,6 +567,16 @@ void function_cc write_eeprom(u32 unused_address, u32 value) \ value = readaddress##type(map, address & 0x7FFF) \ + +#define unmapped_rom_read8(addr) \ + (((addr) >> 1) >> (((addr) & 1) * 8)) & 0xFF + +#define unmapped_rom_read16(addr) \ + ((addr) >> 1) & 0xFFFF + +#define unmapped_rom_read32(addr) \ + ((((addr) & ~3) >> 1) & 0xFFFF) | (((((addr) & ~3) + 2) >> 1) << 16) + #define read_open8() \ if(!(reg[REG_CPSR] & 0x20)) \ value = read_memory8(reg[REG_PC] + 8 + (address & 0x03)); \ @@ -671,6 +687,12 @@ u32 function_cc read_eeprom(void) value = readaddress##type(oam_ram, address & 0x3FF); \ break; \ \ + case 0x0D: \ + if (backup_type == BACKUP_EEPROM) { \ + value = read_eeprom(); \ + break; \ + } \ + /* fallthrough */ \ case 0x08: \ case 0x09: \ case 0x0A: \ @@ -678,23 +700,13 @@ u32 function_cc read_eeprom(void) case 0x0C: \ /* gamepak ROM */ \ if((address & 0x1FFFFFF) >= gamepak_size) \ - value = 0; \ + value = unmapped_rom_read##type(address); \ else \ { \ read_memory_gamepak(type); \ } \ break; \ \ - case 0x0D: \ - if((address & 0x1FFFFFF) < gamepak_size) \ - { \ - read_memory_gamepak(type); \ - } \ - else \ - value = read_eeprom(); \ - \ - break; \ - \ case 0x0E: \ case 0x0F: \ read_backup##type(); \ @@ -1464,7 +1476,7 @@ void function_cc write_rtc(u32 address, u32 value) break; \ \ case 0x0D: \ - write_eeprom(address, value); \ + write_eeprom##type(address, value); \ break; \ \ case 0x0E: \ diff --git a/x86/x86_stub.S b/x86/x86_stub.S index d411f09..c46c8ab 100644 --- a/x86/x86_stub.S +++ b/x86/x86_stub.S @@ -223,6 +223,8 @@ ext_store_rtc8: # No RTC writes on byte or word access ext_store_rtc32: ext_store_backup16: # Backup (flash) accessed via byte writes ext_store_backup32: +ext_store_eeprom8: # EEPROM accesses are performed using 16 bit DMA +ext_store_eeprom32: ext_store_ignore: ret # ignore these writes @@ -277,7 +279,7 @@ cpu_sleep_loop: jmp lookup_pc # pc changes after a halt -ext_store_eeprom: +ext_store_eeprom16: CALL_FUNC(write_eeprom) # perform eeprom write ret @@ -568,7 +570,7 @@ return_to_main: ADDR_TYPE ext_store_ignore /* 0x0A gamepak, ignore */;\ ADDR_TYPE ext_store_ignore /* 0x0B gamepak, ignore */;\ ADDR_TYPE ext_store_ignore /* 0x0C gamepak, ignore */;\ - ADDR_TYPE ext_store_eeprom /* 0x0D EEPROM (possibly) */;\ + ADDR_TYPE ext_store_eeprom##asize /* 0x0D EEPROM (possibly) */;\ ADDR_TYPE ext_store_backup##asize /* 0x0E Flash ROM/SRAM */;\ ADDR_TYPE ext_store_ignore /* 0x0F ignore */;\ @@ -599,7 +601,7 @@ defsymbl(x86_table_data) ADDR_TYPE ext_store_ignore # 0x0A gamepak, ignore ADDR_TYPE ext_store_ignore # 0x0B gamepak, ignore ADDR_TYPE ext_store_ignore # 0x0C gamepak, ignore - ADDR_TYPE ext_store_eeprom # 0x0D EEPROM (possibly) + ADDR_TYPE ext_store_eeprom32 # 0x0D EEPROM (possibly) ADDR_TYPE ext_store_ignore # 0x0E Flash ROM/SRAM must be 8bit ADDR_TYPE ext_store_ignore # 0x0F ignore