Пример #1
0
        private void ControllerView_ReadHeader(object sender, RoutedEventArgs e)
        {
            if (!_state.IsOpen)
            {
                return;
            }

            _header = _controller.ReadGameboyHeader();
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(_header)));
        }
Пример #2
0
        public async Task ReadROMAsync(CartridgeHeader header, StorageFolder saveLocation)
        {
            var contentBuffer  = new List <byte>();
            var currentAddress = 0x0000;
            var targetAddress  = 0x7FFF;

            _serial.DiscardInBuffer();
            _serial.DiscardOutBuffer();

            SetMode(Constants.COMMAND_RESET);
            SetMode(Constants.COMMAND_SET_START_ADDRESS, currentAddress);
            SetMode(Constants.COMMAND_READ_ROM_RAM);

            for (ushort bank = 1; bank < header.RomBanks; bank++)
            {
                if (header.RomBanks > 2)
                {
                    // MBC2 and larger
                    if ((byte)header.Mapper >= 5)
                    {
                        SetBank(0x2100, bank);
                        if (bank >= 256)
                        {
                            // Handle high bit(s)
                            SetBank(0x3000, 1);
                        }
                    }
                    else
                    {
                        // Set the mode
                        SetBank(0x6000, 0);
                        // Set 0b01100000
                        SetBank(0x4000, (ushort)(bank >> 5));
                        // Set 0b00011111
                        SetBank(0x2000, (ushort)(bank & 0x1F));
                    }
                }

                if (bank > 1)
                {
                    currentAddress = 0x4000;
                }

                SetMode(Constants.COMMAND_SET_START_ADDRESS, currentAddress);
                SetMode(Constants.COMMAND_READ_ROM_RAM);

                var currentBuffer = new byte[0xFFFF];
                while (currentAddress < targetAddress)
                {
                    try
                    {
                        var numberRead = _serial.Read(currentBuffer, currentAddress, 64);
                        currentAddress += numberRead;

                        if (currentAddress < targetAddress)
                        {
                            SetMode(Constants.COMMAND_CONTINUE);
                        }
                    }
                    catch (TimeoutException)
                    {
                        Debug.WriteLine("Bytes not ready!");
                        Thread.Sleep(500);

                        SetMode(Constants.COMMAND_SET_START_ADDRESS, (byte)currentAddress);
                        SetMode(Constants.COMMAND_READ_ROM_RAM);

                        continue;
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("Unable to complete read!");
                    }
                }

                if (bank > 1)
                {
                    var segment = new ArraySegment <byte>(currentBuffer, 0x4000, 0x8000 - 0x4000);
                    contentBuffer.AddRange(segment);
                }
                else
                {
                    contentBuffer.AddRange(currentBuffer);
                }
            }

            try
            {
                var safeTitle = header.Title.Replace('\0', ' ');
                var saveFile  = await saveLocation.CreateFileAsync($"{safeTitle}.gb", CreationCollisionOption.ReplaceExisting);

                using (var transaction = await saveFile.OpenTransactedWriteAsync())
                    using (var dataWriter = new DataWriter(transaction.Stream))
                    {
                        dataWriter.WriteBytes(contentBuffer.ToArray());
                        await dataWriter.StoreAsync();

                        await transaction.CommitAsync();
                    }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Unable to save file!");
            }

            SetMode(0);
        }