Exemplo n.º 1
0
        public CartridgeHeader(byte[] romData)
        {
            // 0x134 - 0x13E - 11 ascii characters of the game title
            GameTitle = Encoding.ASCII.GetString(romData, 0x134, 11);

            // 0x13F - 0x142 - 4 ascii character game code
            GameCode = Encoding.ASCII.GetString(romData, 0x13F, 4);

            CgbSupportCode = (CgbSupportCode)romData[0x143];

            // 0x144 - 0x145 - 2 ascii character licensee code
            MakerCode = Encoding.ASCII.GetString(romData, 0x144, 2);

            SgbSupportCode  = romData[0x146];
            CartridgeType   = (CartridgeType)romData[0x147];
            RomSize         = romData[0x148];
            ExternalRamSize = romData[0x149];
            DestinationCode = romData[0x14A];
            OldLicenseeCode = romData[0x14B];
            MaskRomVersion  = romData[0x14C];

            ComplementCheck = romData[0x14D];

            Checksum = (ushort)((romData[0x14E] << 8) | romData[0x14F]);
        }
Exemplo n.º 2
0
    public GBHeader(byte[] rom)
    {
        // Verify that there's at least enough here to try reading the header info
        if (rom.Length < 0x014f)
        {
            return;
        }
        couldParse = true;

        containsScrollingNintendoGraphic = CheckScrollingGraphics(rom);
        gameTitle           = GetTitle(rom);
        gbcVal              = GetGBCVal(rom);
        newLicenseeCode     = GetNewLicenseeCode(rom);
        sgbFunctions        = GetSGBFunctions(rom);
        cartridgeType       = GetCartridgeType(rom);
        romSize             = GetRomSize(rom);
        ramSize             = GetRamSize(rom);
        destinationCode     = GetDestinationCode(rom);
        oldLicenseeCode     = GetOldLicenseeCode(rom);
        maskROMVersion      = rom[0x14C];
        complementCheckByte = rom[0x14D];
        checksumHigh        = rom[0x14E];
        checksumLow         = rom[0x14F];

        passesComplementCheck = RunComplementCheck(rom);

        isValid = containsScrollingNintendoGraphic & passesComplementCheck;
    }
Exemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CartridgeHeader"/> class.
 /// </summary>
 /// <param name="entryPoint">The entry point.</param>
 /// <param name="title">The title.</param>
 /// <param name="isGameBoyColour">if set to <c>true</c> [supports game boy colour].</param>
 /// <param name="licenseCode">The license code.</param>
 /// <param name="isSuperGameBoy">if set to <c>true</c> [supports super game boy].</param>
 /// <param name="cartridgeType">Type of the cartridge.</param>
 /// <param name="romSize">Size of the rom.</param>
 /// <param name="ramSize">Size of the ram.</param>
 /// <param name="destinationCode">The destination code.</param>
 /// <param name="romVersion">The rom version.</param>
 /// <param name="headerChecksum">The header checksum.</param>
 /// <param name="romChecksum">The rom checksum.</param>
 public CartridgeHeader(byte[] entryPoint,
                        string title,
                        bool isGameBoyColour,
                        string licenseCode,
                        bool isSuperGameBoy,
                        CartridgeType cartridgeType,
                        CartridgeRomSize romSize,
                        CartridgeRamSize ramSize,
                        DestinationCode destinationCode,
                        byte romVersion,
                        byte headerChecksum,
                        ushort romChecksum)
 {
     EntryPoint      = entryPoint;
     Title           = title;
     IsGameBoyColour = isGameBoyColour;
     LicenseCode     = licenseCode;
     IsSuperGameBoy  = isSuperGameBoy;
     CartridgeType   = cartridgeType;
     RomSize         = romSize;
     RamSize         = ramSize;
     DestinationCode = destinationCode;
     RomVersion      = romVersion;
     HeaderChecksum  = headerChecksum;
     RomChecksum     = romChecksum;
 }
Exemplo n.º 4
0
        public EmulatedCartridge(byte[] romContents)
        {
            if (romContents == null)
            {
                throw new ArgumentNullException(nameof(romContents));
            }
            _romContents = romContents;

            if (CartridgeType.IsRom())
            {
                BankController = new RomOnlyBankController(this);
            }
            else if (CartridgeType.IsMbc1())
            {
                BankController = new MemoryBankController1(this);
            }
            else if (CartridgeType.IsMbc2())
            {
                BankController = new MemoryBankController2(this);
            }
            else
            {
                throw new NotSupportedException("Unsupported cartridge type " + CartridgeType + ".");
            }
        }
Exemplo n.º 5
0
 public static bool HasTimer(this CartridgeType type)
 {
     switch (type)
     {
     case CartridgeType.Mbc3TimerBattery:
     case CartridgeType.Mbc3TimerRamBattery:
         return(true);
     }
     return(false);
 }
Exemplo n.º 6
0
 public static bool IsMbc2(this CartridgeType type)
 {
     switch (type)
     {
     case CartridgeType.Mbc2:
     case CartridgeType.Mbc2Battery:
         return(true);
     }
     return(false);
 }
Exemplo n.º 7
0
 public static bool IsRom(this CartridgeType type)
 {
     switch (type)
     {
     case CartridgeType.RomOnly:
     case CartridgeType.RomRam:
     case CartridgeType.RomRamBattery:
         return(true);
     }
     return(false);
 }
Exemplo n.º 8
0
        public void OpenMemo(Stream memo)
        {
            _carsize = Math.Min(memo.Length, 0x10000);
            _car     = new byte[_carsize];
            memo.Read(_car, 0, (int)_carsize);

            _cartype  = _carsize > 0x4000 ? CartridgeType.SwitchBank : CartridgeType.Simple; //cartouche > 16 Ko
            _carflags = 4;                                                                   //cartridge enabled, write disabled, bank 0;

            Reset();
        }
Exemplo n.º 9
0
 public static bool HasRumble(this CartridgeType type)
 {
     switch (type)
     {
     case CartridgeType.Mbc5Rumble:
     case CartridgeType.Mbc5RumbleRam:
     case CartridgeType.Mbc5RumbleRamBattery:
         return(true);
     }
     return(false);
 }
Exemplo n.º 10
0
        public Mbc2(int[] cartridge, CartridgeType type, IBattery battery, int romBanks)
        {
            _cartridge = cartridge;
            _ram       = new int[0x0200];
            for (var i = 0; i < _ram.Length; i++)
            {
                _ram[i] = 0xff;
            }

            _battery = battery;
            battery.LoadRam(_ram);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Returns the proper Cart object, based on the file loaded.
        /// </summary>
        /// <param name="romFile">The binary file to load.</param>
        /// <returns>A Cart with the characteristics of the cartridge the file specifies.</returns>
        public static Cart LoadCart(byte[] romFile)
        {
            CartridgeType cs           = (CartridgeType)romFile[0x147];
            Cart          returnedCart = null;

            #region MBC

            switch (cs)
            {
            case CartridgeType.ROM:
            case CartridgeType.ROM_R:
            case CartridgeType.ROM_RB:
                returnedCart = new PlainCart(romFile, FeatureList[cs]);
                break;

            case CartridgeType.MBC1:
            case CartridgeType.MBC1_R:
            case CartridgeType.MBC1_RB:
                returnedCart = new MBC1(romFile, FeatureList[cs]);
                break;

            case CartridgeType.MBC2:
            case CartridgeType.MBC2_B:
                returnedCart = new MBC2(romFile, FeatureList[cs]);
                break;

            case CartridgeType.MBC3:
            case CartridgeType.MBC3_TB:
            case CartridgeType.MBC3_TRB:
            case CartridgeType.MBC3_R:
            case CartridgeType.MBC3_RB:
                returnedCart = new MBC3(romFile, FeatureList[cs]);
                break;

            case CartridgeType.MBC5:
            case CartridgeType.MBC5_M:
            case CartridgeType.MBC5_MR:
            case CartridgeType.MBC5_MRB:
            case CartridgeType.MBC5_R:
            case CartridgeType.MBC5_RB:
                returnedCart = new MBC5(romFile, FeatureList[cs]);
                break;

            default:
                throw new System.Exception("Cart is not supported.");
            }

            #endregion MBC

            Logger.GetInstance().Log(new LogMessage(LogMessageSource.Cart, $"Cart type {cs} loaded."));
            return(returnedCart);
        }
Exemplo n.º 12
0
        public Mbc5(int[] cartridge, CartridgeType type, IBattery battery, int romBanks, int ramBanks)
        {
            _cartridge = cartridge;
            _ramBanks  = ramBanks;
            _ram       = new int[0x2000 * Math.Max(_ramBanks, 1)];
            for (var i = 0; i < _ram.Length; i++)
            {
                _ram[i] = 0xff;
            }

            _battery = battery;
            battery.LoadRam(_ram);
        }
Exemplo n.º 13
0
        private void ScrapeMetaData(byte[] rom)
        {
            ROM_TITLE     = GetROMTitle(rom);
            gameType      = GetGameType(rom);
            cartridgeType = GetCartridgeType(rom);

            romBanks = GetNumROMBanks(rom);
            ramBanks = GetNumRAMBanks(rom);

            destinationCode = GetDestinationCode(rom);
            memoryModel     = MemoryModel.MM16x8;

            Debug.Log("ROM Title:{0}\nGame Type:{1}\nCartridge Type:{2}\nROM Banks:{3}\nRAM Banks:{4}\nDestination Code:{5}\n",
                      ROM_TITLE, gameType, cartridgeType, romBanks, ramBanks, destinationCode);
        }
Exemplo n.º 14
0
        public Mbc1(int[] cartridge, CartridgeType type, IBattery battery, int romBanks, int ramBanks)
        {
            _multicart = romBanks == 64 && IsMulticart(cartridge);
            _cartridge = cartridge;
            _ramBanks  = ramBanks;
            _romBanks  = romBanks;
            _ram       = new int[0x2000 * _ramBanks];
            for (var i = 0; i < _ram.Length; i++)
            {
                _ram[i] = 0xff;
            }

            _battery = battery;
            battery.LoadRam(_ram);
        }
Exemplo n.º 15
0
        public Mbc3(int[] cartridge, CartridgeType type, IBattery battery, int romBanks, int ramBanks)
        {
            _cartridge = cartridge;
            _ram       = new int[0x2000 * Math.Max(ramBanks, 1)];
            for (var i = 0; i < _ram.Length; i++)
            {
                _ram[i] = 0xff;
            }

            _clock   = new RealTimeClock(Clock.SystemClock);
            _battery = battery;

            var clockData = new long[12];

            battery.LoadRamWithClock(_ram, clockData);
            _clock.Deserialize(clockData);
        }
Exemplo n.º 16
0
        public MBCBase(byte[] romData)
        {
            _romData = romData;

            //check if CGB-only game (not supported for now)
            if (_romData[0x0143] == 0xC0)
            {
                throw new NotSupportedException("CGB-only games are not supported");
            }

            _cartridgeType = (CartridgeType)romData[0x0147];

            _romSizeType = (RomSizeType)_romData[0x0148];
            _ramSizeType = (RamSizeType)_romData[0x0149];

            _ramData = new byte[RamSizeInBytes];
        }
Exemplo n.º 17
0
 public static bool HasBattery(this CartridgeType type)
 {
     switch (type)
     {
     case CartridgeType.RomRamBattery:
     case CartridgeType.Mbc1RamBattery:
     case CartridgeType.Mbc2Battery:
     case CartridgeType.Mbc3RamBattery:
     case CartridgeType.Mbc3TimerBattery:
     case CartridgeType.Mbc3TimerRamBattery:
     case CartridgeType.Mbc4RamBattery:
     case CartridgeType.Mbc5RamBattery:
     case CartridgeType.Mmm01RamBattery:
     case CartridgeType.HuC1RamBattery:
         return(true);
     }
     return(false);
 }
Exemplo n.º 18
0
        public Memory(string romPath)
        {
            byte[] rom = File.ReadAllBytes(romPath);

            ROM_TITLE     = GetROMTitle(rom);
            gameType      = GetGameType(rom);
            cartridgeType = GetCartridgeType(rom);

            int romBanks = GetNumROMBanks(rom);
            int ramBanks = GetNumRAMBanks(rom);

            destinationCode = GetDestinationCode(rom);
            memoryModel     = MemoryModel.MM16x8;

            cartridge = AssembleCartridge(ramBanks, romBanks, rom);

            Console.WriteLine(ROM_TITLE);
            Console.WriteLine(gameType);
            Console.WriteLine(cartridgeType);
            Console.WriteLine("ROM Banks: {0}", romBanks);
            Console.WriteLine("RAM Banks: {0}", ramBanks);
            Console.WriteLine(destinationCode);
        }
 public static IEnumerable <CartridgeType> Values(this CartridgeType src)
 {
     return(Enum.GetValues(typeof(CartridgeType)).Cast <CartridgeType>());
 }
 private static bool NameContainsSegment(this CartridgeType src, string segment)
 {
     return(new Regex("(^|_)" + Regex.Escape(segment) + "($|_)").IsMatch(src.ToString()));
 }
 public static bool IsRumble(this CartridgeType src) => src.NameContainsSegment("RUMBLE");
 public static bool IsBattery(this CartridgeType src) => src.NameContainsSegment("BATTERY");
 public static bool IsTimer(this CartridgeType src) => src.NameContainsSegment("TIMER");
 public static bool IsSram(this CartridgeType src) => src.NameContainsSegment("SRAM");
 public static bool IsMmm01(this CartridgeType src) => src.NameContainsSegment("MMM01");
 public static bool IsMbc5(this CartridgeType src) => src.NameContainsSegment("MBC5");
Exemplo n.º 27
0
        public void Awake()
        {
            _rom = File.ReadAllBytes("./Contrib/ROMs/tetris.gb");

            StringBuilder titleString = new StringBuilder();

            for (int i = 0x0134; i <= 0x0142; i++)
            {
                if (_rom[i] == 0x00)
                {
                    break;
                }

                titleString.Append((char)_rom[i]);
            }
            Title = titleString.ToString();

            if ((_rom[0x0143] & 0xC0) == 0xC0)
            {
                ColorType = ColorType.ColorOnly;
            }
            else if ((_rom[0x0143] & 0x80) == 0x80)
            {
                ColorType = ColorType.MonochromeOrColor;
            }
            else
            {
                ColorType = ColorType.Monochrome;
            }

            NewLicenseeCode = (_rom[0x0144] << 4) | _rom[0x0145];

            SupportsSuperGameBoyFucntionality = _rom[0x0146] == 0x03;

            CartridgeType = (CartridgeType)_rom[0x0147];

            Size = (32 * 1024) << _rom[0x0148];

            switch (_rom[0x0149])
            {
            case 0x01:
                RAMSize = 2048;
                break;

            case 0x02:
                RAMSize = 8192;
                break;

            case 0x03:
                RAMSize = 32768;
                break;

            case 0x04:
                RAMSize = 131072;
                break;

            case 0x05:
                RAMSize = 65536;
                break;

            default:
                RAMSize = 0;
                break;
            }

            IsJapanese = _rom[0x014A] == 0x00;

            OldLicenseeCode = _rom[0x014B];

            MaskROMVersion = _rom[0x014C];

            HeaderChecksum = _rom[0x014D];

            int calculatedHeaderChecksum = 0;

            for (int i = 0x0134; i <= 0x014C; i++)
            {
                calculatedHeaderChecksum = calculatedHeaderChecksum - _rom[i] - 1;
            }
            CalculatedHeaderChecksum = (byte)(calculatedHeaderChecksum & 0xFF);

            Checksum = (ushort)((_rom[0x014E] << 8) | _rom[0x014F]);

            int calculatedChecksum = 0;

            for (int i = 0; i < _rom.Length; i++)
            {
                if ((i != 0x014E) && (i != 0x014F))
                {
                    calculatedChecksum += _rom[i];
                }
            }
            CalculatedChecksum = (ushort)(calculatedChecksum & 0xFFFF);
        }
Exemplo n.º 28
0
 public Rom(int[] rom, CartridgeType type, int romBanks, int ramBanks)
 {
     _rom = rom;
 }
Exemplo n.º 29
0
        public void setByte(ushort address, Byte Value)
        {
            CartridgeType type = (CartridgeType)this.headerInfoDict.Where(fi => fi.description == "Cartridge Type").First().value;

            switch (type)
            {
            case CartridgeType.ROM_ONLY:
                break;

            case CartridgeType.ROM_MBC1:
            case CartridgeType.ROM_MBC1_RAM:
            case CartridgeType.ROM_MBC1_RAM_BATT:
                if (address >= 0x0000 && address <= 0x1FFF)
                {
                    // RAM Enable
                }
                else if (address >= 0x2000 && address <= 0x3FFF)
                {
                    // ROM Select
                    Byte romBankNum = Value;

                    // ROM Address MBC1 Bug
                    if ((romBankNum & 0x1F) == 0)
                    {
                        romBankNum += 1;
                    }
                    romBankNum = (Byte)(romBankNum & 0x1F);

                    // Set ROM Bank Num
                    if (memContMode == MBC1_Mode.ROM_MODE)
                    {
                        // Set only 5 lsb bits
                        selectedRomBank = (ushort)((selectedRomBank & 0xC0) | (romBankNum & 0x1F));
                    }
                }
                else if (address >= 0x4000 && address <= 0x5FFF)
                {
                    Byte tmp = (Byte)(Value & 0x03);

                    if (memContMode == MBC1_Mode.ROM_MODE)
                    {
                        // Upper ROM Select (Set upper 2 bits 5-6)
                        selectedRomBank = (ushort)((selectedRomBank & 0x1F) | (tmp << 5));
                    }
                    else
                    {
                        // RAM Mode
                        selectedRamBank = tmp;
                    }
                }
                else if (address >= 0x6000 && address <= 0x7FFF)
                {
                    // ROM/RAM mode select
                    if (Value == 0)
                    {
                        memContMode = MBC1_Mode.ROM_MODE;
                    }
                    else if (Value == 1)
                    {
                        memContMode = MBC1_Mode.RAM_MODE;
                    }
                    else
                    {
                        throw new ArgumentException($"Invalid Write to ROM Address 0x{address.ToString("X4")} value 0x{Value.ToString("X2")}");
                    }
                }
                else
                {
                    throw new ArgumentException($"Attempted Write to Address Which is in ROM Space");
                }
                break;


            default:
                throw new NotImplementedException($"Cartridge Type {type.ToString()} MMC Operation write at {address.ToString("X4")} not Implemented");
            }
        }