/// <summary> /// Writes one byte to the specified bank, at the specified offset /// </summary> /// <param name="memoryType"></param> /// <param name="offset"></param> /// <param name="data"></param> public void WriteByte(int offset, byte data) { //CHR ROM if (offset < 0x2000) { _chrRom[offset] = data; return; } //PPU Interceptors if (offset <= 0x3FFF || offset == 0x4014) { if (!WriteInterceptors.TryGetValue(offset, out currentWriteInterceptor)) { return; } currentWriteInterceptor(offset, data); return; } if (offset >= 0x8000 && offset <= 0xFFFF) { _prgRom[offset - 0x8000] = data; return; } throw new ArgumentOutOfRangeException(nameof(offset), offset, "Maximum value of offset is 0xFFFF"); }
/// <summary> /// Writes one byte to the specified bank, at the specified offset /// </summary> /// <param name="offset"></param> /// <param name="data"></param> public void WriteByte(int offset, byte data) { //CHR ROM+RAM Writes if (offset < 0x2000) { _chrRom[offset] = data; return; } //PPU Registers if (offset <= 0x3FFF || offset == 0x4014) { if (WriteInterceptors.TryGetValue(offset, out currentWriteInterceptor)) { currentWriteInterceptor(offset, data); } return; } //Some UxROM boards from Nintendo have bus conflicts, we avoid these here if (offset >= 0x6000 && offset <= 0x7FFF) { return; } //Bank Select if (offset >= 0xC000 && offset <= 0xFFFF) { _prgBank0Offset = (data & 0x0F) * 0x4000; return; } throw new ArgumentOutOfRangeException(nameof(offset), offset, "Maximum value of offset is 0xFFFF"); }
/// <summary> /// Writes one byte to the specified bank, at the specified offset /// /// CHR Bank Switching is handled at $8000->$FFFF /// </summary> /// <param name="memoryType"></param> /// <param name="offset"></param> /// <param name="data"></param> public void WriteByte(int offset, byte data) { //CHR ROM+RAM Writes if (offset < 0x2000) { _chrRom[_chrRomOffset + offset] = data; return; } //PPU Registers if (offset <= 0x3FFF || offset == 0x4014) { if (WriteInterceptors.TryGetValue(offset, out currentWriteInterceptor)) { currentWriteInterceptor(offset, data); } return; } //CHR Bank Select if (offset >= 0x8000 && offset <= 0xFFFF) { _chrRomOffset = (data & 0x03) * 0x2000; return; } throw new ArgumentOutOfRangeException(nameof(offset), offset, "Maximum value of offset is 0xFFFF"); }
/// <summary> /// Writes one byte to the specified bank, at the specified offset /// </summary> /// <param name="memoryType"></param> /// <param name="offset"></param> /// <param name="data"></param> public void WriteByte(int offset, byte data) { // CHR Bank 0 == $0000-$0FFF // CHR Bank 1 == $1000-$1FFF if (offset <= 0x1FFF) { if (!_useChrRam) { throw new AccessViolationException($"Invalid write to CHR ROM (CHR RAM not enabled). Offset: {offset:X4}"); } var chrOffset = (offset / 0x1000) == 0 ? _chrBank0Offset : _chrBank1Offset; chrOffset += offset % 0x1000; _chrRom[chrOffset] = data; return; } //PPU Registers if (offset <= 0x3FFF || offset == 0x4014) { if (WriteInterceptors.TryGetValue(offset, out currentWriteInterceptor)) { currentWriteInterceptor(offset, data); } return; } // PRG RAM Bank == $6000-$7FFF if (offset >= 0x6000 && offset <= 0x7FFF) { if (!_usePrgRam) { throw new AccessViolationException($"Attempt to write PRG RAM when disabled. Offset ${offset:X4}"); } _prgRam[offset - 0x6000] = data; return; } //Writes to this range are handled by the Load Register if (offset >= 0x8000 && offset <= 0xFFFF) { WriteLoadRegister(offset, data); return; } //Sanity Check if we reach this point throw new ArgumentOutOfRangeException(nameof(offset), "Maximum value of offset is 0xFFFF"); }
/// <summary> /// Writes one byte to the specified bank, at the specified offset /// </summary> /// <param name="memoryType"></param> /// <param name="offset"></param> /// <param name="data"></param> public void WriteByte(enumMemoryType memoryType, int offset, byte data) { switch (memoryType) { case enumMemoryType.CPU: _prgRom[CpuOffsetToPrgRomOffset(offset)] = data; return; case enumMemoryType.PPU: if (!WriteInterceptors.TryGetValue(offset, out currentWriteInterceptor)) { _chrRom[offset] = data; } else { currentWriteInterceptor(offset, data); } return; default: throw new ArgumentOutOfRangeException(nameof(memoryType), memoryType, null); } }