Beispiel #1
0
 public override void Reset()
 {
     this.romBank           = 1;
     this.ramBank           = 0;
     this.enableExternalRam = false;
     Array.Clear(this.externalRam, 0, this.externalRam.Length);
     this.bankingMode = BankingMode.ROM;
 }
Beispiel #2
0
        public void WriteByte(byte data, int address)
        {
            if (address < MemorySchema.ROM_END)
            {
                //TODO determine how to get rid of magic numbers
                if (address < 0x2000)
                {
                    switch (_header.BankingMode)
                    {
                    case CartridgeSchema.MBCMode.MBC1:
                    case CartridgeSchema.MBCMode.MBC2:
                    case CartridgeSchema.MBCMode.MBC3:
                    case CartridgeSchema.MBCMode.MBC5:
                        if (_header.BankingMode == CartridgeSchema.MBCMode.MBC2 && Helpers.TestBit((ushort)address, 4))
                        {
                            return;
                        }

                        _externalRAM.Enabled = Helpers.GetBits(data, 4) == 0x0A;
                        break;
                    }
                }
                else if (address < 0x4000)
                {
                    int newBank;

                    switch (_header.BankingMode)
                    {
                    case CartridgeSchema.MBCMode.NoMBC:
                        break;

                    case CartridgeSchema.MBCMode.MBC1:
                        //Override the lower 5 bits of the ROM Bank
                        newBank = _romBank;

                        Helpers.ResetLowBits(ref newBank, 5);
                        newBank |= Helpers.GetBits(data, 5);

                        SetROMBank(newBank);
                        break;

                    case CartridgeSchema.MBCMode.MBC2:
                        SetROMBank(Helpers.GetBits(data, 4));
                        break;

                    case CartridgeSchema.MBCMode.MBC3:
                        SetROMBank(Helpers.GetBits(data, 7));
                        break;

                    case CartridgeSchema.MBCMode.MBC5:
                        if (address < 0x3000)
                        {
                            //Override the lower 5 bits of the ROM Bank
                            newBank = _romBank;

                            Helpers.ResetLowBits(ref newBank, 8);
                            newBank |= Helpers.GetBits(data, 8);

                            SetROMBank(newBank);
                        }
                        else
                        {
                            newBank = _romBank;
                            Helpers.SetBit(ref newBank, 9, Helpers.TestBit(data, 1));
                            SetROMBank(newBank);
                        }

                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                else if (address < 0x6000)
                {
                    switch (_header.BankingMode)
                    {
                    case CartridgeSchema.MBCMode.MBC1:
                        if (_bankMode == BankingMode.ROMBank)
                        {
                            //Override the bits 5-6 of the romBank
                            int newBank = _romBank;

                            Helpers.ResetHighBits(ref newBank, 3);
                            newBank |= (byte)(data << 5);

                            SetROMBank(newBank);
                        }
                        else
                        {
                            _ramBank = _header.RAMBanks == 0 ? 0 : Helpers.GetBits(data, 2) % _header.RAMBanks;
                        }
                        break;

                    case CartridgeSchema.MBCMode.MBC3:
                        //TODO RTC register select
                        _ramBank = Helpers.GetBits(data, 2) % _header.RAMBanks;
                        break;

                    case CartridgeSchema.MBCMode.MBC5:
                        _ramBank = Helpers.GetBits(data, 4) % _header.RAMBanks;
                        break;
                    }
                }
                else if (address < 0x8000)
                {
                    if (_header.BankingMode == CartridgeSchema.MBCMode.MBC1)
                    {
                        _bankMode = (BankingMode)Helpers.GetBits(data, 1);
                    }
                }
            }
            else if (address >= MemorySchema.EXTERNAL_RAM_START && address < MemorySchema.EXTERNAL_RAM_END && _externalRAM.Enabled)
            {
                address = (address - MemorySchema.EXTERNAL_RAM_START) + ((_bankMode == BankingMode.RAMBank ? _ramBank : 0) * CartridgeSchema.RAM_BANK_SIZE);

                if (address < _externalRAM.Length)
                {
                    _externalRAM.WriteByte(data, address);
                }
            }
        }
Beispiel #3
0
        public override void Write(ushort addr, byte value)
        {
            // RAM Enable
            if (addr >= 0x0000 && addr <= 0x1FFF)
            {
                if ((value & 0xF) == 0x0A)
                {
                    this.enableExternalRam = true;
                }
                else
                {
                    this.enableExternalRam = false;
                }
                return;
            }
            // ROM Bank Number Lower 5 Bits
            if (addr >= 0x2000 && addr <= 0x3FFF)
            {
                this.romBank &= 0b11100000;                 // Erase 5 bits
                this.romBank |= (byte)(value & 0b00011111); // Whole 5 bits

                if (this.romBank == 0)
                {
                    this.romBank = 1;
                }

                return;
            }
            // RAM Bank Number / Upper Bits of ROM Bank Number
            if (addr >= 0x4000 && addr <= 0x5FFF)
            {
                value &= 0b11;
                if (this.bankingMode == BankingMode.RAM)
                {
                    Console.WriteLine("Set RAM Bank to: " + value);
                    this.ramBank = value;
                }
                else
                {
                    this.romBank &= 0b00011111; // Erase high bits
                    this.romBank |= (byte)(value << 5);
                }

                return;
            }
            // RAM Bank 00-03
            if (addr >= 0xA000 && addr <= 0xBFFF && this.enableExternalRam)
            {
                this.externalRam[this.calcBankAddrRam(addr, this.ramBank)] = value;
                return;
            }

            if (addr >= 0x6000 && addr <= 0x7FFF)
            {
                if ((value & 1) != 0)
                {
                    this.bankingMode = BankingMode.RAM;
                }
                else
                {
                    this.bankingMode = BankingMode.ROM;
                }
                return;
            }
        }