private void InitMemoryDomains()
        {
            CreateMemoryDomain(LibSameboy.MemoryAreas.ROM, "ROM");
            CreateMemoryDomain(LibSameboy.MemoryAreas.RAM, "WRAM");
            CreateMemoryDomain(LibSameboy.MemoryAreas.CART_RAM, "CartRAM");
            CreateMemoryDomain(LibSameboy.MemoryAreas.VRAM, "VRAM");
            CreateMemoryDomain(LibSameboy.MemoryAreas.HRAM, "HRAM");
            CreateMemoryDomain(LibSameboy.MemoryAreas.IO, "MMIO");
            CreateMemoryDomain(LibSameboy.MemoryAreas.BOOTROM, "BIOS");
            CreateMemoryDomain(LibSameboy.MemoryAreas.OAM, "OAM");
            CreateMemoryDomain(LibSameboy.MemoryAreas.BGP, "BGP");
            CreateMemoryDomain(LibSameboy.MemoryAreas.OBP, "OBP");
            CreateMemoryDomain(LibSameboy.MemoryAreas.IE, "IE");

            // also add a special memory domain for the system bus, where calls get sent directly to the core each time
            _memoryDomains.Add(new MemoryDomainDelegate("System Bus", 65536, MemoryDomain.Endian.Little,
                                                        delegate(long addr)
            {
                if (addr < 0 || addr >= 65536)
                {
                    throw new ArgumentOutOfRangeException();
                }

                return(LibSameboy.sameboy_cpuread(SameboyState, (ushort)addr));
            },
                                                        delegate(long addr, byte val)
            {
                if (addr < 0 || addr >= 65536)
                {
                    throw new ArgumentOutOfRangeException();
                }

                LibSameboy.sameboy_cpuwrite(SameboyState, (ushort)addr, val);
            }, 1));

            MemoryDomains = new MemoryDomainList(_memoryDomains);
            _serviceProvider.Register(MemoryDomains);
        }