private unsafe void MakeMemoryDomain(string name, LibsnesApi.SNES_MEMORY id, MemoryDomain.Endian endian, int byteSize = 1) { int size = Api.QUERY_get_memory_size(id); // if this type of memory isn't available, don't make the memory domain (most commonly save ram) if (size == 0) { return; } byte *blockPtr = Api.QUERY_get_memory_data(id); var md = new MemoryDomainIntPtrMonitor(name, MemoryDomain.Endian.Little, (IntPtr)blockPtr, size, id != LibsnesApi.SNES_MEMORY.CARTRIDGE_ROM, // hack: for just this one memory area, it will be readonly byteSize, Api); _memoryDomainList.Add(md); }
private unsafe void MakeMemoryDomain(string name, LibsnesApi.SNES_MEMORY id, MemoryDomain.Endian endian, int byteSize = 1) { int size = Api.QUERY_get_memory_size(id); int mask = size - 1; bool pow2 = Util.IsPowerOfTwo(size); // if this type of memory isnt available, dont make the memory domain (most commonly save ram) if (size == 0) { return; } byte *blockptr = Api.QUERY_get_memory_data(id); MemoryDomain md; if (id == LibsnesApi.SNES_MEMORY.OAM) { // OAM is actually two differently sized banks of memory which arent truly considered adjacent. // maybe a better way to visualize it is with an empty bus and adjacent banks // so, we just throw away everything above its size of 544 bytes if (size != 544) { throw new InvalidOperationException("oam size isnt 544 bytes.. wtf?"); } md = new MemoryDomainDelegate( name, size, endian, addr => addr < 544 ? blockptr[addr] : (byte)0x00, (addr, value) => { if (addr < 544) { blockptr[addr] = value; } }, byteSize); } else if (pow2) { md = new MemoryDomainDelegate( name, size, endian, addr => blockptr[addr & mask], (addr, value) => blockptr[addr & mask] = value, byteSize); } else { md = new MemoryDomainDelegate( name, size, endian, addr => blockptr[addr % size], (addr, value) => blockptr[addr % size] = value, byteSize); } _memoryDomainList.Add(md); }
private MemoryDomain MakeMemoryDomain(string name, mupen64plusApi.N64_MEMORY id, MemoryDomain.Endian endian) { int size = api.get_memory_size(id); //if this type of memory isnt available, dont make the memory domain if (size == 0) { return(null); } IntPtr memPtr = api.get_memory_ptr(id); var md = new MemoryDomain( name, size, endian, delegate(int addr) { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } return(Marshal.ReadByte(memPtr, addr)); }, delegate(int addr, byte val) { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } Marshal.WriteByte(memPtr + addr, val); }); _memoryDomains.Add(md); return(md); }
private void MakeMemoryDomain(string name, mupen64plusApi.N64_MEMORY id, MemoryDomain.Endian endian, bool swizzled = false) { int size = api.get_memory_size(id); //if this type of memory isnt available, don't make the memory domain if (size == 0) { return; } IntPtr memPtr = api.get_memory_ptr(id); Func <long, byte> peekByte; Action <long, byte> pokeByte; if (swizzled) { peekByte = addr => { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } return(Marshal.ReadByte(memPtr, (int)(addr ^ 3))); }; pokeByte = (addr, val) => { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } Marshal.WriteByte(memPtr, (int)(addr ^ 3), val); }; } else { peekByte = addr => { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } return(Marshal.ReadByte(memPtr, (int)(addr))); }; pokeByte = (addr, val) => { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } Marshal.WriteByte(memPtr, (int)(addr), val); }; } var md = new MemoryDomainDelegate(name, size, endian, peekByte, pokeByte, 4); _memoryDomains.Add(md); }
private void InitMemoryDomains() { var domains = new List <MemoryDomain>(); _systemBusAddressShift = LibMAME.mame_lua_get_int(MAMELuaCommand.GetSpaceAddressShift); var size = (long)LibMAME.mame_lua_get_double(MAMELuaCommand.GetSpaceAddressMask) + 1; var dataWidth = LibMAME.mame_lua_get_int(MAMELuaCommand.GetSpaceDataWidth) >> 3; // mame returns in bits var endianString = MameGetString(MAMELuaCommand.GetSpaceEndianness); MemoryDomain.Endian endian = MemoryDomain.Endian.Unknown; if (endianString == "little") { endian = MemoryDomain.Endian.Little; } else if (endianString == "big") { endian = MemoryDomain.Endian.Big; } var mapCount = LibMAME.mame_lua_get_int(MAMELuaCommand.GetSpaceMapCount); for (int i = 1; i <= mapCount; i++) { var read = MameGetString($"return { MAMELuaCommand.SpaceMap }[{ i }].readtype"); var write = MameGetString($"return { MAMELuaCommand.SpaceMap }[{ i }].writetype"); if (read == "ram" && write == "ram" /* || read == "rom" */) { var firstOffset = LibMAME.mame_lua_get_int($"return { MAMELuaCommand.SpaceMap }[{ i }].offset"); var lastOffset = LibMAME.mame_lua_get_int($"return { MAMELuaCommand.SpaceMap }[{ i }].endoff"); var name = $"{ read.ToUpper() } { firstOffset:X}-{ lastOffset:X}"; domains.Add(new MemoryDomainDelegate(name, lastOffset - firstOffset + 1, endian, delegate(long addr) { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } _memAccess = true; _mamePeriodicComplete.WaitOne(); addr += firstOffset; var val = (byte)LibMAME.mame_lua_get_int($"{ MAMELuaCommand.GetSpace }:read_u8({ addr << _systemBusAddressShift })"); _memoryAccessComplete.Set(); _memAccess = false; return(val); }, read == "rom" ? (Action <long, byte>) null : delegate(long addr, byte val) { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } _memAccess = true; _mamePeriodicComplete.WaitOne(); addr += firstOffset; LibMAME.mame_lua_execute($"{ MAMELuaCommand.GetSpace }:write_u8({ addr << _systemBusAddressShift }, { val })"); _memoryAccessComplete.Set(); _memAccess = false; }, dataWidth)); } } domains.Add(new MemoryDomainDelegate("System Bus", size, endian, delegate(long addr) { if (addr < 0 || addr >= size) { throw new ArgumentOutOfRangeException(); } _memAccess = true; _mamePeriodicComplete.WaitOne(); var val = (byte)LibMAME.mame_lua_get_int($"{ MAMELuaCommand.GetSpace }:read_u8({ addr << _systemBusAddressShift })"); _memoryAccessComplete.Set(); _memAccess = false; return(val); }, null, dataWidth)); _memoryDomains = new MemoryDomainList(domains); (ServiceProvider as BasicServiceProvider).Register <IMemoryDomains>(_memoryDomains); }