コード例 #1
0
ファイル: Mapper003.cs プロジェクト: rlzicar/Nesemuto
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            bool isPpuAddr = addr < 0x3fff;

            if (isPpuAddr)
            {
                if (TryAccessNameTable(addr, mode, ref value))
                {
                    return(value);
                }

                return(ChrRom[m_ChrBankOffset + addr]);
            }

            bool isChrBankSelectAddr = addr >= 0x8000 && addr <= 0xffff;

            if (mode == MemoryAccessMode.Write && isChrBankSelectAddr)
            {
                var bank = value % m_BankCount;
                m_ChrBankOffset = bank * 0x2000;
                return(0);
            }

            return(Mapper.Access(PrgRom, addr % m_PrgSize, mode, value));
        }
コード例 #2
0
ファイル: Mapper066.cs プロジェクト: rlzicar/Nesemuto
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            bool isBankSelectAddr = addr >= 0x8000 && addr <= 0xffff;

            if (mode == MemoryAccessMode.Write && isBankSelectAddr)
            {
                var chrBank = value & 3;
                var prgBank = (value >> 4) & 3;
                m_ChrBankOffset = 0x2000 * chrBank;
                m_PrgBankOffset = 0x8000 * prgBank - 0x8000;
            }

            if (TryAccessNameTable(addr, mode, ref value))
            {
                return(value);
            }

            bool isChrAddr = addr <= 0x1fff;

            if (isChrAddr)
            {
                return(Access(ChrRom, addr + m_ChrBankOffset, mode, value));
            }

            return(Access(PrgRom, addr + m_PrgBankOffset, mode, value));
        }
コード例 #3
0
        private void WritetoMemoryOrPort(
            ushort address,
            byte value,
            IMemory memory,
            MemoryAccessMode accessMode,
            MemoryAccessEventType beforeEventType,
            MemoryAccessEventType afterEventType,
            byte waitStates)
        {
            var beforeEventArgs = FireMemoryAccessEvent(beforeEventType, address, value);

            if (!beforeEventArgs.CancelMemoryAccess &&
                (accessMode == MemoryAccessMode.ReadAndWrite || accessMode == MemoryAccessMode.WriteOnly))
            {
                memory[address] = beforeEventArgs.Value;
            }

            if (executionContext != null)
            {
                executionContext.AccummulatedMemoryWaitStates += waitStates;
            }

            FireMemoryAccessEvent(
                afterEventType,
                address,
                beforeEventArgs.Value,
                beforeEventArgs.LocalUserState,
                beforeEventArgs.CancelMemoryAccess);
        }
コード例 #4
0
ファイル: Mapper007.cs プロジェクト: rlzicar/Nesemuto
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            bool isPrgAddr        = addr >= 0x8000 && addr <= 0xffff;
            bool isBankSelectAddr = mode == MemoryAccessMode.Write && isPrgAddr;

            if (isBankSelectAddr)
            {
                var bank = value & 0xf;
                m_PrgBankOffset = (bank % m_BankCount) * 0x8000 - 0x8000;
                var mirroring = (value >> 4) & 1;
                Mirroring = mirroring == 0 ? Mirroring.ScreenA : Mirroring.ScreenB;
                return(0);
            }

            if (isPrgAddr)
            {
                var finalAddr = m_PrgBankOffset + addr;
                return(PrgRom[finalAddr]);
            }

            if (TryAccessNameTable(addr, mode, ref value))
            {
                return(value);
            }

            bool isChrAddr = addr <= 0x1fff;

            if (isChrAddr)
            {
                return(Access(ChrRom, addr, mode, value));
            }

            return(0x0);
        }
コード例 #5
0
ファイル: Ppu.cs プロジェクト: rlzicar/Nesemuto
        public byte AccessPalette(int addr, MemoryAccessMode mode, byte value)
        {
            bool read  = mode == MemoryAccessMode.Read;
            bool write = !read;

            if (addr >= 0x3f20)
            {
                addr = (0x3f00 + addr % 0x20);
            }
            else if (addr >= 0x3f10)
            {
                bool shouldMirror = addr == 0x3f10 || addr == 0x3f14 || addr == 0x3f18 || addr == 0x3f1c;
                if (shouldMirror)
                {
                    addr -= 0x10;
                }
            }

            bool isBackdropAddr = addr == 0x3f04 || addr == 0x3f08 || addr == 0x3f0c;

            if (read && isBackdropAddr)
            {
                addr = 0x3f00;
            }

            if (write)
            {
                m_Palettes[addr - 0x3f00] = value;
                return(0);
            }

            return((byte)m_Palettes[addr - 0x3f00]);
        }
コード例 #6
0
        protected static byte Access(byte[] data, int addr, MemoryAccessMode mode, byte value)
        {
            if (mode == MemoryAccessMode.Read)
            {
                return(data[addr]);
            }

            data[addr] = value;
            return(0);
        }
コード例 #7
0
 private void SetAccessMode(byte address, MemoryAccessMode accessMode, bool isPort)
 {
     if (isPort)
     {
         Sut.SetPortsSpaceAccessMode(address, 1, accessMode);
     }
     else
     {
         Sut.SetMemoryAccessMode(address, 1, accessMode);
     }
 }
コード例 #8
0
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            bool isRegAddr = addr >= 0x8000 && addr <= 0xffff;

            if (isRegAddr && mode == MemoryAccessMode.Write)
            {
                var highBit   = ((addr >> 14) & 1) << 6;
                var mirroring = (addr >> 13) & 1;
                Mirroring = mirroring == 0 ? Mirroring.Vertical : Mirroring.Horizontal;
                m_PrgMode = (addr >> 12) & 1;
                m_PrgBank = ((addr >> 6) & 0x3f) | highBit;
                m_ChrBank = (addr & 0x3f) | highBit;
                if (m_PrgMode == 0)
                {
                    m_PrgBank >>= 1;
                }

                return(0);
            }

            bool isPrgAddr = addr >= 0x8000;

            if (isPrgAddr && mode == MemoryAccessMode.Read)
            {
                switch (m_PrgMode)
                {
                case 0:
                    return(PrgRom[m_PrgBank * 0x8000 + (addr - 0x8000)]);

                case 1:
                    return(addr >= 0xc000
                            ? PrgRom[m_PrgBank * 0x4000 + (addr - 0xc000)]
                            : PrgRom[m_PrgBank * 0x4000 + (addr - 0x8000)]);
                }
            }

            if (TryAccessNameTable(addr, mode, ref value))
            {
                return(value);
            }

            var isChrAddr = addr < 0x8000;

            if (isChrAddr && mode == MemoryAccessMode.Read)
            {
                return(ChrRom[m_ChrBank * 0x2000 + addr]);
            }

            return(0);
        }
コード例 #9
0
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            if (TryAccessNameTable(addr, mode, ref value))
            {
                return(value);
            }

            bool isChrAddr = addr <= 0x1fff;

            if (isChrAddr)
            {
                return(Mapper.Access(ChrRom, addr, mode, value));
            }

            return(PrgRom[addr % m_PrgSize]);
        }
コード例 #10
0
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            bool isCpuAddr = addr > 0x3fff;

            if (isCpuAddr)
            {
                bool isFixedPrgAddr = addr >= 0xc000 && addr <= 0xffff;
                if (mode == MemoryAccessMode.Read && isFixedPrgAddr)
                {
                    int finalAddr = m_FinalBankOffset + addr;
                    return(PrgRom[finalAddr]);
                }

                bool isSwitchableBankAddr = addr >= 0x8000 && addr <= 0xbfff;
                if (mode == MemoryAccessMode.Read && isSwitchableBankAddr)
                {
                    return(PrgRom[m_SelectedBankOffset + addr]);
                }

                bool isBankSelectRegisterAddr = addr >= 0x8000 && addr <= 0xffff;
                if (mode == MemoryAccessMode.Write && isBankSelectRegisterAddr)
                {
                    m_SelectedBankOffset = (value & 0xf) % m_BankCount * 0x4000 - 0x8000;
                    return(0);
                }
            }
            else
            {
                bool isChrRomAddr = addr <= 0x1fff;
                if (isChrRomAddr)
                {
                    return(Mapper.Access(ChrRom, addr, mode, value));
                }

                if (TryAccessNameTable(addr, mode, ref value))
                {
                    return(value);
                }
            }

            return(0);
        }
コード例 #11
0
        public InstructionReader(MemoryAccessMode accessMode)
        {
            switch (accessMode)
            {
            case MemoryAccessMode.Physical:
                m_Source = Machine.Current.Memory; break;

            case MemoryAccessMode.DebugVirtual:
                m_Source = new VMemViewStream(); break;

            case MemoryAccessMode.Virtual:
                m_Source = Machine.Current.DeviceCPU.VirtualMemoryStream; break;

            default: m_ModeInvalid = true; break;
            }

            if (m_Source != null)
            {
                m_BinReader = new BinaryReader(new Int32SwapStream(m_Source));
            }
        }
コード例 #12
0
        private byte ReadFromMemoryOrPort(
            ushort address,
            IMemory memory,
            MemoryAccessMode accessMode,
            MemoryAccessEventType beforeEventType,
            MemoryAccessEventType afterEventType,
            byte waitStates)
        {
            var beforeEventArgs = FireMemoryAccessEvent(beforeEventType, address, 0xFF);

            byte value;

            if (!beforeEventArgs.CancelMemoryAccess &&
                (accessMode == MemoryAccessMode.ReadAndWrite || accessMode == MemoryAccessMode.ReadOnly))
            {
                value = memory[address];
            }
            else
            {
                value = beforeEventArgs.Value;
            }

            if (executionContext != null)
            {
                executionContext.AccummulatedMemoryWaitStates += waitStates;
            }

            var afterEventArgs = FireMemoryAccessEvent(
                afterEventType,
                address,
                value,
                beforeEventArgs.LocalUserState,
                beforeEventArgs.CancelMemoryAccess);

            return(afterEventArgs.Value);
        }
コード例 #13
0
        public void WriteToMemory_accesses_memory_if_memory_mode_is_ReadAndWrite_or_WriteOnly(MemoryAccessMode accessMode, bool isPort)
        {
            var address = Fixture.Create <byte>();
            var value   = Fixture.Create <byte>();
            var memory  = isPort ? Ports : Memory;

            SetAccessMode(address, accessMode, isPort);

            Write(address, value, isPort);

            memory.VerifySet(m => m[address] = value);
        }
コード例 #14
0
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            bool isPpuAddr = addr <= 0x3fff;

            if (isPpuAddr)
            {
                if (TryAccessNameTable(addr, mode, ref value))
                {
                    return(value);
                }

                bool isChrAddr = addr <= 0x1fff;
                if (isChrAddr)
                {
                    var ppuBank   = addr / k_ChrBankSize;
                    var finalAddr = m_ChrBankOffsets[ppuBank] + addr;
                    return(Access(ChrRom, finalAddr, mode, value));
                }
            }
            else
            {
                bool write = mode == MemoryAccessMode.Write;
                bool read  = !write;
                if (write)
                {
                    bool isEvenAddr       = (addr & 1) == 0;
                    bool isOddAddr        = !isEvenAddr;
                    bool isBankSelectAddr = isEvenAddr && (addr >= 0x8000 && addr <= 0x9ffe);
                    if (isBankSelectAddr)
                    {
                        m_RegisterToUpdate = value & 7;
                        m_PrgBankMode      = value & 0x40;
                        m_ChrBankMode      = value & 0x80;
                        return(0);
                    }

                    bool isBankDataAddr = isOddAddr && (addr >= 0x8001 && addr <= 0x9fff);
                    if (isBankDataAddr)
                    {
                        if (m_RegisterToUpdate == 6 || m_RegisterToUpdate == 7)
                        {
                            value = (byte)((value & 0x3f) % m_PrgBankCount);
                        }
                        else
                        {
                            value = (byte)(value % m_ChrBankCount);
                        }

                        m_Registers[m_RegisterToUpdate] = value;
                        UpdateChrOffsets();
                        UpdatePrgOffsets();
                        return(0);
                    }

                    bool isMirroringSelectAddr = isEvenAddr && (addr >= 0xa000 && addr <= 0xbffe);
                    if (isMirroringSelectAddr)
                    {
                        Mirroring = (value & 1) == 0 ? Mirroring.Vertical : Mirroring.Horizontal;
                        return(0);
                    }

                    bool isIrqLatchAddr = isEvenAddr && (addr >= 0xc000 && addr <= 0xdffe);
                    if (isIrqLatchAddr)
                    {
                        m_ScanlineCounterLatch = value;
                        return(0);
                    }

                    bool isIrqReloadAddr = isOddAddr && (addr >= 0xc001 && addr <= 0xdfff);
                    if (isIrqReloadAddr)
                    {
                        m_ScanlineCounter = 0; // force reload
                        return(0);
                    }

                    bool isIrqDisableAddr = isEvenAddr && (addr >= 0xe000 && addr <= 0xfffe);
                    if (isIrqDisableAddr)
                    {
                        m_IrqEnabled = false;
                        IrqPending   = false;
                        return(0);
                    }

                    bool isIrqEnableAddr = isOddAddr && (addr >= 0xe001 && addr <= 0xffff);
                    if (isIrqEnableAddr)
                    {
                        m_IrqEnabled = true;
                        return(0);
                    }
                }

                bool isPrgAddr = addr >= 0x8000 && addr <= 0xffff;
                if (read && isPrgAddr)
                {
                    var cpuBank   = ((addr - 0x8000) / k_PrgBankSize);
                    var offset    = m_PrgBankOffsets[cpuBank];
                    var finalAddr = (offset + addr);
                    return(PrgRom[finalAddr]);
                }

                bool isPrgRamAddr = addr >= 0x6000 && addr <= 0x7fff;
                if (isPrgRamAddr)
                {
                    return(Access(m_PrgRam, addr - 0x6000, mode, value));
                }
            }

            return(0);
        }
コード例 #15
0
        public void ReadFromMemory_does_not_access_memory_if_memory_mode_is_NotConnected_or_WriteOnly(MemoryAccessMode accessMode, bool isPort)
        {
            var address = Fixture.Create <byte>();
            var value   = Fixture.Create <byte>();
            var memory  = isPort ? Ports : Memory;

            memory.Setup(m => m[address]).Throws <Exception>();
            SetAccessMode(address, accessMode, isPort);

            Read(address, isPort);
        }
コード例 #16
0
 public void SetPortsSpaceAccessMode(byte startPort, int length, MemoryAccessMode mode)
 {
     SetArrayContents(portsAccessModes, startPort, length, mode);
 }
コード例 #17
0
 public void SetMemoryAccessMode(ushort startAddress, int length, MemoryAccessMode mode)
 {
     SetArrayContents(memoryAccessModes, startAddress, length, mode);
 }
コード例 #18
0
 // コンストラクタ
 public PhysicalMemoryProtectionConfig(byte value)
 {
     IsLockingMode       = (value & 0x80) > 0;
     AddressMatchingMode = (AddressMatchingMode)((value & 0x18) >> 3);
     Permission          = (MemoryAccessMode)(value & 0x07);
 }
コード例 #19
0
 protected abstract byte Access(ushort addr, MemoryAccessMode mode, byte value);
コード例 #20
0
ファイル: Mapper001.cs プロジェクト: rlzicar/Nesemuto
        protected override byte Access(ushort addr, MemoryAccessMode mode, byte value)
        {
            int  finalAddr = addr;
            bool isPpuAddr = addr <= 0x3fff;

            if (isPpuAddr)
            {
                if (TryAccessNameTable(addr, mode, ref value))
                {
                    return(value);
                }

                bool isChrBank0Addr = addr <= 0x0fff;
                bool isChrBank1Addr = addr >= 0x1000 && addr <= 0x1fff;
                if (isChrBank0Addr)
                {
                    finalAddr = m_SelectedChrBankOffset0 + addr;
                }
                else if (isChrBank1Addr)
                {
                    finalAddr = m_SelectedChrBankOffset1 + addr;
                }

                return(Access(ChrRom, finalAddr, mode, value));
            }

            bool isLoadRegisterAddr = addr >= 0x8000 && addr <= 0xffff;

            if (mode == MemoryAccessMode.Write && isLoadRegisterAddr)
            {
                var  dataBit     = (ushort)(value & 1);
                var  resetBit    = (value & 0x80) >> 7;
                bool shouldReset = resetBit == 1;
                if (shouldReset)
                {
                    m_ShiftRegister  = k_ShiftRegisterInitialValue;
                    m_PrgRomBankMode = PrgRomBankMode.Switch16KLow;
                }
                else
                {
                    bool shiftRegisterFull = (m_ShiftRegister & 1) == 1;

                    m_ShiftRegister >>= 1;
                    m_ShiftRegister   = (byte)(m_ShiftRegister | (dataBit << 4));
                    if (shiftRegisterFull)
                    {
                        WriteInternalRegister(addr, (byte)(m_ShiftRegister & 0xff));
                        m_ShiftRegister = k_ShiftRegisterInitialValue;
                    }
                }

                return(0);
            }

            bool isPrgRamAddr = addr >= 0x6000 && addr <= 0x7fff;

            if (isPrgRamAddr)
            {
                return(Access(m_PrgRam, addr - 0x6000, mode, value));
            }

            bool isPrgBank0Addr = addr >= 0x8000 && addr <= 0xbfff;
            bool isPrgBank1Addr = addr >= 0xc000 && addr <= 0xffff;

            if (isPrgBank0Addr)
            {
                finalAddr = m_SelectedPrgBankOffset0 + addr;
            }
            else if (isPrgBank1Addr)
            {
                finalAddr = m_SelectedPrgBankOffset1 + addr;
            }

            return(PrgRom[finalAddr]);
        }
コード例 #21
0
        public void ReadFromMemory_accesses_memory_if_memory_mode_is_ReadAndWrite_or_ReadOnly(MemoryAccessMode accessMode, bool isPort)
        {
            var address = Fixture.Create <byte>();
            var value   = Fixture.Create <byte>();
            var memory  = isPort ? Ports : Memory;

            memory.Setup(m => m[address]).Returns(value);
            SetAccessMode(address, accessMode, isPort);

            var actual = Read(address, isPort);

            Assert.AreEqual(value, actual);
            memory.Verify(m => m[address]);
        }
コード例 #22
0
        protected bool TryAccessNameTable(ushort addr, MemoryAccessMode mode, ref byte value)
        {
            if (addr < 0x2000 || addr > 0x3eff)
            {
                return(false);
            }

            if (addr >= 0x3000)
            {
                addr -= 0x1000;
            }

            switch (Mirroring)
            {
            case Mirroring.Horizontal:
            {
                bool isScreenB = addr >= 0x2400 && addr <= 0x27ff;
                bool isScreenC = addr >= 0x2800 && addr <= 0x2bff;
                if (isScreenB)
                {
                    // B -> A
                    addr -= 0x400;
                }
                else if (isScreenC)
                {
                    // C -> D
                    addr += 0x400;
                }

                break;
            }

            case Mirroring.Vertical:
            {
                bool isScreenB = addr >= 0x2400 && addr <= 0x27ff;
                bool isScreenC = addr >= 0x2800 && addr <= 0x2bff;

                if (isScreenB)
                {
                    // B -> D
                    addr += 0x800;
                }
                else if (isScreenC)
                {
                    // C -> A
                    addr -= 0x800;
                }

                break;
            }

            case Mirroring.ScreenA:
                addr = (ushort)(0x2000 + addr % 0x400);
                break;

            case Mirroring.ScreenB:
                addr = (ushort)(0x2c00 + addr % 0x400);
                break;
            }

            value = Access(m_Nametables, addr - 0x2000, mode, value);
            return(true);
        }