Esempio n. 1
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            Console.Write("Reading random PRG... ");
            byte[] lastBank = dumper.ReadCpu(0x8000, 0x8000);
            Console.WriteLine("OK");

            var banks = size / 0x8000;

            for (var bank = 0; bank < banks; bank++)
            {
                Console.Write("Reading PRG bank #{0}... ", bank);
                // Avoiding bus conflicts
                bool noBusConflict = false;
                for (int i = 0; i < lastBank.Length; i++)
                {
                    if (lastBank[i] == bank)
                    {
                        dumper.WriteCpu((ushort)(0x8000 + i), (byte)bank);
                        noBusConflict = true;
                        break;
                    }
                }
                if (!noBusConflict) // Whatever...
                {
                    dumper.WriteCpu((ushort)0x8000, (byte)bank);
                }
                lastBank = dumper.ReadCpu(0x8000, 0x8000);
                data.AddRange(lastBank);
                Console.WriteLine("OK");
            }
        }
Esempio n. 2
0
    public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        var banks = (byte)(size / 0x4000);

        Console.Write("Reading last PRG bank... ");
        var lastBank = dumper.ReadCpu(0xC000, 0x4000);

        Console.WriteLine("OK");
        for (int bank = 0; bank < banks - 1; bank++)
        {
            Console.Write($"Reading PRG bank #{bank}/{banks}... ");
            // Avoiding bus conflicts
            var noBusConflict = false;
            for (var i = 0; i < lastBank.Length; i++)
            {
                if (lastBank[i] == bank)
                {
                    dumper.WriteCpu((ushort)(0xC000 + i), (byte)bank);
                    noBusConflict = true;
                    break;
                }
            }
            if (!noBusConflict) // Whatever...
            {
                dumper.WriteCpu(0x8000, (byte)bank);
            }
            data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
            Console.WriteLine("OK");
        }
        data.AddRange(lastBank);
    }
    void Run(IFamicomDumperConnection dumper)
    {
        try
        {
            // Just simple test that RAM adapter is connected
            bool ramAdapterPresent = true;
            dumper.WriteCpu(0x4023, 0x01);       // enable disk registers
            dumper.WriteCpu(0x4026, 0x00);
            dumper.WriteCpu(0x4025, 0b00100110); // reset
            dumper.WriteCpu(0x0000, 0xFF);       // to prevent open bus read
            var ext = dumper.ReadCpu(0x4033);
            if (ext != 0x00)
            {
                ramAdapterPresent = false;
            }
            dumper.WriteCpu(0x4026, 0xFF);
            dumper.WriteCpu(0x0000, 0x00); // to prevent open bus read
            ext = dumper.ReadCpu(0x4033);
            if ((ext & 0x7F) != 0x7F)
            {
                ramAdapterPresent = false;
            }
            if (!ramAdapterPresent)
            {
                throw new IOException("Famicom Disk System RAM adapter IO error, is it connected?");
            }

            dumper.WriteCpu(0x4025, 0b00100110); // reset
            dumper.WriteCpu(0x4025, 0b00100101); // enable motor without data transfer
            Thread.Sleep(100);
            // Check battery health
            ext = dumper.ReadCpu(0x4033);
            if ((ext & 0x80) == 0)
            {
                throw new IOException("Battery voltage is low or power supply is not connected");
            }

            Console.WriteLine("Measuring FDS drive speed, make sure that disk card is inserted and wait. Press any key to stop.");
            var cancellationTokenSource = new CancellationTokenSource();
            var task = SpeedMeasureLoop(dumper, cancellationTokenSource.Token);
            Console.ReadKey();
            cancellationTokenSource.Cancel();
            task.GetAwaiter().GetResult();
        }
        finally
        {
            // Stop
            dumper.WriteCpu(0x4025, 0b00100110);
        }
    }
 public static void PPBClear(IFamicomDumperConnection dumper)
 {
     LockBitsCheckPrint(dumper);
     PPBLockBitCheckPrint(dumper);
     Console.Write($"Erasing all PBBs... ");
     // PPB Command Set Entry
     dumper.WriteCpu(0x8AAA, 0xAA);
     dumper.WriteCpu(0x8555, 0x55);
     dumper.WriteCpu(0x8AAA, 0xC0);
     // All PPB Erase
     dumper.WriteCpu(0x8000, 0x80);
     dumper.WriteCpu(0x8000, 0x30);
     // Check
     try
     {
         DateTime startTime = DateTime.Now;
         while (true)
         {
             byte b = dumper.ReadCpu(0x8000);
             if (b == 0x01)
             {
                 break;
             }
             if ((DateTime.Now - startTime).TotalMilliseconds >= 1500)
             {
                 throw new IOException("PPB clear failed");
             }
         }
     }
     finally
     {
         ResetFlash(dumper);
     }
     Console.WriteLine("OK");
 }
    async Task SpeedMeasureLoop(IFamicomDumperConnection dumper, CancellationToken cancellationToken = default)
    {
        DateTime?lastCycleTime = null;

        while (true)
        {
            // Reset
            dumper.WriteCpu(0x4025, 0b00100110); // reset
            dumper.WriteCpu(0x4025, 0b00100101); // enable motor without data transfer

            // Wait for ready state
            while ((dumper.ReadCpu(0x4032) & 2) != 0)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }
                await Task.Delay(1);
            }

            // Calculate and print cycle duration
            if (lastCycleTime != null)
            {
                Console.WriteLine($"Full cycle time: {(int)(DateTime.Now - lastCycleTime.Value).TotalMilliseconds} ms");
            }
            // Remember cycle start time
            lastCycleTime = DateTime.Now;
        }
    }
 public static void LockBitsCheckPrint(IFamicomDumperConnection dumper)
 {
     try
     {
         // Lock Register Set Entry
         dumper.WriteCpu(0x8AAA, 0xAA);
         dumper.WriteCpu(0x8555, 0x55);
         dumper.WriteCpu(0x8AAA, 0x40);
         var lockRegister = dumper.ReadCpu(0x8000);
         if ((lockRegister & 1) == 0)
         {
             Console.WriteLine("WARNING: Secured Silicon Sector Protection Bit is set!");
         }
         if ((lockRegister & 2) == 0)
         {
             Console.WriteLine("WARNING: Persistent Protection Mode Lock Bit is set!");
         }
         if ((lockRegister & 4) == 0)
         {
             Console.WriteLine("WARNING: Password Protection Mode Lock Bit is set!");
         }
     }
     finally
     {
         ResetFlash(dumper);
     }
 }
 public static void PPBSet(IFamicomDumperConnection dumper)
 {
     Console.Write("Writing PPB for sector... ");
     // PPB Command Set Entry
     dumper.WriteCpu(0x8AAA, 0xAA);
     dumper.WriteCpu(0x8555, 0x55);
     dumper.WriteCpu(0x8AAA, 0xC0);
     // PPB Program
     dumper.WriteCpu(0x8000, 0xA0);
     dumper.WriteCpu(0x8000, 0x00);
     // Check
     try
     {
         DateTime startTime = DateTime.Now;
         while (true)
         {
             byte b = dumper.ReadCpu(0x8000);
             if (b == 0x00)
             {
                 break;
             }
             if ((DateTime.Now - startTime).TotalMilliseconds >= 1500)
             {
                 throw new IOException("PPB write failed");
             }
         }
     }
     finally
     {
         ResetFlash(dumper);
     }
     Console.WriteLine("OK");
 }
Esempio n. 8
0
 public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
 {
     Console.Write("Reading PRG... ");
     prg = dumper.ReadCpu(0x8000, size);
     data.AddRange(prg);
     Console.WriteLine("OK");
 }
Esempio n. 9
0
    public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        dumper.Reset();
        version = DetectVersion(dumper);
        UInt16 coolboyReg = (UInt16)(version == 2 ? 0x5000 : 0x6000);
        int    banks      = size / 0x4000;

        for (var bank = 0; bank < banks; bank++)
        {
            var r0 = (byte)(((bank >> 3) & 0x07)          // 5, 4, 3 bits
                            | (((bank >> 9) & 0x03) << 4) // 10, 9 bits
                            | (1 << 6));                  // resets 4th mask bit
            var r1 = (byte)((((bank >> 7) & 0x03) << 2)   // 8, 7
                            | (((bank >> 6) & 1) << 4)    // 6
                            | (1 << 7));                  // resets 5th mask bit
            var r2 = (byte)0;
            var r3 = (byte)((1 << 4)                      // NROM mode
                            | ((bank & 7) << 1));         // 2, 1, 0 bits
            dumper.WriteCpu(coolboyReg, r0, r1, r2, r3);

            Console.Write($"Reading PRG bank #{bank}/{banks}... ");
            data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
            Console.WriteLine("OK");
        }
    }
Esempio n. 10
0
    // But method signature must be like this. Also you can make this method static.
    void Run(IFamicomDumperConnection dumper, string[] args)
    {
        // You can parse additional command line arguments if need
        // Specify arguments this way: >FamicomDumper.exe script --csfile DemoScript.cs - argument1 argument2 argument3
        if (args.Any())
        {
            Console.WriteLine("Command line arguments: " + string.Join(", ", args));
        }

        Console.WriteLine("Please insert MMC3 cartridge and press enter");
        Console.ReadLine();

        Console.WriteLine("Let's check - how many PRG banks on this MMC3 cartridge");
        byte[] firstBank = null;
        for (var bank = 0; ; bank = bank == 0 ? 1 : bank * 2)
        {
            if (bank > 256)
            {
                throw new InvalidDataException("Bank number out of range, did you actually insert the MMC3 cartridge?");
            }
            Console.Write($"Reading PRG bank #{bank}... ");
            dumper.WriteCpu(0x8000, 6, (byte)bank);
            var data = dumper.ReadCpu(0x8000, 0x2000);
            Console.WriteLine("OK");
            if (bank == 0)
            {
                firstBank = data;
            }
            else if (Enumerable.SequenceEqual(data, firstBank))
            {
                Console.WriteLine($"There are {bank} PRG banks on this cartridge, {bank * 0x2000 / 1024} KBytes in total");
                break;
            }
        }

        Console.WriteLine("Let's check - how many CHR banks on this MMC3 cartridge");
        for (var bank = 0; ; bank = bank == 0 ? 1 : bank * 2)
        {
            if (bank > 256)
            {
                throw new InvalidDataException("Bank number out of range, did you actually insert the MMC3 cartridge?");
            }
            Console.Write($"Reading CHR bank #{bank}... ");
            dumper.WriteCpu(0x8000, 2, (byte)bank);
            var data = dumper.ReadPpu(0x1000, 0x0400);
            Console.WriteLine("OK");
            if (bank == 0)
            {
                firstBank = data;
            }
            else if (Enumerable.SequenceEqual(data, firstBank))
            {
                Console.WriteLine($"There are {bank} CHR banks on this cartridge, {bank * 0x0400 / 1024} KBytes in total");
                break;
            }
        }
    }
Esempio n. 11
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            var banks = size / 0x2000;

            dumper.WriteCpu(0x6000, 0);
            for (var bank = 0; bank < banks - 2; bank += 2)
            {
                Console.Write("Reading PRG banks #{0} and #{1}... ", bank, bank + 1);
                dumper.WriteCpu(ScrumbleAddress(0x8000), ScrumbleValues(6));
                dumper.WriteCpu(ScrumbleAddress(0x8001), (byte)bank);
                dumper.WriteCpu(ScrumbleAddress(0x8000), ScrumbleValues(7));
                dumper.WriteCpu(ScrumbleAddress(0x8001), (byte)(bank | 1));
                data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
                Console.WriteLine("OK");
            }
            Console.Write("Reading last PRG banks #{0} and #{1}... ", banks - 2, banks - 1);
            data.AddRange(dumper.ReadCpu(0xC000, 0x4000));
            Console.WriteLine("OK");
        }
Esempio n. 12
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            var banks = size / 0x2000;

            if (banks > 256)
            {
                throw new ArgumentOutOfRangeException("size", "PRG size is too big");
            }
            for (var bank = 0; bank < banks - 2; bank += 2)
            {
                Console.Write("Reading PRG banks #{0} and #{1}... ", bank, bank + 1);
                dumper.WriteCpu(0x8000, new byte[] { 6, (byte)bank });
                dumper.WriteCpu(0x8000, new byte[] { 7, (byte)(bank | 1) });
                data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
                Console.WriteLine("OK");
            }
            Console.Write("Reading last PRG banks #{0} and #{1}... ", banks - 2, banks - 1);
            data.AddRange(dumper.ReadCpu(0xC000, 0x4000));
            Console.WriteLine("OK");
        }
Esempio n. 13
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            dumper.WriteCpu(0x8000, 0x80);
            WriteMMC1(dumper, 0x8000, 0x0C);

            var banks = size / 0x4000;

            for (var bank = 0; bank < banks - 1; bank++)
            {
                Console.Write("Reading PRG bank #{0}... ", bank);
                WriteMMC1(dumper, 0xE000, (byte)bank);
                data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
                Console.WriteLine("OK");
            }
            if (banks > 0)
            {
                Console.Write("Reading last PRG bank #{0}... ", banks - 1);
                data.AddRange(dumper.ReadCpu(0xC000, 0x4000));
                Console.WriteLine("OK");
            }
        }
Esempio n. 14
0
    public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        var banks = size / 0x4000;

        for (var bank = 0; bank < banks; bank++)
        {
            Console.Write($"Reading PRG bank #{bank}/{banks}... ");
            dumper.WriteCpu(0x8000, (byte)bank);
            data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
            Console.WriteLine("OK");
        }
    }
Esempio n. 15
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            var banks = size / 0x4000;

            for (var bank = 0; bank < banks; bank++)
            {
                Console.Write("Reading PRG bank #{0}... ", bank);
                dumper.WriteCpu((ushort)(0x8000 | (bank << 1)), 0);
                data.AddRange(dumper.ReadCpu(0xC000, 0x4000));
                Console.WriteLine("OK");
            }
        }
Esempio n. 16
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            var banks = size / 0x2000;

            dumper.WriteCpu(0x5100, 3); // bank mode #3, four 8KB banks
            for (var bank = 0; bank < banks; bank++)
            {
                Console.Write("Reading PRG bank #{0}... ", bank);
                dumper.WriteCpu(0x5114, (byte)(bank | 0x80));
                data.AddRange(dumper.ReadCpu(0x8000, 0x2000));
                Console.WriteLine("OK");
            }
        }
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            var banks = size / 0x2000;

            for (var bank = 0; bank < banks; bank++)
            {
                Console.Write("Reading PRG bank #{0}... ", bank);
                dumper.WriteCpu(0x8000, 9); // Bank $9 - CPU $8000-$9FFF
                dumper.WriteCpu(0xA000, (byte)bank);
                data.AddRange(dumper.ReadCpu(0x8000, 0x2000));
                Console.WriteLine("OK");
            }
        }
Esempio n. 18
0
    public void DumpPrg(IFamicomDumperConnection dumper, List<byte> data, int size)
    {
        var banks = size / 0x2000;

        dumper.WriteCpu(0x9004 | 0x9080, 0); // disable swap mode
        for (var bank = 0; bank < banks; bank++)
        {
            Console.Write($"Reading PRG bank #{bank}/{banks}... ");
            dumper.WriteCpu(0x8000, (byte)bank); // PRG Select 0
            data.AddRange(dumper.ReadCpu(0x8000, 0x2000));
            Console.WriteLine("OK");
        }
    }
Esempio n. 19
0
    void Run(IFamicomDumperConnection dumper, IMapper mapper, string[] args)
    {
        int count = -1;

        if (args.Any())
        {
            count = int.Parse(args.First());
        }
        if (mapper != null)
        {
            if (mapper.Number >= 0)
            {
                Console.WriteLine($"Using mapper: #{mapper.Number} ({mapper.Name})");
            }
            else
            {
                Console.WriteLine($"Using mapper: {mapper.Name}");
            }
            mapper.EnablePrgRam(dumper);
        }
        var rnd = new Random();

        while (count != 0)
        {
            var data = new byte[0x2000];
            rnd.NextBytes(data);
            Console.Write("Writing PRG RAM... ");
            dumper.WriteCpu(0x6000, data);
            Console.Write("Reading PRG RAM... ");
            var  rdata = dumper.ReadCpu(0x6000, 0x2000);
            bool ok    = true;
            for (int b = 0; b < 0x2000; b++)
            {
                if (data[b] != rdata[b])
                {
                    Console.WriteLine($"Mismatch at {b:X4}: {rdata[b]:X2} != {data[b]:X2}");
                    ok = false;
                }
            }
            if (!ok)
            {
                File.WriteAllBytes("prgramgood.bin", data);
                Console.WriteLine("prgramgood.bin writed");
                File.WriteAllBytes("prgrambad.bin", rdata);
                Console.WriteLine("prgrambad.bin writed");
                throw new InvalidDataException("Failed!");
            }
            Console.WriteLine("OK!");
            count--;
        }
    }
Esempio n. 20
0
    public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        var banks = size / 0x2000;

        dumper.WriteCpu(0x6000, 0);
        for (var bank = 0; bank < banks; bank++)
        {
            Console.Write($"Reading PRG banks #{bank}/{banks}... ");
            dumper.WriteCpu(ScrumbleAddress(0x8000), ScrumbleValues(6));
            dumper.WriteCpu(ScrumbleAddress(0x8001), (byte)bank);
            data.AddRange(dumper.ReadCpu(0x8000, 0x2000));
            Console.WriteLine("OK");
        }
        Console.WriteLine("OK");
    }
Esempio n. 21
0
        public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
        {
            var outbanks = size / (256 * 1024);

            for (byte outbank = 0; outbank < outbanks; outbank += 1)
            {
                dumper.Reset();
                dumper.WriteCpu(0xA001, 0x80); // RAM protect
                dumper.WriteCpu((ushort)(0x6828 | (outbank << 1)), 0x00);
                dumper.WriteCpu(0xA001, 0);    // disable W-RAM
                const int banks = 32;
                for (var bank = 0; bank < banks - 2; bank += 2)
                {
                    Console.Write("Reading PRG banks #{2}|{0} and #{2}|{1}... ", bank, bank + 1, outbank);
                    dumper.WriteCpu(0x8000, new byte[] { 6, (byte)bank });
                    dumper.WriteCpu(0x8000, new byte[] { 7, (byte)(bank | 1) });
                    data.AddRange(dumper.ReadCpu(0x8000, 0x4000));
                    Console.WriteLine("OK");
                }
                Console.Write("Reading last PRG banks #{2}|{0} and #{2}|{1}... ", banks - 2, banks - 1, outbank);
                data.AddRange(dumper.ReadCpu(0xC000, 0x4000));
                Console.WriteLine("OK");
            }
        }
 public static byte PPBRead(IFamicomDumperConnection dumper)
 {
     try
     {
         // PPB Command Set Entry
         dumper.WriteCpu(0x8AAA, 0xAA);
         dumper.WriteCpu(0x8555, 0x55);
         dumper.WriteCpu(0x8AAA, 0xC0);
         // PPB Status Read
         return(dumper.ReadCpu(0x8000));
     }
     finally
     {
         ResetFlash(dumper);
     }
 }
Esempio n. 23
0
    void Run(IFamicomDumperConnection dumper, IMapper mapper)
    {
        if (mapper != null)
        {
            if (mapper.Number >= 0)
            {
                Console.WriteLine($"Using mapper: #{mapper.Number} ({mapper.Name})");
            }
            else
            {
                Console.WriteLine($"Using mapper: {mapper.Name}");
            }
            mapper.EnablePrgRam(dumper);
        }
        var rnd  = new Random();
        var data = new byte[0x2000];

        rnd.NextBytes(data);
        Console.Write("Writing PRG RAM... ");
        dumper.WriteCpu(0x6000, data);
        Console.WriteLine("OK");
        Console.WriteLine("Replug cartridge and press any key");
        Console.ReadKey();
        Console.WriteLine();
        Console.Write("Reading PRG RAM... ");
        var  rdata = dumper.ReadCpu(0x6000, 0x2000);
        bool ok    = true;

        for (int b = 0; b < 0x2000; b++)
        {
            if (data[b] != rdata[b])
            {
                Console.WriteLine($"Mismatch at {b:X4}: {rdata[b]:X2} != {data[b]:X2}");
                ok = false;
            }
        }
        if (!ok)
        {
            File.WriteAllBytes("prgramgood.bin", data);
            Console.WriteLine("prgramgood.bin writed");
            File.WriteAllBytes("prgrambad.bin", rdata);
            Console.WriteLine("prgrambad.bin writed");
            throw new InvalidDataException("Failed!");
        }
        Console.WriteLine("OK!");
        Console.WriteLine("Battery is OK!");
    }
Esempio n. 24
0
    public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        var banks = size / 0x2000;

        if (banks > 256)
        {
            throw new ArgumentOutOfRangeException("size", "PRG size is too big");
        }
        for (var bank = 0; bank < banks; bank++)
        {
            Console.Write($"Reading PRG banks #{bank}/{banks}... ");
            dumper.WriteCpu(0x8000, 6, (byte)bank);
            data.AddRange(dumper.ReadCpu(0x8000, 0x2000));
            Console.WriteLine("OK");
        }
        Console.WriteLine("OK");
    }
    public static void TestPrgRam(IFamicomDumperConnection dumper, int count)
    {
        Console.Write("Reset... ");
        dumper.Reset();
        Console.WriteLine("OK");
        dumper.WriteCpu(0x5007, 0x01); // enable PRG RAM
        var rnd = new Random();

        while (count != 0)
        {
            var data = new byte[][] { new byte[0x2000], new byte[0x2000], new byte[0x2000], new byte[0x2000] };
            for (byte bank = 0; bank < 4; bank++)
            {
                Console.WriteLine($"Writing PRG RAM, bank #{bank}/{4}... ");
                rnd.NextBytes(data[bank]);
                dumper.WriteCpu(0x5005, bank);
                dumper.WriteCpu(0x6000, data[bank]);
            }
            for (byte bank = 0; bank < 4; bank++)
            {
                Console.Write($"Reading PRG RAM, bank #{bank}/{4}... ");
                dumper.WriteCpu(0x5005, bank);
                var  rdata = dumper.ReadCpu(0x6000, 0x2000);
                bool ok    = true;
                for (int b = 0; b < 0x2000; b++)
                {
                    if (data[bank][b] != rdata[b])
                    {
                        Console.WriteLine($"Mismatch at {b:X4}: {rdata[b]:X2} != {data[bank][b]:X2}");
                        ok = false;
                    }
                }
                if (!ok)
                {
                    File.WriteAllBytes("prgramgood.bin", data[bank]);
                    Console.WriteLine("prgramgood.bin writed");
                    File.WriteAllBytes("prgrambad.bin", rdata);
                    Console.WriteLine("prgrambad.bin writed");
                    throw new InvalidDataException("Test failed");
                }
                Console.WriteLine("OK");
            }
            count--;
        }
    }
 public static CFIInfo GetCFIInfo(IFamicomDumperConnection dumper)
 {
     try
     {
         dumper.WriteCpu(0x8AAA, 0x98); // CFI mode
         var cfiRaw = dumper.ReadCpu(0x8000, 0x100);
         if (cfiRaw[0x20] != 0x51 || cfiRaw[0x22] != 0x52 || cfiRaw[0x24] != 0x59)
         {
             throw new IOException("Can't enter CFI mode. Invalid flash memory? Broken cartridge? Is it inserted?");
         }
         var cfi = new CFIInfo(cfiRaw, CFIInfo.ParseMode.Every2Bytes);
         return(cfi);
     }
     finally
     {
         dumper.WriteCpu(0x8000, 0xF0);
     }
 }
 public static void PPBLockBitCheckPrint(IFamicomDumperConnection dumper)
 {
     try
     {
         // PPB Lock Command Set Entry
         dumper.WriteCpu(0x8AAA, 0xAA);
         dumper.WriteCpu(0x8555, 0x55);
         dumper.WriteCpu(0x8AAA, 0x50);
         var ppbLockStatus = dumper.ReadCpu(0x8000);
         if (ppbLockStatus == 0)
         {
             Console.WriteLine("WARNING: PPB Lock Bit is set!");
         }
     }
     finally
     {
         ResetFlash(dumper);
     }
 }
Esempio n. 28
0
        // But method signature must be like this. Also you can make this method static.
        void Run(IFamicomDumperConnection dumper)
        {
            Console.WriteLine("Please insert MMC3 cartridge and press any key");
            Console.ReadKey();

            Console.WriteLine("Let's check - how many PRG banks on this MMC3 cartridge");
            byte[] firstBank = null;
            for (var bank = 0; ; bank = bank == 0 ? 1 : bank * 2)
            {
                Console.Write("Reading PRG bank #{0}... ", bank);
                dumper.WriteCpu(0x8000, new byte[] { 6, (byte)bank });
                var data = dumper.ReadCpu(0x8000, 0x2000);
                Console.WriteLine("OK");
                if (bank == 0)
                {
                    firstBank = data;
                }
                else if (Enumerable.SequenceEqual(data, firstBank))
                {
                    Console.WriteLine("There are {0} PRG banks on this cartridge, {1} KBytes in total", bank, bank * 0x2000 / 1024);
                    break;
                }
            }

            Console.WriteLine("Let's check - how many CHR banks on this MMC3 cartridge");
            for (var bank = 0; ; bank = bank == 0 ? 1 : bank * 2)
            {
                Console.Write("Reading CHR bank #{0}... ", bank);
                dumper.WriteCpu(0x8000, new byte[] { 2, (byte)bank });
                var data = dumper.ReadPpu(0x1000, 0x0400);
                Console.WriteLine("OK");
                if (bank == 0)
                {
                    firstBank = data;
                }
                else if (Enumerable.SequenceEqual(data, firstBank))
                {
                    Console.WriteLine("There are {0} CHR banks on this cartridge, {1} KBytes in total", bank, bank * 0x0400 / 1024);
                    break;
                }
            }
        }
Esempio n. 29
0
    public void DumpPrg(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        var banks = size / 0x8000;

        Console.Write("Reset... ");
        dumper.Reset();
        Console.WriteLine("OK");
        dumper.WriteCpu(0x5002, 0xFE); // mask = 32K
        for (int bank = 0; bank < banks; bank++)
        {
            var r0 = (byte)(bank >> 7);
            var r1 = (byte)(bank << 1);
            dumper.WriteCpu(0x5000, r0);
            dumper.WriteCpu(0x5001, r1);

            Console.Write($"Reading PRG bank #{bank}/{banks}... ");
            data.AddRange(dumper.ReadCpu(0x8000, 0x8000));
            Console.WriteLine("OK");
        }
    }
Esempio n. 30
0
    public void DumpChr(IFamicomDumperConnection dumper, List <byte> data, int size)
    {
        if (prg == null)
        {
            prg = dumper.ReadCpu(0x8000, DefaultPrgSize);
        }
        var banks = size / 0x2000;

        for (var bank = 0; bank < banks; bank++)
        {
            Console.Write($"Reading CHR bank #{bank}/{banks}... ");
            // Avoiding bus conflicts
            for (var i = 0; i < prg.Length; i++)
            {
                if (prg[i] == bank)
                {
                    dumper.WriteCpu((ushort)(0x8000 + i), (byte)bank);
                    break;
                }
            }
            data.AddRange(dumper.ReadPpu(0x0000, 0x2000));
            Console.WriteLine("OK");
        }
    }