Esempio n. 1
0
        private void Setup_Mapper()
        {
            // setup up mapper based on header entry
            string mppr;

            switch (header[0x47])
            {
            case 0x0: mapper = new MapperDefault();         mppr = "NROM";          break;

            case 0x1: mapper = new MapperMBC1();            mppr = "MBC1";          break;

            case 0x2: mapper = new MapperMBC1();            mppr = "MBC1";          break;

            case 0x3: mapper = new MapperMBC1();            mppr = "MBC1";          break;

            case 0x5: mapper = new MapperMBC2();            mppr = "MBC2";          break;

            case 0x6: mapper = new MapperMBC2();            mppr = "MBC2";          break;

            case 0x8: mapper = new MapperDefault();         mppr = "NROM";          break;

            case 0x9: mapper = new MapperDefault();         mppr = "NROM";          break;

            case 0xB: mapper = new MapperMMM01();           mppr = "MMM01";         break;

            case 0xC: mapper = new MapperMMM01();           mppr = "MMM01";         break;

            case 0xD: mapper = new MapperMMM01();           mppr = "MMM01";         break;

            case 0xF: mapper = new MapperMBC3();            mppr = "MBC3";          break;

            case 0x10: mapper = new MapperMBC3();           mppr = "MBC3";          break;

            case 0x11: mapper = new MapperMBC3();           mppr = "MBC3";          break;

            case 0x12: mapper = new MapperMBC3();           mppr = "MBC3";          break;

            case 0x13: mapper = new MapperMBC3();           mppr = "MBC3";          break;

            case 0x19: mapper = new MapperMBC5();           mppr = "MBC5";          break;

            case 0x1A: mapper = new MapperMBC5();           mppr = "MBC5";          break;

            case 0x1B: mapper = new MapperMBC5();           mppr = "MBC5";          break;

            case 0x1C: mapper = new MapperMBC5();           mppr = "MBC5";          break;

            case 0x1D: mapper = new MapperMBC5();           mppr = "MBC5";          break;

            case 0x1E: mapper = new MapperMBC5();           mppr = "MBC5";          break;

            case 0x20: mapper = new MapperMBC6();           mppr = "MBC6";          break;

            case 0x22: mapper = new MapperMBC7();           mppr = "MBC7";          break;

            case 0xFC: mapper = new MapperCamera();         mppr = "CAM";           break;

            case 0xFD: mapper = new MapperTAMA5();          mppr = "TAMA5";         break;

            case 0xFE: mapper = new MapperHuC3();           mppr = "HuC3";          break;

            case 0xFF: mapper = new MapperHuC1();           mppr = "HuC1";          break;

            // Bootleg mappers
            // NOTE: Sachen mapper selection does not account for scrambling, so if another bootleg mapper
            // identifies itself as 0x31, this will need to be modified
            case 0x31: mapper = new MapperSachen2();        mppr = "Schn2";         break;

            case 0x4:
            case 0x7:
            case 0xA:
            case 0xE:
            case 0x14:
            case 0x15:
            case 0x16:
            case 0x17:
            case 0x18:
            case 0x1F:
            case 0x21:
            default:
                // mapper not implemented
                Console.WriteLine(header[0x47]);
                throw new Exception("Mapper not implemented");
                break;
            }

            // special case for multi cart mappers
            if ((_rom.HashMD5(0, _rom.Length) == "97122B9B183AAB4079C8D36A4CE6E9C1") ||
                (_rom.HashMD5(0, _rom.Length) == "9FB9C42CF52DCFDCFBAD5E61AE1B5777") ||
                (_rom.HashMD5(0, _rom.Length) == "CF1F58AB72112716D3C615A553B2F481")
                )
            {
                Console.WriteLine("Using Multi-Cart Mapper");
                mapper = new MapperMBC1Multi();
            }

            Console.Write("Mapper: ");
            Console.WriteLine(mppr);

            cart_RAM = null;

            switch (header[0x49])
            {
            case 1:
                cart_RAM = new byte[0x800];
                break;

            case 2:
                cart_RAM = new byte[0x2000];
                break;

            case 3:
                cart_RAM = new byte[0x8000];
                break;

            case 4:
                cart_RAM = new byte[0x20000];
                break;

            case 5:
                cart_RAM = new byte[0x10000];
                break;
            }

            // Sachen maper not known to have RAM
            if ((mppr == "Schn1") || (mppr == "Schn2"))
            {
                cart_RAM = null;
            }

            // mbc2 carts have built in RAM
            if (mppr == "MBC2")
            {
                cart_RAM = new byte[0x200];
            }

            mapper.Core = this;
            mapper.Initialize();

            if (cart_RAM != null)
            {
                Console.Write("RAM: "); Console.WriteLine(cart_RAM.Length);

                if (_syncSettings.Use_SRAM)
                {
                    // load cartRAM here
                }
                else
                {
                    for (int i = 0; i < cart_RAM.Length; i++)
                    {
                        cart_RAM[i] = 0xFF;
                    }
                }
            }


            // Extra RTC initialization for mbc3
            if (mppr == "MBC3")
            {
                Use_RTC = true;
                int days = (int)Math.Floor(_syncSettings.RTCInitialTime / 86400.0);

                int days_upper = ((days & 0x100) >> 8) | ((days & 0x200) >> 2);

                mapper.RTC_Get((byte)days_upper, 4);
                mapper.RTC_Get((byte)(days & 0xFF), 3);

                int remaining = _syncSettings.RTCInitialTime - (days * 86400);

                int hours = (int)Math.Floor(remaining / 3600.0);

                mapper.RTC_Get((byte)(hours & 0xFF), 2);

                remaining = remaining - (hours * 3600);

                int minutes = (int)Math.Floor(remaining / 60.0);

                mapper.RTC_Get((byte)(minutes & 0xFF), 1);

                remaining = remaining - (minutes * 60);

                mapper.RTC_Get((byte)(remaining & 0xFF), 0);
            }
        }
Esempio n. 2
0
        private void Setup_Mapper()
        {
            // setup up mapper based on header entry
            string mppr;

            switch (header[0x47])
            {
            case 0x0: mapper = new MapperDefault();         mppr = "NROM";                                                  break;

            case 0x1: mapper = new MapperMBC1();            mppr = "MBC1";                                                  break;

            case 0x2: mapper = new MapperMBC1();            mppr = "MBC1";                                                  break;

            case 0x3: mapper = new MapperMBC1();            mppr = "MBC1";          has_bat = true;         break;

            case 0x5: mapper = new MapperMBC2();            mppr = "MBC2";                                                  break;

            case 0x6: mapper = new MapperMBC2();            mppr = "MBC2";          has_bat = true;         break;

            case 0x8: mapper = new MapperDefault();         mppr = "NROM";                                                  break;

            case 0x9: mapper = new MapperDefault();         mppr = "NROM";          has_bat = true;         break;

            case 0xB: mapper = new MapperMMM01();           mppr = "MMM01";                                                 break;

            case 0xC: mapper = new MapperMMM01();           mppr = "MMM01";                                                 break;

            case 0xD: mapper = new MapperMMM01();           mppr = "MMM01";         has_bat = true;         break;

            case 0xF: mapper = new MapperMBC3();            mppr = "MBC3";          has_bat = true;         break;

            case 0x10: mapper = new MapperMBC3();           mppr = "MBC3";          has_bat = true;         break;

            case 0x11: mapper = new MapperMBC3();           mppr = "MBC3";                                                  break;

            case 0x12: mapper = new MapperMBC3();           mppr = "MBC3";                                                  break;

            case 0x13: mapper = new MapperMBC3();           mppr = "MBC3";          has_bat = true;         break;

            case 0x19: mapper = new MapperMBC5();           mppr = "MBC5";                                                  break;

            case 0x1A: mapper = new MapperMBC5();           mppr = "MBC5";          has_bat = true;         break;

            case 0x1B: mapper = new MapperMBC5();           mppr = "MBC5";                                                  break;

            case 0x1C: mapper = new MapperMBC5();           mppr = "MBC5";                                                  break;

            case 0x1D: mapper = new MapperMBC5();           mppr = "MBC5";                                                  break;

            case 0x1E: mapper = new MapperMBC5();           mppr = "MBC5";          has_bat = true;         break;

            case 0x20: mapper = new MapperMBC6();           mppr = "MBC6";                                                  break;

            case 0x22: mapper = new MapperMBC7();           mppr = "MBC7";          has_bat = true;         break;

            case 0xFC: mapper = new MapperCamera();         mppr = "CAM";                                                   break;

            case 0xFD: mapper = new MapperTAMA5();          mppr = "TAMA5";                                                 break;

            case 0xFE: mapper = new MapperHuC3();           mppr = "HuC3";                                                  break;

            case 0xFF: mapper = new MapperHuC1();           mppr = "HuC1";                                                  break;

            // Bootleg mappers
            // NOTE: Sachen mapper selection does not account for scrambling, so if another bootleg mapper
            // identifies itself as 0x31, this will need to be modified
            case 0x31: mapper = new MapperSachen2();        mppr = "Schn2";                                                 break;

            case 0x4:
            case 0x7:
            case 0xA:
            case 0xE:
            case 0x14:
            case 0x15:
            case 0x16:
            case 0x17:
            case 0x18:
            case 0x1F:
            case 0x21:
            default:
                // mapper not implemented
                Console.WriteLine(header[0x47]);
                throw new Exception("Mapper not implemented");
            }

            // special case for multi cart mappers
            if ((_rom.HashMD5(0, _rom.Length) == "97122B9B183AAB4079C8D36A4CE6E9C1") ||
                (_rom.HashMD5(0, _rom.Length) == "9FB9C42CF52DCFDCFBAD5E61AE1B5777") ||
                (_rom.HashMD5(0, _rom.Length) == "CF1F58AB72112716D3C615A553B2F481")
                )
            {
                Console.WriteLine("Using Multi-Cart Mapper");
                mapper = new MapperMBC1Multi();
            }

            // Wisdom Tree does not identify their mapper, so use hash instead
            if ((_rom.HashMD5(0, _rom.Length) == "2C07CAEE51A1F0C91C72C7C6F380B0F6") ||             // Joshua
                (_rom.HashMD5(0, _rom.Length) == "37E017C8D1A45BAB609FB5B43FB64337") ||             // Spiritual Warfare
                (_rom.HashMD5(0, _rom.Length) == "AB1FA0ED0207B1D0D5F401F0CD17BEBF") ||             // Exodus
                (_rom.HashMD5(0, _rom.Length) == "BA2AC3587B3E1B36DE52E740274071B0") ||             // Bible - KJV
                (_rom.HashMD5(0, _rom.Length) == "8CDDB8B2DCD3EC1A3FDD770DF8BDA07C")                // Bible - NIV
                )
            {
                Console.WriteLine("Using Wisdom Tree Mapper");
                mapper = new MapperWT();
                mppr   = "Wtree";
            }

            // special case for bootlegs
            if ((_rom.HashMD5(0, _rom.Length) == "CAE0998A899DF2EE6ABA8E7695C2A096"))
            {
                Console.WriteLine("Using RockMan 8 (Unlicensed) Mapper");
                mapper = new MapperRM8();
            }
            if ((_rom.HashMD5(0, _rom.Length) == "D3C1924D847BC5D125BF54C2076BE27A"))
            {
                Console.WriteLine("Using Sachen 1 (Unlicensed) Mapper");
                mapper = new MapperSachen1();
                mppr   = "Schn1";
            }

            Console.Write("Mapper: ");
            Console.WriteLine(mppr);

            cart_RAM = null;

            switch (header[0x49])
            {
            case 1:
                cart_RAM = new byte[0x800];
                break;

            case 2:
                cart_RAM = new byte[0x2000];
                break;

            case 3:
                cart_RAM = new byte[0x8000];
                break;

            case 4:
                cart_RAM = new byte[0x20000];
                break;

            case 5:
                cart_RAM = new byte[0x10000];
                break;

            case 0:
                Console.WriteLine("Mapper Number indicates Battery Backed RAM but none present.");
                Console.WriteLine("Disabling Battery Setting.");
                has_bat = false;
                break;
            }

            // Sachen maper not known to have RAM
            if ((mppr == "Schn1") || (mppr == "Schn2"))
            {
                cart_RAM = null;
                Use_MT   = true;
            }

            // mbc2 carts have built in RAM
            if (mppr == "MBC2")
            {
                cart_RAM = new byte[0x200];
            }

            // mbc7 has 256 bytes of RAM, regardless of any header info
            if (mppr == "MBC7")
            {
                cart_RAM = new byte[0x100];
                has_bat  = true;
            }

            mapper.Core = this;
            mapper.Initialize();

            if (cart_RAM != null && (mppr != "MBC7"))
            {
                Console.Write("RAM: "); Console.WriteLine(cart_RAM.Length);

                for (int i = 0; i < cart_RAM.Length; i++)
                {
                    cart_RAM[i] = 0xFF;
                }
            }

            // Extra RTC initialization for mbc3
            if (mppr == "MBC3")
            {
                Use_MT = true;
                int days = (int)Math.Floor(_syncSettings.RTCInitialTime / 86400.0);

                int days_upper = ((days & 0x100) >> 8) | ((days & 0x200) >> 2);

                mapper.RTC_Get((byte)days_upper, 4);
                mapper.RTC_Get((byte)(days & 0xFF), 3);

                int remaining = _syncSettings.RTCInitialTime - (days * 86400);

                int hours = (int)Math.Floor(remaining / 3600.0);

                mapper.RTC_Get((byte)(hours & 0xFF), 2);

                remaining = remaining - (hours * 3600);

                int minutes = (int)Math.Floor(remaining / 60.0);

                mapper.RTC_Get((byte)(minutes & 0xFF), 1);

                remaining = remaining - (minutes * 60);

                mapper.RTC_Get((byte)(remaining & 0xFF), 0);
            }

            if (mppr == "HuC3")
            {
                Use_MT = true;

                int years = (int)Math.Floor(_syncSettings.RTCInitialTime / 31536000.0);

                mapper.RTC_Get((byte)years, 24);

                int remaining = _syncSettings.RTCInitialTime - (years * 31536000);

                int days       = (int)Math.Floor(remaining / 86400.0);
                int days_upper = (days >> 8) & 0xF;

                mapper.RTC_Get((byte)days_upper, 20);
                mapper.RTC_Get((byte)(days & 0xFF), 12);

                remaining = remaining - (days * 86400);

                int minutes       = (int)Math.Floor(remaining / 60.0);
                int minutes_upper = (minutes >> 8) & 0xF;

                mapper.RTC_Get((byte)(minutes_upper), 8);
                mapper.RTC_Get((byte)(remaining & 0xFF), 0);
            }
        }