Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }