static void WriteFlash(FamicomDumperConnection dumper, string fileName, WriteFlashRotMode rotMode = WriteFlashRotMode.None)
        {
            var nesFile  = new NesFile(fileName);
            int prgBanks = nesFile.PRG.Length / 0x8000;

            if (prgBanks * 0x8000 < nesFile.PRG.Length)
            {
                prgBanks++;
            }
            int chrBanks = nesFile.CHR.Length / 0x2000;

            if (chrBanks * 0x2000 < nesFile.CHR.Length)
            {
                chrBanks++;
            }

            Console.Write("Erasing PRG FLASH... ");
            dumper.Timeout = 3000000;
            dumper.ErasePrgFlash();
            Console.WriteLine("Done!");
            Console.Write("Writing PRG FLASH... ");
            dumper.Timeout = 10000;
            int writed = 0;

            for (byte bank = 0; bank < 16; bank++)
            {
                int pos;
                if (bank < prgBanks)
                {
                    pos = bank * 0x8000;
                }
                else if (rotMode == WriteFlashRotMode.LastBanksOnly)
                {
                    if (bank >= prgBanks && bank < 15)
                    {
                        continue;
                    }
                    pos = (prgBanks - 1) * 0x8000; // last bank
                }
                else if (rotMode == WriteFlashRotMode.Full)
                {
                    pos = (bank % prgBanks) * 0x8000;
                }
                else
                {
                    continue;
                }
                var data = new byte[0x8000];
                Array.Copy(nesFile.PRG, pos, data, 0, Math.Min(0x8000, nesFile.PRG.Length - pos));
                if (bank == prgBanks - 1 && nesFile.PRG.Length - pos < 0x8000)
                {
                    Array.Copy(nesFile.PRG, pos, data, 0x8000 - (nesFile.PRG.Length - pos), nesFile.PRG.Length - pos);
                }
                dumper.WriteCpu(0x0000, (byte)(bank));
                dumper.WritePrgFlash(0x0000, data);
                writed++;
                switch (rotMode)
                {
                case WriteFlashRotMode.None:
                    Console.Write("{0}% ", 100 * writed / prgBanks);
                    break;

                case WriteFlashRotMode.LastBanksOnly:
                    Console.Write("{0}% ", 100 * writed / (prgBanks + 1));
                    break;

                case WriteFlashRotMode.Full:
                    Console.Write("{0}% ", 100 * writed / 16);
                    break;
                }
            }

            Console.WriteLine("Done! {0} banks writed.", writed);

            Console.Write("Erasing CHR FLASH... ");
            dumper.EraseChrFlash();
            Console.WriteLine("Done!");
            Console.Write("Writing CHR FLASH... ");
            for (byte bank = 0; bank < chrBanks; bank++)
            {
                int pos  = bank * 0x2000;
                var data = new byte[0x2000];
                Array.Copy(nesFile.CHR, pos, data, 0, Math.Min(0x2000, nesFile.CHR.Length - pos));
                dumper.WriteCpu(0x4000, bank);
                dumper.WriteChrFlash(0x0000, data);
                if (chrBanks > 1)
                {
                    Console.Write("{0}% ", 100 * (bank + 1) / chrBanks);
                }
            }

            Console.WriteLine("Done! {0} banks writed.", chrBanks);
        }