コード例 #1
0
        private static void CheckRAMAdapter(IFamicomDumperConnectionExt dumper)
        {
            // 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("RAM adapter IO error, is it connected?");
            }
        }
コード例 #2
0
        public override Task <ReadResponse> ReadCpu(ReadRequest request, ServerCallContext context)
        {
            var result = new ReadResponse();

            try
            {
                if (request.Length > 1)
                {
                    Console.Write($"Reading 0x{request.Address:X4}-0x{request.Address + request.Length - 1:X4} @ CPU... ");
                }
                else
                {
                    Console.Write($"Reading 0x{request.Address:X4} @ CPU... ");
                }
                byte[] data;
                if (request.HasLength)
                {
                    data = dumper.ReadCpu((ushort)request.Address, (ushort)request.Length);
                }
                else
                {
                    data = new byte[] { dumper.ReadCpu((ushort)request.Address) }
                };
                if (data.Length <= 32)
                {
                    foreach (var b in data)
                    {
                        Console.Write($"{b:X2} ");
                    }
                    Console.WriteLine();
                }
                else
                {
                    Console.WriteLine("OK");
                }
                result.Data = ByteString.CopyFrom(data);
            }
            catch (Exception ex)
            {
                PrintError(ex);
                result.ErrorInfo = new ErrorInfo()
                {
                    ExceptionName    = ex.GetType().ToString(),
                    ExceptionMessage = ex.Message
                };
            }
            return(Task.FromResult(result));
        }
コード例 #3
0
        public static void DumpFDS(IFamicomDumperConnectionExt dumper, string fileName, byte sides = 1, bool dumpHiddenFiles = true, bool useHeader = true)
        {
            if (dumper.ProtocolVersion < 3)
            {
                throw new NotSupportedException("Dumper firmware version is too old, update it to read/write FDS cards");
            }
            CheckRAMAdapter(dumper);

            var sideImages = new List <FdsDiskSide>();

            for (int side = 1; side <= sides; side++)
            {
                var driveStatus = dumper.ReadCpu(0x4032);
                if ((driveStatus & 1) != 0)
                {
                    Console.Write($"Please set disk card, side #{side}... ");
                    while ((driveStatus & 1) != 0)
                    {
                        Thread.Sleep(100);
                        driveStatus = dumper.ReadCpu(0x4032);
                    }
                    Console.WriteLine("OK");
                }
                var sideImage = DumpFDSSide(dumper, dumpHiddenFiles, printDiskInfo: true);
                sideImages.Add(sideImage);

                if (side < sides)
                {
                    driveStatus = dumper.ReadCpu(0x4032);
                    if ((driveStatus & 1) == 0)
                    {
                        Console.Write($"Please remove disk card... ");
                        while ((driveStatus & 1) == 0)
                        {
                            Thread.Sleep(100);
                            driveStatus = dumper.ReadCpu(0x4032);
                        }
                        Console.WriteLine("OK");
                    }
                }
            }
            Console.Write($"Saving to {fileName}... ");
            var fdsImage = new FdsFile(sideImages);

            fdsImage.Save(fileName, useHeader);
            Console.WriteLine("OK");
        }
コード例 #4
0
        public static void WriteFDS(IFamicomDumperConnectionExt dumper, string fileName, bool needCheck = false)
        {
            if (dumper.ProtocolVersion < 3)
            {
                throw new NotSupportedException("Dumper firmware version is too old, update it to read/write FDS cards");
            }
            var oldTimeout = dumper.Timeout;

            try
            {
                dumper.Timeout = 30000;
                //CheckRAMAdapter(dumper);

                var rom = new FdsFile(fileName);

                for (int sideNumber = 0; sideNumber < rom.Sides.Count; sideNumber++)
                {
                    var driveStatus = dumper.ReadCpu(0x4032);
                    if ((driveStatus & 1) != 0)
                    {
                        Console.Write($"Please set disk card, side #{sideNumber + 1}... ");
                        while ((driveStatus & 1) != 0)
                        {
                            Thread.Sleep(100);
                            driveStatus = dumper.ReadCpu(0x4032);
                        }
                        Console.WriteLine("OK");
                    }

                    PrintDiskHeaderInfo(rom.Sides[sideNumber].DiskInfoBlock);
                    Console.WriteLine($"Number of non-hidden files: {rom.Sides[sideNumber].FileAmount}");
                    Console.WriteLine($"Number of hidden files: {rom.Sides[sideNumber].Files.Count - rom.Sides[sideNumber].FileAmount}");
                    var blocks = rom.Sides[sideNumber].GetBlocks().ToArray();
                    Console.WriteLine($"Total blocks to write: {blocks.Length}");
                    byte blocksWrited = 0;
                    while (blocksWrited < blocks.Length)
                    {
                        uint totalSize     = 1;
                        var  blockIDs      = new List <byte>();
                        var  blocksToWrite = new List <IFdsBlock>();

                        for (byte i = blocksWrited; i < blocks.Length; i++)
                        {
                            if (totalSize + blocks[i].Length + 3 <= dumper.MaxWritePacketSize)
                            {
                                blocksToWrite.Add(blocks[i]);
                                blockIDs.Add(i);
                                totalSize += blocks[i].Length + 3;
                            }
                            else
                            {
                                break;
                            }
                        }
                        if (!blocksToWrite.Any())
                        {
                            throw new OutOfMemoryException("Dumper has not enoght memory to write such big block");
                        }
                        Console.Write($"Writing block(s): {string.Join(", ", blockIDs)}... ");
                        dumper.WriteFdsBlocks(blockIDs.ToArray(), blocksToWrite.Select(b => b.ToBytes()).ToArray());
                        Console.WriteLine("OK");
                        blocksWrited += (byte)blocksToWrite.Count;
                    }

                    if (needCheck)
                    {
                        Console.WriteLine("Starting verification process");
                        var hiddenFiles = rom.Sides[sideNumber].Files.Count > rom.Sides[sideNumber].FileAmount;
                        var sideImage   = DumpFDSSide(dumper, dumpHiddenFiles: hiddenFiles, printDiskInfo: false);
                        if (!sideImage.DiskInfoBlock.Equals(rom.Sides[sideNumber].DiskInfoBlock))
                        {
                            throw new IOException("Disk info block verification failed");
                        }
                        if (!sideImage.FileAmount.Equals(rom.Sides[sideNumber].FileAmount))
                        {
                            throw new IOException("File amount block verification failed");
                        }
                        if (sideImage.Files.Count < rom.Sides[sideNumber].Files.Count)
                        {
                            throw new IOException($"Invalid file count: {sideImage.Files.Count} < {rom.Sides[sideNumber].Files.Count}");
                        }
                        for (int f = 0; f < rom.Sides[sideNumber].Files.Count; f++)
                        {
                            if (!sideImage.Files[f].HeaderBlock.Equals(rom.Sides[sideNumber].Files[f].HeaderBlock))
                            {
                                throw new IOException($"File #{f} header block verification failed");
                            }
                            if (!sideImage.Files[f].DataBlock.Equals(rom.Sides[sideNumber].Files[f].DataBlock))
                            {
                                throw new IOException($"File #{f} data block verification failed");
                            }
                        }
                        Console.WriteLine("Verification successful.");
                    }

                    if (sideNumber + 1 < rom.Sides.Count)
                    {
                        driveStatus = dumper.ReadCpu(0x4032);
                        if ((driveStatus & 1) == 0)
                        {
                            Console.Write($"Please remove disk card... ");
                            while ((driveStatus & 1) == 0)
                            {
                                Thread.Sleep(100);
                                driveStatus = dumper.ReadCpu(0x4032);
                            }
                            Console.WriteLine("OK");
                        }
                    }
                }
            }
            finally
            {
                dumper.Timeout = oldTimeout;
            }
        }