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)); }
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)); }
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); }
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); }
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]); }
protected static byte Access(byte[] data, int addr, MemoryAccessMode mode, byte value) { if (mode == MemoryAccessMode.Read) { return(data[addr]); } data[addr] = value; return(0); }
private void SetAccessMode(byte address, MemoryAccessMode accessMode, bool isPort) { if (isPort) { Sut.SetPortsSpaceAccessMode(address, 1, accessMode); } else { Sut.SetMemoryAccessMode(address, 1, accessMode); } }
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); }
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]); }
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); }
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)); } }
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); }
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); }
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); }
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); }
public void SetPortsSpaceAccessMode(byte startPort, int length, MemoryAccessMode mode) { SetArrayContents(portsAccessModes, startPort, length, mode); }
public void SetMemoryAccessMode(ushort startAddress, int length, MemoryAccessMode mode) { SetArrayContents(memoryAccessModes, startAddress, length, mode); }
// コンストラクタ public PhysicalMemoryProtectionConfig(byte value) { IsLockingMode = (value & 0x80) > 0; AddressMatchingMode = (AddressMatchingMode)((value & 0x18) >> 3); Permission = (MemoryAccessMode)(value & 0x07); }
protected abstract byte Access(ushort addr, MemoryAccessMode mode, byte value);
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]); }
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]); }
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); }