diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 8d9c6ec7..b2383fd7 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -320,8 +320,31 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) S9xApplyCheats(); } +static struct retro_memory_descriptor memorydesc[64]; +static unsigned memorydesc_c; +void S9xAppendMapping(struct retro_memory_descriptor * desc) +{ + //do it backwards - snes9x defines the last one to win, while we define the first one to win + memcpy(&memorydesc[64 - (++memorydesc_c)], desc, sizeof(struct retro_memory_descriptor)); +} + +//#define RETRO_MEMDESC_CONST (1 << 0) +//struct retro_memory_descriptor { +// uint64_t flags; +// void * ptr; +// size_t offset; +// size_t start; +// size_t select; +// size_t disconnect; +// size_t len; +// const char * addrspace; +//}; +//void S9xAppendMapping(struct retro_memory_descriptor desc); + bool retro_load_game(const struct retro_game_info *game) { + memorydesc_c = 0; + if(game->data == NULL && game->size == 0 && game->path != NULL) rom_loaded = Memory.LoadROM(game->path); else @@ -330,6 +353,9 @@ bool retro_load_game(const struct retro_game_info *game) if (!rom_loaded && log_cb) log_cb(RETRO_LOG_ERROR, "[libretro]: Rom loading failed...\n"); + struct retro_memory_map map={ memorydesc+64-memorydesc_c, memorydesc_c }; + if (rom_loaded) environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &map); + return rom_loaded; } @@ -339,6 +365,8 @@ void retro_unload_game(void) bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) { + memorydesc_c = 0; + switch (game_type) { case RETRO_GAME_TYPE_BSX: @@ -380,6 +408,9 @@ bool retro_load_game_special(unsigned game_type, rom_loaded = false; break; } + + struct retro_memory_map map={ memorydesc+64-memorydesc_c, memorydesc_c }; + if (rom_loaded) environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &map); return rom_loaded; } diff --git a/libretro/libretro.h b/libretro/libretro.h index ac7319e7..c62dcc94 100755 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -658,7 +658,9 @@ enum retro_mod struct retro_memory_descriptor { uint64_t flags; - //Pointer to the start of the relevant ROM or RAM chip. Do not do math on this; the frontend may group things with identical pointers together. + //Pointer to the start of the relevant ROM or RAM chip. + //It's strongly recommended to use 'offset' if possible, rather than doing math on the pointer. + //If the same byte is mapped my multiple descriptors, their descriptors must have the same pointer. //If 'start' does not point to the first byte in the pointer, put the difference in 'offset' instead. //May be NULL if there's nothing usable here (e.g. hardware registers and open bus). No flags should be set if the pointer is NULL. void * ptr; diff --git a/memmap.cpp b/memmap.cpp index fa1230f1..cdb2d4b8 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -201,6 +201,11 @@ #include "movie.h" #include "display.h" +#ifdef __LIBRETRO__ +#include "libretro.h" +void S9xAppendMapping(struct retro_memory_descriptor * desc); +#endif + #ifndef SET_UI_COLOR #define SET_UI_COLOR(r, g, b) ; #endif @@ -2773,6 +2778,17 @@ void CMemory::map_lorom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add BlockIsRAM[p] = FALSE; } } + +#ifdef __LIBRETRO__ + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.offset=0;// + desc.start=0;// + desc.select=0x8000; + desc.len=0;// + S9xAppendMapping(&desc); +#endif } void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size) @@ -2790,6 +2806,18 @@ void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add BlockIsRAM[p] = FALSE; } } + +#ifdef __LIBRETRO__ + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.offset=0;// + desc.start=0;// + desc.select=0;// + desc.disconnect=0; + desc.len=0;// + S9xAppendMapping(&desc); +#endif } void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, uint32 offset) @@ -2807,6 +2835,18 @@ void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin BlockIsRAM[p] = FALSE; } } + +#ifdef __LIBRETRO__ + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.offset=0;// + desc.start=0;// + desc.select=0;// + desc.disconnect=0x8000; + desc.len=0;// + S9xAppendMapping(&desc); +#endif } void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, uint32 offset) @@ -2824,6 +2864,17 @@ void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin BlockIsRAM[p] = FALSE; } } +#ifdef __LIBRETRO__ + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.offset=0;// + desc.start=0;// + desc.select=0;// + desc.disconnect=0x0000; + desc.len=0;// + S9xAppendMapping(&desc); +#endif } void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint8 *data) @@ -2840,6 +2891,18 @@ void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add BlockIsRAM[p] = TRUE; } } +#ifdef __LIBRETRO__ + struct retro_memory_descriptor desc = {0}; + desc.flags=0; + desc.ptr=data; + desc.offset=0; + if (data == RAM+0x10000) { desc.ptr=RAM; desc.offset=0x10000; } + desc.start=0;// + desc.select=0;// + desc.disconnect=0;// + desc.len=0;// + S9xAppendMapping(&desc); +#endif } void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, int index, int type) @@ -2860,6 +2923,60 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add BlockIsRAM[p] = isRAM; } } +#ifdef __LIBRETRO__ + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=NULL;//this function maps funky stuff like hardware regs, but also various SRAM +//the following should be handled: +/* + case CMemory::MAP_LOROM_SRAM: + if (Memory.SRAMMask) + { + *(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)) = Byte; + CPU.SRAMModified = TRUE; + } + + addCyclesInMemoryAccess; + return; + + case CMemory::MAP_LOROM_SRAM_B: + if (Multi.sramMaskB) + { + *(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)) = Byte; + CPU.SRAMModified = TRUE; + } + + addCyclesInMemoryAccess; + return; + + case CMemory::MAP_HIROM_SRAM: + if (Memory.SRAMMask) + { + *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = Byte; + CPU.SRAMModified = TRUE; + } + + addCyclesInMemoryAccess; + return; + + case CMemory::MAP_BWRAM: + *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte; + CPU.SRAMModified = TRUE; + addCyclesInMemoryAccess; + return; + + case CMemory::MAP_SA1RAM: + *(Memory.SRAM + (Address & 0xffff)) = Byte; + addCyclesInMemoryAccess; + return; +*/ + desc.offset=0;// + desc.start=0;// + desc.select=0;// + desc.disconnect=0;// + desc.len=0;// + S9xAppendMapping(&desc); +#endif } void CMemory::map_System (void)