From a07e4c6c49c76d3c4b2500077a708410a8b73978 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 15:06:25 +0200 Subject: [PATCH 01/19] Add mem descriptors to libretro.h. --- libretro/libretro.h | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/libretro/libretro.h b/libretro/libretro.h index a51cfc06..ac7319e7 100755 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -180,6 +180,9 @@ extern "C" { // Video ram lets a frontend peek into a game systems video RAM (VRAM). #define RETRO_MEMORY_VIDEO_RAM 3 +// ROM lets a frontend poke a game system's main program. +#define RETRO_MEMORY_ROM 4 + // Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. enum retro_key { @@ -637,6 +640,104 @@ enum retro_mod // The core must pass an array of const struct retro_controller_info which is terminated with // a blanked out struct. Each element of the struct corresponds to an ascending port index to retro_set_controller_port_device(). // Even if special device types are set in the libretro core, libretro should only poll input based on the base input device types. +#define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) + // const struct retro_memory_map * -- + // This environment call lets a libretro core tell the frontend about the memory maps + // emulated by this core. This can be used to implement, for example, cheats. + // + // Should only be used by emulators; it doesn't make much sense for anything else. + // + // It is highly recommended to expose all relevant pointers through retro_get_memory_* as well. + // + // Can be called from retro_init and retro_load_game. + // + +#define RETRO_MEMDESC_CONST (1 << 0) // The frontend will never change this memory area once retro_load_game has returned. +#define RETRO_MEMDESC_BIGENDIAN (1 << 1) // The memory area contains big endian data. Default is little endian. +#define RETRO_MEMDESC_ALIGNED (1 << 2) // All memory access in this area is aligned to their own size, and no non-power-of-two sized data exists. +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. + //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; + size_t offset; + + //This is the location in the emulated address space where the mapping starts. + size_t start; + + //Which bits must be same as in 'start' for this mapping to apply. + //The first memory descriptor to claim a certain byte is the one that applies. + //A bit which is set in 'start' must also be set in this. + //Can be zero, in which case each byte is assumed mapped exactly once. In this case, 'len' must be a power of two. + size_t select; + + //If this is nonzero, the set bits are assumed not connected to the memory chip's address pins. + size_t disconnect; + + //This one tells the size of the current memory area. + //If, after start+disconnect are applied, the address is higher than this, the highest bit of the address is cleared. + //If the address is still too high, the next highest bit is cleared. + //Can be zero, in which case it's assumed to be infinite (as limited by 'select' and 'disconnect'). + size_t len; + + //To go from emulated address to physical address, the following order applies: + //Subtract 'start', pick off 'disconnect', apply 'len', add 'offset'. + + //The address space name must consist of only a-zA-Z0-9_-, should be as short as feasible (maximum length is 8 plus the NUL), + // and may not be any other address space plus one or more 0-9A-F at the end. + //However, multiple memory descriptors for the same address space is allowed, and the address + // space name can be empty. NULL is treated as empty. + //Address space names are case sensitive, but avoid lowercase if possible. + //The same pointer may exist in multiple address spaces. + //Examples: + // blank+blank - valid (multiple things may be mapped in the same namespace) + // 'Sp'+'Sp' - valid (multiple things may be mapped in the same namespace) + // 'A'+'B' - valid (neither is a prefix of each other) + // 'S'+blank - valid ('S' is not in 0-9A-F) + // 'a'+blank - valid ('a' is not in 0-9A-F) + // 'a'+'A' - valid (neither is a prefix of each other) + // 'AR'+blank - valid ('R' is not in 0-9A-F) + // 'ARB'+blank - valid (the B can't be part of the address either, because there is no namespace 'AR') + // blank+'B' - not valid, because it's ambigous which address space B1234 would refer to. + // The length can't be used for that purpose; the frontend may want to append arbitrary data to an address, without a separator. + const char * addrspace; +}; +//The frontend may use the largest value of 'start'+'select' in a certain namespace to infer the size of the address space. +//If the address space is larger than that, a mapping with .ptr=NULL should be at the end of the array, with .select set to all ones for as long as the address space is big. +//Sample descriptors (minus .ptr, and RETRO_MEMFLAG_ on the flags): +//SNES WRAM: +// .start=0x7E0000, .len=0x20000 +//(Note that this must be mapped before the ROM in most cases; some of the ROM mappers try to claim $7E0000, or at least $7E8000.) +//SNES SPC700 RAM: +// .addrspace="S", .len=0x10000 +//SNES WRAM mirrors: +// .flags=MIRROR, .start=0x000000, .select=0xC0E000, .len=0x2000 +// .flags=MIRROR, .start=0x800000, .select=0xC0E000, .len=0x2000 +//SNES WRAM mirrors, alternate equivalent descriptor: +// .flags=MIRROR, .select=0x40E000, .disconnect=~0x1FFF +//(Various similar constructions can be created by combining parts of the above two.) +//SNES LoROM (512KB, mirrored a couple of times): +// .flags=CONST, .start=0x008000, .select=0x408000, .disconnect=0x8000, .len=512*1024 +// .flags=CONST, .start=0x400000, .select=0x400000, .disconnect=0x8000, .len=512*1024 +//SNES HiROM (4MB): +// .flags=CONST, .start=0x400000, .select=0x400000, .len=4*1024*1024 +// .flags=CONST, .offset=0x8000, .start=0x008000, .select=0x408000, .len=4*1024*1024 +//SNES ExHiROM (8MB): +// .flags=CONST, .offset=0, .start=0xC00000, .select=0xC00000, .len=4*1024*1024 +// .flags=CONST, .offset=4*1024*1024, .start=0x400000, .select=0xC00000, .len=4*1024*1024 +// .flags=CONST, .offset=0x8000, .start=0x808000, .select=0xC08000, .len=4*1024*1024 +// .flags=CONST, .offset=4*1024*1024+0x8000, .start=0x008000, .select=0xC08000, .len=4*1024*1024 +//Clarify the size of the address space: +// .ptr=NULL, .select=0xFFFFFF +//.len can be implied by .select in many of them, but was included for clarity. + +struct retro_memory_map +{ + const struct retro_memory_descriptor * descriptors; + unsigned num_descriptors; +}; struct retro_controller_description { From 2313dc0ce49fb807765a9cef7e0a48e4ef4093ef Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 16:30:56 +0200 Subject: [PATCH 02/19] Start adding this. Those mapping functions will take quite a while to figure out... --- libretro/libretro.cpp | 31 +++++++++++ libretro/libretro.h | 4 +- memmap.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) 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) From bb7850dd39b068b20392233922878c16fbc1b3b5 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 17:08:05 +0200 Subject: [PATCH 03/19] WRAM works now. Gonna implement the rest of the descriptors now... --- libretro/libretro.cpp | 13 ------------- libretro/libretro.h | 1 + memmap.cpp | 22 +++++++++++----------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index b2383fd7..2e91fc38 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -328,19 +328,6 @@ void S9xAppendMapping(struct retro_memory_descriptor * desc) 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; diff --git a/libretro/libretro.h b/libretro/libretro.h index c62dcc94..e63aebb2 100755 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -663,6 +663,7 @@ struct retro_memory_descriptor { //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. + //It's recommended to minimize the number of descriptors if possible, but not mandatory. void * ptr; size_t offset; diff --git a/memmap.cpp b/memmap.cpp index cdb2d4b8..3b0b8797 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2787,7 +2787,7 @@ void CMemory::map_lorom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add desc.start=0;// desc.select=0x8000; desc.len=0;// - S9xAppendMapping(&desc); + //S9xAppendMapping(&desc); #endif } @@ -2816,7 +2816,7 @@ void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add desc.select=0;// desc.disconnect=0; desc.len=0;// - S9xAppendMapping(&desc); + //S9xAppendMapping(&desc); #endif } @@ -2845,7 +2845,7 @@ void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin desc.select=0;// desc.disconnect=0x8000; desc.len=0;// - S9xAppendMapping(&desc); + //S9xAppendMapping(&desc); #endif } @@ -2873,7 +2873,7 @@ void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin desc.select=0;// desc.disconnect=0x0000; desc.len=0;// - S9xAppendMapping(&desc); + //S9xAppendMapping(&desc); #endif } @@ -2896,11 +2896,11 @@ void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add 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;// + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.disconnect=0; + desc.len=0; +if (bank_s==0x7e || bank_s==0x7f) S9xAppendMapping(&desc); #endif } @@ -2975,7 +2975,7 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add desc.select=0;// desc.disconnect=0;// desc.len=0;// - S9xAppendMapping(&desc); + //S9xAppendMapping(&desc); #endif } @@ -2993,8 +2993,8 @@ void CMemory::map_System (void) void CMemory::map_WRAM (void) { // will overwrite others - map_space(0x7e, 0x7e, 0x0000, 0xffff, RAM); map_space(0x7f, 0x7f, 0x0000, 0xffff, RAM + 0x10000); + map_space(0x7e, 0x7e, 0x0000, 0xffff, RAM); } void CMemory::map_LoROMSRAM (void) From 2401f86259c647d23a79e6b96b82797a9d4a4deb Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 18:10:49 +0200 Subject: [PATCH 04/19] Almost done, only need to map up those kinds of SRAM. --- memmap.cpp | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index 3b0b8797..aa27f54f 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2783,11 +2783,11 @@ void CMemory::map_lorom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add 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); + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.disconnect=0x8000; + desc.len=size; + S9xAppendMapping(&desc); #endif } @@ -2811,12 +2811,10 @@ void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add 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); + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.len=size; + S9xAppendMapping(&desc); #endif } @@ -2840,12 +2838,12 @@ void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin struct retro_memory_descriptor desc = {0}; desc.flags=RETRO_MEMDESC_CONST; desc.ptr=ROM; - desc.offset=0;// - desc.start=0;// - desc.select=0;// + desc.offset=offset; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; desc.disconnect=0x8000; - desc.len=0;// - //S9xAppendMapping(&desc); + desc.len=size; + S9xAppendMapping(&desc); #endif } @@ -2868,12 +2866,11 @@ void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin 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); + desc.offset=offset; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.len=size; + S9xAppendMapping(&desc); #endif } @@ -2893,14 +2890,9 @@ void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } #ifdef __LIBRETRO__ struct retro_memory_descriptor desc = {0}; - desc.flags=0; desc.ptr=data; - desc.offset=0; desc.start=bank_s<<16 | addr_s; desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - desc.disconnect=0; - desc.len=0; -if (bank_s==0x7e || bank_s==0x7f) S9xAppendMapping(&desc); #endif } From 0a4ff3707436864263f10b88ab5b818c69d7bf58 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 18:37:16 +0200 Subject: [PATCH 05/19] That's the SRAM too. And SA-1 RAM. --- memmap.cpp | 80 ++++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index aa27f54f..a0fe24e0 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2917,57 +2917,35 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } #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); + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + if (type==MAP_LOROM_SRAM || type==MAP_SA1RAM) + { + desc.ptr=Memory.SRAM; + desc.disconnect=0x8000; + desc.len=Memory.SRAMMask+1; + S9xAppendMapping(&desc); + } + if (type==MAP_LOROM_SRAM_B) + { + desc.ptr=Multi.sramB; + desc.disconnect=0x8000; + desc.len=Multi.sramMaskB+1; + S9xAppendMapping(&desc); + } + if (type==MAP_HIROM_SRAM || type==MAP_RONLY_SRAM) + { + desc.ptr=Memory.SRAM; + desc.disconnect=0xF8E000; + desc.len=Memory.SRAMMask+1; + S9xAppendMapping(&desc); + } + if (type==MAP_BWRAM) + { + desc.ptr=Memory.BWRAM; + desc.disconnect=0xFFE000; + S9xAppendMapping(&desc); + } #endif } From 39fa17f9db8a76215d35f85844c5a3b4228fca42 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 19:11:28 +0200 Subject: [PATCH 06/19] Export the ROM pointer. --- libretro/libretro.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 2e91fc38..7d4bfa56 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -706,6 +706,9 @@ void* retro_get_memory_data(unsigned type) case RETRO_MEMORY_VIDEO_RAM: data = Memory.VRAM; break; + case RETRO_MEMORY_ROM: + data = Memory.ROM; + break; default: data = NULL; break; @@ -737,6 +740,9 @@ size_t retro_get_memory_size(unsigned type) case RETRO_MEMORY_VIDEO_RAM: size = 64 * 1024; break; + case RETRO_MEMORY_ROM: + size = Memory.CalculatedSize; + break; default: size = 0; break; From 4fc2d661a45383091e9a30b60c778e787a09ac51 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 19:24:20 +0200 Subject: [PATCH 07/19] We need the SRAM mask inside the map ROM function, or we tell the front that SRAM is one byte. I'll move it over. --- memmap.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index a0fe24e0..c19f7306 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2532,6 +2532,9 @@ void CMemory::InitROM (void) Map_Initialize(); CalculatedChecksum = 0; + // SRAM size + SRAMMask = SRAMSize ? ((1 << (SRAMSize + 3)) * 128) - 1 : 0; + if (HiROM) { if (Settings.BS) @@ -2662,9 +2665,6 @@ void CMemory::InitROM (void) *p = 0; } - // SRAM size - SRAMMask = SRAMSize ? ((1 << (SRAMSize + 3)) * 128) - 1 : 0; - // checksum if (!isChecksumOK || ((uint32) CalculatedSize > (uint32) (((1 << (ROMSize - 7)) * 128) * 1024))) { @@ -2921,6 +2921,7 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; if (type==MAP_LOROM_SRAM || type==MAP_SA1RAM) { +puts("BBB"); desc.ptr=Memory.SRAM; desc.disconnect=0x8000; desc.len=Memory.SRAMMask+1; From 62fd28d744986973b9d8671f0057936c8b650d58 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 19:25:00 +0200 Subject: [PATCH 08/19] Kill debug code. --- memmap.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/memmap.cpp b/memmap.cpp index c19f7306..bc32c933 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2921,7 +2921,6 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; if (type==MAP_LOROM_SRAM || type==MAP_SA1RAM) { -puts("BBB"); desc.ptr=Memory.SRAM; desc.disconnect=0x8000; desc.len=Memory.SRAMMask+1; From 73a4e459d151b8153915453756aae3786e6a41b3 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 19:28:56 +0200 Subject: [PATCH 09/19] Allow larger SRAM in HiROM. .len is enough to trim the size down properly anyways. --- memmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memmap.cpp b/memmap.cpp index bc32c933..96e9fdfe 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2936,7 +2936,7 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add if (type==MAP_HIROM_SRAM || type==MAP_RONLY_SRAM) { desc.ptr=Memory.SRAM; - desc.disconnect=0xF8E000; + desc.disconnect=0x00E000; desc.len=Memory.SRAMMask+1; S9xAppendMapping(&desc); } From d3ecdd353414c4fce283227d7b9831f24bf7cc47 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 20:02:49 +0200 Subject: [PATCH 10/19] Fix rather creepy crash. Merge those 64 mappings into one. --- libretro/libretro.cpp | 9 +- memmap.cpp | 192 +++++++++++++++++++++++++----------------- memmap.h | 12 +-- 3 files changed, 128 insertions(+), 85 deletions(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 7d4bfa56..6a79b8cd 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -320,12 +320,13 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) S9xApplyCheats(); } -static struct retro_memory_descriptor memorydesc[64]; +#define MAX_MAPS 256 +static struct retro_memory_descriptor memorydesc[MAX_MAPS]; 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)); + memcpy(&memorydesc[MAX_MAPS - (++memorydesc_c)], desc, sizeof(struct retro_memory_descriptor)); } bool retro_load_game(const struct retro_game_info *game) @@ -340,7 +341,7 @@ 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 }; + struct retro_memory_map map={ memorydesc+MAX_MAPS-memorydesc_c, memorydesc_c }; if (rom_loaded) environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &map); return rom_loaded; @@ -396,7 +397,7 @@ bool retro_load_game_special(unsigned game_type, break; } - struct retro_memory_map map={ memorydesc+64-memorydesc_c, memorydesc_c }; + struct retro_memory_map map={ memorydesc+MAX_MAPS-memorydesc_c, memorydesc_c }; if (rom_loaded) environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &map); return rom_loaded; diff --git a/memmap.cpp b/memmap.cpp index 96e9fdfe..d853d934 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2763,7 +2763,7 @@ uint32 CMemory::map_mirror (uint32 size, uint32 pos) return (mask + map_mirror(size - mask, pos - mask)); } -void CMemory::map_lorom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size) +void CMemory::map_lorom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, bool auto_export_map) { uint32 c, i, p, addr; @@ -2780,18 +2780,21 @@ void CMemory::map_lorom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } #ifdef __LIBRETRO__ - struct retro_memory_descriptor desc = {0}; - desc.flags=RETRO_MEMDESC_CONST; - desc.ptr=ROM; - desc.start=bank_s<<16 | addr_s; - desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - desc.disconnect=0x8000; - desc.len=size; - S9xAppendMapping(&desc); + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.disconnect=0x8000; + desc.len=size; + S9xAppendMapping(&desc); + } #endif } -void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size) +void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, bool auto_export_map) { uint32 c, i, p, addr; @@ -2808,17 +2811,20 @@ void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } #ifdef __LIBRETRO__ - struct retro_memory_descriptor desc = {0}; - desc.flags=RETRO_MEMDESC_CONST; - desc.ptr=ROM; - desc.start=bank_s<<16 | addr_s; - desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - desc.len=size; - S9xAppendMapping(&desc); + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.len=size; + S9xAppendMapping(&desc); + } #endif } -void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, uint32 offset) +void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, uint32 offset, bool auto_export_map) { uint32 c, i, p, addr; @@ -2835,19 +2841,22 @@ void CMemory::map_lorom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin } #ifdef __LIBRETRO__ - struct retro_memory_descriptor desc = {0}; - desc.flags=RETRO_MEMDESC_CONST; - desc.ptr=ROM; - desc.offset=offset; - desc.start=bank_s<<16 | addr_s; - desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - desc.disconnect=0x8000; - desc.len=size; - S9xAppendMapping(&desc); + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.offset=offset; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.disconnect=0x8000; + desc.len=size; + S9xAppendMapping(&desc); + } #endif } -void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, uint32 offset) +void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint32 size, uint32 offset, bool auto_export_map) { uint32 c, i, p, addr; @@ -2863,18 +2872,21 @@ void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin } } #ifdef __LIBRETRO__ - struct retro_memory_descriptor desc = {0}; - desc.flags=RETRO_MEMDESC_CONST; - desc.ptr=ROM; - desc.offset=offset; - desc.start=bank_s<<16 | addr_s; - desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - desc.len=size; - S9xAppendMapping(&desc); + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.flags=RETRO_MEMDESC_CONST; + desc.ptr=ROM; + desc.offset=offset; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.len=size; + S9xAppendMapping(&desc); + } #endif } -void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint8 *data) +void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, uint8 *data, bool auto_export_map) { uint32 c, i, p; @@ -2889,15 +2901,18 @@ void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } } #ifdef __LIBRETRO__ - struct retro_memory_descriptor desc = {0}; - desc.ptr=data; - desc.start=bank_s<<16 | addr_s; - desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - S9xAppendMapping(&desc); + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.ptr=data; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + S9xAppendMapping(&desc); + } #endif } -void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, int index, int type) +void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 addr_e, int index, int type, bool auto_export_map) { uint32 c, i, p; bool8 isROM, isRAM; @@ -2916,35 +2931,38 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } } #ifdef __LIBRETRO__ - struct retro_memory_descriptor desc = {0}; - desc.start=bank_s<<16 | addr_s; - desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - if (type==MAP_LOROM_SRAM || type==MAP_SA1RAM) + if (auto_export_map) { - desc.ptr=Memory.SRAM; - desc.disconnect=0x8000; - desc.len=Memory.SRAMMask+1; - S9xAppendMapping(&desc); - } - if (type==MAP_LOROM_SRAM_B) - { - desc.ptr=Multi.sramB; - desc.disconnect=0x8000; - desc.len=Multi.sramMaskB+1; - S9xAppendMapping(&desc); - } - if (type==MAP_HIROM_SRAM || type==MAP_RONLY_SRAM) - { - desc.ptr=Memory.SRAM; - desc.disconnect=0x00E000; - desc.len=Memory.SRAMMask+1; - S9xAppendMapping(&desc); - } - if (type==MAP_BWRAM) - { - desc.ptr=Memory.BWRAM; - desc.disconnect=0xFFE000; - S9xAppendMapping(&desc); + struct retro_memory_descriptor desc = {0}; + desc.start=bank_s<<16 | addr_s; + desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + if (type==MAP_LOROM_SRAM || type==MAP_SA1RAM) + { + desc.ptr=Memory.SRAM; + desc.disconnect=0x8000; + desc.len=Memory.SRAMMask+1; + S9xAppendMapping(&desc); + } + if (type==MAP_LOROM_SRAM_B) + { + desc.ptr=Multi.sramB; + desc.disconnect=0x8000; + desc.len=Multi.sramMaskB+1; + S9xAppendMapping(&desc); + } + if (type==MAP_HIROM_SRAM || type==MAP_RONLY_SRAM) + { + desc.ptr=Memory.SRAM; + desc.disconnect=0x00E000; + desc.len=Memory.SRAMMask+1; + S9xAppendMapping(&desc); + } + if (type==MAP_BWRAM) + { + desc.ptr=Memory.BWRAM; + desc.disconnect=0xFFE000; + S9xAppendMapping(&desc); + } } #endif } @@ -3303,7 +3321,19 @@ void CMemory::Map_SA1LoROMMap (void) map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); for (int c = 0x40; c < 0x80; c++) - map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000); + map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); + +#ifdef __LIBRETRO__ + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.ptr=SRAM; + desc.start=0x400000; + desc.select=0xC00000; + desc.disconnect=0xFE0000; + S9xAppendMapping(&desc); + } +#endif map_WRAM(); @@ -3339,13 +3369,25 @@ void CMemory::Map_GNEXTSA1LoROMMap (void) map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); - map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM); - map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); + map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); + map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); for (int c = 0x40; c < 0x80; c++) - map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000); + map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); + +#ifdef __LIBRETRO__ + if (auto_export_map) + { + struct retro_memory_descriptor desc = {0}; + desc.ptr=SRAM; + desc.start=0x400000; + desc.select=0xC00000; + desc.disconnect=0xFE0000; + S9xAppendMapping(&desc); + } +#endif // FIXME: untested! map_hirom_offset(0x70, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); diff --git a/memmap.h b/memmap.h index 0f943542..0ca1245d 100644 --- a/memmap.h +++ b/memmap.h @@ -295,12 +295,12 @@ struct CMemory void InitROM (void); uint32 map_mirror (uint32, uint32); - void map_lorom (uint32, uint32, uint32, uint32, uint32); - void map_hirom (uint32, uint32, uint32, uint32, uint32); - void map_lorom_offset (uint32, uint32, uint32, uint32, uint32, uint32); - void map_hirom_offset (uint32, uint32, uint32, uint32, uint32, uint32); - void map_space (uint32, uint32, uint32, uint32, uint8 *); - void map_index (uint32, uint32, uint32, uint32, int, int); + void map_lorom (uint32, uint32, uint32, uint32, uint32, bool = true); + void map_hirom (uint32, uint32, uint32, uint32, uint32, bool = true); + void map_lorom_offset (uint32, uint32, uint32, uint32, uint32, uint32, bool = true); + void map_hirom_offset (uint32, uint32, uint32, uint32, uint32, uint32, bool = true); + void map_space (uint32, uint32, uint32, uint32, uint8 *, bool = true); + void map_index (uint32, uint32, uint32, uint32, int, int, bool = true); void map_System (void); void map_WRAM (void); void map_LoROMSRAM (void); From dbd233128201991002b0caf1a2e1f83b00dbe416 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 20:28:19 +0200 Subject: [PATCH 11/19] Fix bad copypasta. --- memmap.cpp | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index d853d934..6cf4d936 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -3324,15 +3324,12 @@ void CMemory::Map_SA1LoROMMap (void) map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); #ifdef __LIBRETRO__ - if (auto_export_map) - { - struct retro_memory_descriptor desc = {0}; - desc.ptr=SRAM; - desc.start=0x400000; - desc.select=0xC00000; - desc.disconnect=0xFE0000; - S9xAppendMapping(&desc); - } + struct retro_memory_descriptor desc = {0}; + desc.ptr=SRAM; + desc.start=0x400000; + desc.select=0xC00000; + desc.disconnect=0xFE0000; + S9xAppendMapping(&desc); #endif map_WRAM(); @@ -3378,15 +3375,12 @@ void CMemory::Map_GNEXTSA1LoROMMap (void) map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); #ifdef __LIBRETRO__ - if (auto_export_map) - { - struct retro_memory_descriptor desc = {0}; - desc.ptr=SRAM; - desc.start=0x400000; - desc.select=0xC00000; - desc.disconnect=0xFE0000; - S9xAppendMapping(&desc); - } + struct retro_memory_descriptor desc = {0}; + desc.ptr=SRAM; + desc.start=0x400000; + desc.select=0xC00000; + desc.disconnect=0xFE0000; + S9xAppendMapping(&desc); #endif // FIXME: untested! From 2a9fbf0f24a566fc80bc3f5a02833c084c8dd937 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 20:53:27 +0200 Subject: [PATCH 12/19] Disconnect the bank byte from WRAM. It shouldn't be there. --- memmap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/memmap.cpp b/memmap.cpp index 6cf4d936..d3684d94 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2907,6 +2907,7 @@ void CMemory::map_space (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add desc.ptr=data; desc.start=bank_s<<16 | addr_s; desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; + desc.disconnect=0xFF0000; S9xAppendMapping(&desc); } #endif From 0fcda51be41219fcef6ce70ba08b2c95fb859398 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 21:17:07 +0200 Subject: [PATCH 13/19] Map some of those backwards, so the lower address shows up first in the descriptors. --- memmap.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index d3684d94..132de475 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2988,14 +2988,14 @@ void CMemory::map_WRAM (void) void CMemory::map_LoROMSRAM (void) { - map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM); map_index(0xf0, 0xff, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM); + map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM); } void CMemory::map_HiROMSRAM (void) { - map_index(0x20, 0x3f, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM); map_index(0xa0, 0xbf, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM); + map_index(0x20, 0x3f, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM); } void CMemory::map_DSP (void) @@ -3126,8 +3126,8 @@ void CMemory::Map_NoMAD1LoROMMap (void) map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize); map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize); - map_index(0x70, 0x7f, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM); map_index(0xf0, 0xff, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM); + map_index(0x70, 0x7f, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM); map_WRAM(); @@ -3178,10 +3178,10 @@ void CMemory::Map_SRAM512KLoROMMap (void) map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize); map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize); - map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); - map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x8000); - map_space(0x72, 0x72, 0x0000, 0xffff, SRAM + 0x10000); map_space(0x73, 0x73, 0x0000, 0xffff, SRAM + 0x18000); + map_space(0x72, 0x72, 0x0000, 0xffff, SRAM + 0x10000); + map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x8000); + map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); map_WRAM(); @@ -3202,14 +3202,14 @@ void CMemory::Map_SufamiTurboLoROMMap (void) if (Multi.sramSizeA) { - map_index(0x60, 0x63, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM); map_index(0xe0, 0xe3, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM); + map_index(0x60, 0x63, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM); } if (Multi.sramSizeB) { - map_index(0x70, 0x73, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM); map_index(0xf0, 0xf3, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM); + map_index(0x70, 0x73, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM); } map_WRAM(); @@ -3233,8 +3233,8 @@ void CMemory::Map_SufamiTurboPseudoLoROMMap (void) // I don't care :P map_space(0x60, 0x63, 0x8000, 0xffff, SRAM - 0x8000); map_space(0xe0, 0xe3, 0x8000, 0xffff, SRAM - 0x8000); - map_space(0x70, 0x73, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000); - map_space(0xf0, 0xf3, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000); + map_space(0x70, 0x73, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000, false); + map_space(0xf0, 0xf3, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000, false); map_WRAM(); @@ -3262,8 +3262,8 @@ void CMemory::Map_SuperFXLoROMMap (void) map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000); map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000); - map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000); + map_space(0x70, 0x70, 0x0000, 0xffff, SRAM); map_WRAM(); @@ -3316,10 +3316,10 @@ void CMemory::Map_SA1LoROMMap (void) map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0); - map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM); - map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); + map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); + map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); for (int c = 0x40; c < 0x80; c++) map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); From dc18bca804f8636c433e8a0d7d44308921e0a731 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 21:23:14 +0200 Subject: [PATCH 14/19] FillRAM (I-RAM) is probably more important than BW-RAM. --- memmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index 132de475..ad11ca44 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -3316,10 +3316,10 @@ void CMemory::Map_SA1LoROMMap (void) map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0); - map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM); - map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); + map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM); + map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); for (int c = 0x40; c < 0x80; c++) map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); From 2a65558d516f97266148354b7b7f9f1d7df40318 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 21:27:12 +0200 Subject: [PATCH 15/19] Fix this. Apparently this one is variable. --- memmap.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index ad11ca44..ce8165d3 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2960,8 +2960,8 @@ void CMemory::map_index (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add } if (type==MAP_BWRAM) { - desc.ptr=Memory.BWRAM; - desc.disconnect=0xFFE000; + desc.ptr=Memory.SRAM;//this one varies, but we can't use variable maps in this system. + desc.disconnect=0xFFE000;//It's the same as SRAM, anyways. Let's point it to there and let the front ignore it. S9xAppendMapping(&desc); } } @@ -3316,10 +3316,10 @@ void CMemory::Map_SA1LoROMMap (void) map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0); - map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); - map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM); map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM); + map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); + map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O); for (int c = 0x40; c < 0x80; c++) map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000, false); From 3ba8c3bb2d58c55b569ca6746204cf90e445d970 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Wed, 28 May 2014 22:44:52 +0200 Subject: [PATCH 16/19] Trim trailing spaces. --- libretro/libretro.cpp | 2 +- libretro/libretro.h | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 6a79b8cd..c9b56ea4 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -320,7 +320,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) S9xApplyCheats(); } -#define MAX_MAPS 256 +#define MAX_MAPS 32 static struct retro_memory_descriptor memorydesc[MAX_MAPS]; static unsigned memorydesc_c; void S9xAppendMapping(struct retro_memory_descriptor * desc) diff --git a/libretro/libretro.h b/libretro/libretro.h index e63aebb2..6de87836 100755 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -642,12 +642,11 @@ enum retro_mod // Even if special device types are set in the libretro core, libretro should only poll input based on the base input device types. #define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) // const struct retro_memory_map * -- - // This environment call lets a libretro core tell the frontend about the memory maps - // emulated by this core. This can be used to implement, for example, cheats. + // This environment call lets a libretro core tell the frontend about the memory maps this + // core emulates. This can be used to implement, for example, cheats in a core-agnostic way. // // Should only be used by emulators; it doesn't make much sense for anything else. - // - // It is highly recommended to expose all relevant pointers through retro_get_memory_* as well. + // It is recommended to expose all relevant pointers through retro_get_memory_* as well. // // Can be called from retro_init and retro_load_game. // @@ -657,7 +656,7 @@ enum retro_mod #define RETRO_MEMDESC_ALIGNED (1 << 2) // All memory access in this area is aligned to their own size, and no non-power-of-two sized data exists. struct retro_memory_descriptor { uint64_t flags; - + //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. @@ -666,28 +665,28 @@ struct retro_memory_descriptor { //It's recommended to minimize the number of descriptors if possible, but not mandatory. void * ptr; size_t offset; - + //This is the location in the emulated address space where the mapping starts. size_t start; - + //Which bits must be same as in 'start' for this mapping to apply. //The first memory descriptor to claim a certain byte is the one that applies. //A bit which is set in 'start' must also be set in this. //Can be zero, in which case each byte is assumed mapped exactly once. In this case, 'len' must be a power of two. size_t select; - + //If this is nonzero, the set bits are assumed not connected to the memory chip's address pins. size_t disconnect; - + //This one tells the size of the current memory area. //If, after start+disconnect are applied, the address is higher than this, the highest bit of the address is cleared. //If the address is still too high, the next highest bit is cleared. //Can be zero, in which case it's assumed to be infinite (as limited by 'select' and 'disconnect'). size_t len; - + //To go from emulated address to physical address, the following order applies: //Subtract 'start', pick off 'disconnect', apply 'len', add 'offset'. - + //The address space name must consist of only a-zA-Z0-9_-, should be as short as feasible (maximum length is 8 plus the NUL), // and may not be any other address space plus one or more 0-9A-F at the end. //However, multiple memory descriptors for the same address space is allowed, and the address From 5e2b73d26a7ec472b6341ba26e7d6f0288a81abe Mon Sep 17 00:00:00 2001 From: Alcaro Date: Fri, 30 May 2014 11:57:44 +0200 Subject: [PATCH 17/19] Add minimum size flags. --- libretro/libretro.h | 11 ++++++++--- memmap.cpp | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libretro/libretro.h b/libretro/libretro.h index 6de87836..c6ac4c62 100755 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -651,9 +651,14 @@ enum retro_mod // Can be called from retro_init and retro_load_game. // -#define RETRO_MEMDESC_CONST (1 << 0) // The frontend will never change this memory area once retro_load_game has returned. -#define RETRO_MEMDESC_BIGENDIAN (1 << 1) // The memory area contains big endian data. Default is little endian. -#define RETRO_MEMDESC_ALIGNED (1 << 2) // All memory access in this area is aligned to their own size, and no non-power-of-two sized data exists. +#define RETRO_MEMDESC_CONST (1 << 0) // The frontend will never change this memory area once retro_load_game has returned. +#define RETRO_MEMDESC_BIGENDIAN (1 << 1) // The memory area contains big endian data. Default is little endian. +#define RETRO_MEMDESC_ALIGN_2 (1 << 16) // All memory access in this area is aligned to their own size, or 2, whichever is smaller. +#define RETRO_MEMDESC_ALIGN_4 (2 << 16) +#define RETRO_MEMDESC_ALIGN_8 (3 << 16) +#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) // All memory in this region is accessed at least 2 bytes at the time. +#define RETRO_MEMDESC_MINSIZE_4 (2 << 24) +#define RETRO_MEMDESC_MINSIZE_8 (3 << 24) struct retro_memory_descriptor { uint64_t flags; diff --git a/memmap.cpp b/memmap.cpp index ce8165d3..911c6182 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -3330,6 +3330,7 @@ void CMemory::Map_SA1LoROMMap (void) desc.start=0x400000; desc.select=0xC00000; desc.disconnect=0xFE0000; + desc.len=0x20000; S9xAppendMapping(&desc); #endif From 588135d4aae75bb35f6dba1aeb4ec19b74b36509 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Fri, 30 May 2014 12:12:00 +0200 Subject: [PATCH 18/19] This one doesn't really look right. --- memmap.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index 911c6182..771dd06e 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2816,9 +2816,10 @@ void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add struct retro_memory_descriptor desc = {0}; desc.flags=RETRO_MEMDESC_CONST; desc.ptr=ROM; + desc.offset=map_mirror(size, bank_s<<16 | addr_s); desc.start=bank_s<<16 | addr_s; desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; - desc.len=size; + desc.len=size - desc.offset; S9xAppendMapping(&desc); } #endif @@ -2877,7 +2878,7 @@ void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin struct retro_memory_descriptor desc = {0}; desc.flags=RETRO_MEMDESC_CONST; desc.ptr=ROM; - desc.offset=offset; + desc.offset=map_mirror(size, offset + (bank_s<<16 | addr_s)); desc.start=bank_s<<16 | addr_s; desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; desc.len=size; From 5df4ad7082cb17fccbc078af63115baf75a0fa62 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Fri, 30 May 2014 12:26:30 +0200 Subject: [PATCH 19/19] snes9x's internal memory maps are quite weird. I think this is the right way to handle hirom. --- memmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/memmap.cpp b/memmap.cpp index 771dd06e..cb0b35b3 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -2816,7 +2816,7 @@ void CMemory::map_hirom (uint32 bank_s, uint32 bank_e, uint32 addr_s, uint32 add struct retro_memory_descriptor desc = {0}; desc.flags=RETRO_MEMDESC_CONST; desc.ptr=ROM; - desc.offset=map_mirror(size, bank_s<<16 | addr_s); + desc.offset=map_mirror(size, addr_s); desc.start=bank_s<<16 | addr_s; desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; desc.len=size - desc.offset; @@ -2878,7 +2878,7 @@ void CMemory::map_hirom_offset (uint32 bank_s, uint32 bank_e, uint32 addr_s, uin struct retro_memory_descriptor desc = {0}; desc.flags=RETRO_MEMDESC_CONST; desc.ptr=ROM; - desc.offset=map_mirror(size, offset + (bank_s<<16 | addr_s)); + desc.offset=map_mirror(size, offset + addr_s); desc.start=bank_s<<16 | addr_s; desc.select=(bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF; desc.len=size;