internal override void WriteRom(ushort address, byte value) { if (address <= 0x1FFF) { IsRamEnabled = (value & 0x0F) == 0x0A; } else if (address >= 0x2000 && address <= 0x2FFF) { _romb0 = value; RomBank = ((_romb1 << 8) | _romb0) % ROMSize.NumberBanks(); } else if (address >= 0x3000 && address <= 0x3FFF) { _romb1 = (byte)(value & 0b0000_0001); // Only bottom 1 bit is used AFAICT RomBank = ((_romb1 << 8) | _romb0) % ROMSize.NumberBanks(); } else if (address >= 0x4000 && address <= 0x5FFF) { if (RAMSize == CartridgeRAMSize.None) { RamBank = 0; } else { RamBank = (value & 8) % RAMSize.NumberBanks(); } } }
internal Cartridge(byte[] contents) { Contents = contents; RamBanks = new byte[RAMSize.NumberBanks() * RAMSize.BankSizeBytes()]; RamBank = 0x0; RomBank = 0x1; IsRamEnabled = false; }
internal override void WriteRom(ushort address, byte value) { if (address <= 0x1FFF) { IsRamEnabled = (value & 0x0F) == 0x0A; } else if (address >= 0x2000 && address <= 0x3FFF) { RomBank = (value & 0x7f) % ROMSize.NumberBanks(); if (RomBank == 0x0) { RomBank = 0x1; } } else if (address >= 0x4000 && address < 0x5FFF) { if (value <= 0x3) { RamBank = value % RAMSize.NumberBanks(); _mappedRTCRegister = null; } else if (value >= 0x8 && value <= 0xC) { _mappedRTCRegister = value switch { 0x8 => _rtcSecondsRegister, 0x9 => _rtcMinutesRegister, 0xA => _rtcHoursRegister, 0xB => _rtcLowBitsDayCounter, 0xC => _rtcHighBitsDayCounter, _ => throw new ArgumentOutOfRangeException(nameof(value), value, $"Value {value} isn't mapped to an RTC register") }; } } else if (address < 0x7FFF) { // Allow clock to start counting again if (value == 0x1 && _latchedTime.HasValue) { _latchedTime = null; } // Latch current time else if (value == 0x1) { _latchedTime = DateTime.UtcNow; } } }