Exemple #1
0
        public ZXSpectrum(CoreComm comm, IEnumerable <byte[]> files, List <GameInfo> game, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;
            InputCallbacks  = new InputCallbackSystem();
            MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });

            CoreComm = comm;

            _gameInfo = game;

            _cpu = new Z80A();

            _tracer = new TraceBuffer {
                Header = _cpu.TraceHeader
            };

            //_file = file;
            _files = files?.ToList() ?? new List <byte[]>();

            if (settings == null)
            {
                settings = new ZXSpectrumSettings();
            }
            if (syncSettings == null)
            {
                syncSettings = new ZXSpectrumSyncSettings();
            }

            PutSyncSettings((ZXSpectrumSyncSettings)syncSettings ?? new ZXSpectrumSyncSettings());
            PutSettings((ZXSpectrumSettings)settings ?? new ZXSpectrumSettings());

            List <JoystickType> joysticks = new List <JoystickType>();

            joysticks.Add(((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).JoystickType1);
            joysticks.Add(((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).JoystickType2);
            joysticks.Add(((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).JoystickType3);

            deterministicEmulation = ((ZXSpectrumSyncSettings)syncSettings as ZXSpectrumSyncSettings).DeterministicEmulation;

            switch (SyncSettings.MachineType)
            {
            case MachineType.ZXSpectrum16:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum16, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum48:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum48, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2a:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2a, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus3:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            default:
                throw new InvalidOperationException("Machine not yet emulated");
            }

            _cpu.MemoryCallbacks = MemoryCallbacks;

            HardReset = _machine.HardReset;
            SoftReset = _machine.SoftReset;

            _cpu.FetchMemory   = _machine.ReadMemory;
            _cpu.ReadMemory    = _machine.ReadMemory;
            _cpu.WriteMemory   = _machine.WriteMemory;
            _cpu.ReadHardware  = _machine.ReadPort;
            _cpu.WriteHardware = _machine.WritePort;
            _cpu.FetchDB       = _machine.PushBus;

            ser.Register <ITraceable>(_tracer);
            ser.Register <IDisassemblable>(_cpu);
            ser.Register <IVideoProvider>(_machine.ULADevice);

            // initialize sound mixer and attach the various ISoundProvider devices
            SoundMixer = new SoundProviderMixer((int)(32767 / 10), (ISoundProvider)_machine.BuzzerDevice);
            SoundMixer.AddSource((ISoundProvider)_machine.TapeBuzzer);
            if (_machine.AYDevice != null)
            {
                SoundMixer.AddSource(_machine.AYDevice);
            }

            // set audio device settings
            if (_machine.AYDevice != null && _machine.AYDevice.GetType() == typeof(AYChip))
            {
                ((AYChip)_machine.AYDevice as AYChip).PanningConfiguration = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).AYPanConfig;
                _machine.AYDevice.Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).AYVolume;
            }

            if (_machine.BuzzerDevice != null)
            {
                ((Buzzer)_machine.BuzzerDevice as Buzzer).Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).EarVolume;
            }

            if (_machine.TapeBuzzer != null)
            {
                ((Buzzer)_machine.TapeBuzzer as Buzzer).Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).TapeVolume;
            }

            ser.Register <ISoundProvider>(SoundMixer);


            HardReset();
            SetupMemoryDomains();
        }
Exemple #2
0
        //[CoreConstructor("GB", "GBC")]
        public GBHawkLink4x(CoreComm comm, GameInfo game_A, byte[] rom_A, GameInfo game_B, byte[] rom_B, GameInfo game_C, byte[] rom_C, GameInfo game_D, byte[] rom_D, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            Link4xSettings     = (GBLink4xSettings)settings ?? new GBLink4xSettings();
            Link4xSyncSettings = (GBLink4xSyncSettings)syncSettings ?? new GBLink4xSyncSettings();
            _controllerDeck    = new GBHawkLink4xControllerDeck(GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName,
                                                                GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName);

            CoreComm = comm;

            var temp_set_A = new GBHawk.GBHawk.GBSettings();
            var temp_set_B = new GBHawk.GBHawk.GBSettings();
            var temp_set_C = new GBHawk.GBHawk.GBSettings();
            var temp_set_D = new GBHawk.GBHawk.GBSettings();

            var temp_sync_A = new GBHawk.GBHawk.GBSyncSettings();
            var temp_sync_B = new GBHawk.GBHawk.GBSyncSettings();
            var temp_sync_C = new GBHawk.GBHawk.GBSyncSettings();
            var temp_sync_D = new GBHawk.GBHawk.GBSyncSettings();

            temp_sync_A.ConsoleMode = Link4xSyncSettings.ConsoleMode_A;
            temp_sync_B.ConsoleMode = Link4xSyncSettings.ConsoleMode_B;
            temp_sync_C.ConsoleMode = Link4xSyncSettings.ConsoleMode_C;
            temp_sync_D.ConsoleMode = Link4xSyncSettings.ConsoleMode_D;

            temp_sync_A.DivInitialTime = Link4xSyncSettings.DivInitialTime_A;
            temp_sync_B.DivInitialTime = Link4xSyncSettings.DivInitialTime_B;
            temp_sync_C.DivInitialTime = Link4xSyncSettings.DivInitialTime_C;
            temp_sync_D.DivInitialTime = Link4xSyncSettings.DivInitialTime_D;
            temp_sync_A.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_A;
            temp_sync_B.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_B;
            temp_sync_C.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_C;
            temp_sync_D.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_D;
            temp_sync_A.RTCOffset      = Link4xSyncSettings.RTCOffset_A;
            temp_sync_B.RTCOffset      = Link4xSyncSettings.RTCOffset_B;
            temp_sync_C.RTCOffset      = Link4xSyncSettings.RTCOffset_C;
            temp_sync_D.RTCOffset      = Link4xSyncSettings.RTCOffset_D;

            A = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_A, rom_A, temp_set_A, temp_sync_A);

            B = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_B, rom_B, temp_set_B, temp_sync_B);

            C = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_C, rom_C, temp_set_C, temp_sync_C);

            D = new GBHawk.GBHawk(new CoreComm(comm.ShowMessage, comm.Notify)
            {
                CoreFileProvider = comm.CoreFileProvider
            },
                                  game_D, rom_D, temp_set_D, temp_sync_D);

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);

            _tracer = new TraceBuffer {
                Header = A.cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            ServiceProvider = ser;

            SetupMemoryDomains();

            HardReset();
        }
Exemple #3
0
        public VectrexHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new MC6809
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                OnExecFetch     = ExecFetch,
            };

            audio      = new Audio();
            ppu        = new PPU();
            serialport = new SerialPort();

            CoreComm = comm;

            _settings       = (VectrexSettings)settings ?? new VectrexSettings();
            _syncSettings   = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();
            _controllerDeck = new VectrexHawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);

            byte[] Bios = null;
            byte[] Mine = null;

            Bios  = comm.CoreFileProvider.GetFirmware("Vectrex", "Bios", true, "BIOS Not Found, Cannot Load");
            _bios = Bios;

            Mine      = comm.CoreFileProvider.GetFirmware("Vectrex", "Minestorm", true, "Minestorm Not Found, Cannot Load");
            minestorm = Mine;

            Console.WriteLine("SHA1:" + rom.HashSHA1(0, rom.Length));

            _rom = rom;

            // If the game is minstorm, then no cartridge is inserted, retun 0xFF
            if ((rom.HashSHA1(0, rom.Length) == "65D07426B520DDD3115D40F255511E0FD2E20AE7") ||
                (rom.HashSHA1(0, rom.Length) == "1FDCC6E54AE5177BC9CDC79CE616AE3401E5C229"))
            {
                _rom = new byte[0x8000];

                for (int i = 0; i < 0x8000; i++)
                {
                    _rom[i] = 0xFF;
                }
            }

            // mirror games that are too small
            if (_rom.Length < 0x8000)
            {
                _rom = new byte[0x8000];

                for (int i = 0; i < 0x8000 / rom.Length; i++)
                {
                    for (int j = 0; j < rom.Length; j++)
                    {
                        _rom[j + i * rom.Length] = rom[j];
                    }
                }
            }

            // RAM appears to power up to either random values or 0xFF, otherwise all the asteroids in minestorm are on the same side if RAM[0x7E]=0
            for (int i = 0; i < RAM.Length; i++)
            {
                RAM[i] = 0xFF;
            }

            Setup_Mapper();

            _frameHz = 50;

            audio.Core      = this;
            ppu.Core        = this;
            serialport.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(audio);
            ServiceProvider = ser;

            _settings     = (VectrexSettings)settings ?? new VectrexSettings();
            _syncSettings = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            SetupMemoryDomains();
            HardReset();

            cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);
        }
Exemple #4
0
 public AppleII(CoreComm comm, IEnumerable <GameInfo> gameInfoSet, IEnumerable <byte[]> romSet, Settings settings)
     : this(comm, gameInfoSet.First(), romSet.First(), settings)
 {
     _romSet = romSet.ToList();
 }
Exemple #5
0
        public ZXSpectrum(CoreComm comm, IEnumerable <byte[]> files, List <GameInfo> game, object settings, object syncSettings, bool?deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;
            CoreComm        = comm;

            _gameInfo = game;

            _cpu = new Z80A();

            _tracer = new TraceBuffer {
                Header = _cpu.TraceHeader
            };

            _files = files?.ToList() ?? new List <byte[]>();

            if (settings == null)
            {
                settings = new ZXSpectrumSettings();
            }

            if (syncSettings == null)
            {
                syncSettings = new ZXSpectrumSyncSettings();
            }

            PutSyncSettings((ZXSpectrumSyncSettings)syncSettings);
            PutSettings((ZXSpectrumSettings)settings);

            var joysticks = new List <JoystickType>
            {
                ((ZXSpectrumSyncSettings)syncSettings).JoystickType1,
                ((ZXSpectrumSyncSettings)syncSettings).JoystickType2,
                ((ZXSpectrumSyncSettings)syncSettings).JoystickType3
            };

            DeterministicEmulation = ((ZXSpectrumSyncSettings)syncSettings).DeterministicEmulation;

            if (deterministic != null && deterministic == true)
            {
                if (!DeterministicEmulation)
                {
                    CoreComm.Notify("Forcing Deterministic Emulation");
                }

                DeterministicEmulation = deterministic.Value;
            }

            MachineType = SyncSettings.MachineType;

            switch (MachineType)
            {
            case MachineType.ZXSpectrum16:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum16, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum48:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum48, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus2a:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus2a, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.ZXSpectrum128Plus3:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            case MachineType.Pentagon128:
                ControllerDefinition = ZXSpectrumControllerDefinition;
                Init(MachineType.Pentagon128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
                break;

            default:
                throw new InvalidOperationException("Machine not yet emulated");
            }

            _cpu.MemoryCallbacks = MemoryCallbacks;

            HardReset = _machine.HardReset;
            SoftReset = _machine.SoftReset;

            _cpu.FetchMemory   = _machine.ReadMemory;
            _cpu.ReadMemory    = _machine.ReadMemory;
            _cpu.WriteMemory   = _machine.WriteMemory;
            _cpu.ReadHardware  = _machine.ReadPort;
            _cpu.WriteHardware = _machine.WritePort;
            _cpu.FetchDB       = _machine.PushBus;
            _cpu.OnExecFetch   = _machine.CPUMon.OnExecFetch;

            ser.Register <ITraceable>(_tracer);
            ser.Register <IDisassemblable>(_cpu);
            ser.Register <IVideoProvider>(_machine.ULADevice);

            // initialize sound mixer and attach the various ISoundProvider devices
            SoundMixer = new SyncSoundMixer(targetSampleCount: 882);
            SoundMixer.PinSource(_machine.BuzzerDevice, "System Beeper", (int)(32767 / 10));
            SoundMixer.PinSource(_machine.TapeBuzzer, "Tape Audio", (int)(32767 / 10));
            if (_machine.AYDevice != null)
            {
                SoundMixer.PinSource(_machine.AYDevice, "AY-3-3912");
            }

            // set audio device settings
            if (_machine.AYDevice != null && _machine.AYDevice.GetType() == typeof(AY38912))
            {
                ((AY38912)_machine.AYDevice).PanningConfiguration = ((ZXSpectrumSettings)settings).AYPanConfig;
                _machine.AYDevice.Volume = ((ZXSpectrumSettings)settings).AYVolume;
            }

            if (_machine.BuzzerDevice != null)
            {
                _machine.BuzzerDevice.Volume = ((ZXSpectrumSettings)settings).EarVolume;
            }

            if (_machine.TapeBuzzer != null)
            {
                _machine.TapeBuzzer.Volume = ((ZXSpectrumSettings)settings).TapeVolume;
            }

            DCFilter dc = new DCFilter(SoundMixer, 512);

            ser.Register <ISoundProvider>(dc);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            HardReset();
            SetupMemoryDomains();
        }
Exemple #6
0
        private string snes_path_request(int slot, string hint)
        {
            // every rom requests msu1.rom... why? who knows.
            // also handle msu-1 pcm files here
            bool isMsu1Rom = hint == "msu1.rom";
            bool isMsu1Pcm = Path.GetExtension(hint).ToLower() == ".pcm";

            if (isMsu1Rom || isMsu1Pcm)
            {
                // well, check if we have an msu-1 xml
                if (_romxml?["cartridge"]?["msu1"] != null)
                {
                    var msu1 = _romxml["cartridge"]["msu1"];
                    if (isMsu1Rom && msu1["rom"]?.Attributes["name"] != null)
                    {
                        return(PathSubfile(msu1["rom"].Attributes["name"].Value));
                    }

                    if (isMsu1Pcm)
                    {
                        // return @"D:\roms\snes\SuperRoadBlaster\SuperRoadBlaster-1.pcm";
                        // return "";
                        int wantsTrackNumber = int.Parse(hint.Replace("track-", "").Replace(".pcm", ""));
                        wantsTrackNumber++;
                        string wantsTrackString = wantsTrackNumber.ToString();
                        foreach (var child in msu1.ChildNodes.Cast <XmlNode>())
                        {
                            if (child.Name == "track" && child.Attributes["number"].Value == wantsTrackString)
                            {
                                return(PathSubfile(child.Attributes["name"].Value));
                            }
                        }
                    }
                }

                // not found.. what to do? (every rom will get here when msu1.rom is requested)
                return("");
            }

            // not MSU-1.  ok.
            string firmwareId;

            switch (hint)
            {
            case "cx4.rom": firmwareId = "CX4"; break;

            case "dsp1.rom": firmwareId = "DSP1"; break;

            case "dsp1b.rom": firmwareId = "DSP1b"; break;

            case "dsp2.rom": firmwareId = "DSP2"; break;

            case "dsp3.rom": firmwareId = "DSP3"; break;

            case "dsp4.rom": firmwareId = "DSP4"; break;

            case "st010.rom": firmwareId = "ST010"; break;

            case "st011.rom": firmwareId = "ST011"; break;

            case "st018.rom": firmwareId = "ST018"; break;

            default:
                CoreComm.ShowMessage($"Unrecognized SNES firmware request \"{hint}\".");
                return("");
            }

            string ret;
            var    data = CoreComm.CoreFileProvider.GetFirmware("SNES", firmwareId, false, "Game may function incorrectly without the requested firmware.");

            if (data != null)
            {
                ret = hint;
                Api.AddReadonlyFile(data, hint);
            }
            else
            {
                ret = "";
            }

            Console.WriteLine("Served libsnes request for firmware \"{0}\"", hint);

            // return the path we built
            return(ret);
        }
Exemple #7
0
        private string snes_path_request(int slot, string hint, bool required)
        {
            switch (hint)
            {
            case "manifest.bml":
                Api.AddReadonlyFile($"{_romPath}.bml", hint);
                return(hint);

            case "msu1/data.rom":
                Api.AddReadonlyFile($"{_romPath}.msu", hint);
                return(hint);

            case "save.ram":
                // core asked for saveram, but the interface isn't designed to be able to handle this.
                // so, we'll just return nothing and the frontend will set the saveram itself later
                return(null);
            }

            string firmwareId;
            string firmwareSystem = "SNES";

            switch (hint)
            {
            case "cx4": firmwareId = "CX4"; break;

            case "dsp1": firmwareId = "DSP1"; break;

            case "dsp1b": firmwareId = "DSP1b"; break;

            case "dsp2": firmwareId = "DSP2"; break;

            case "dsp3": firmwareId = "DSP3"; break;

            case "dsp4": firmwareId = "DSP4"; break;

            case "st010": firmwareId = "ST010"; break;

            case "st011": firmwareId = "ST011"; break;

            case "st018": firmwareId = "ST018"; break;

            case "sgb": firmwareId = "SGB"; firmwareSystem = "GB"; break;

            case "sgb2": firmwareId = "SGB2"; firmwareSystem = "GB"; break;

            default:
                CoreComm.ShowMessage($"Unrecognized SNES firmware request \"{hint}\".");
                return("");
            }

            string       ret  = "";
            FirmwareID   fwid = new(firmwareSystem, firmwareId);
            const string MISSING_FIRMWARE_MSG = "Game may function incorrectly without the requested firmware.";

            byte[] data = required
                                ? CoreComm.CoreFileProvider.GetFirmwareOrThrow(fwid, MISSING_FIRMWARE_MSG)
                                : CoreComm.CoreFileProvider.GetFirmware(fwid, MISSING_FIRMWARE_MSG);
            if (data != null)
            {
                ret = hint;
                Api.AddReadonlyFile(data, hint);
            }

            Console.WriteLine("Served bsnescore request for firmware \"{0}\"", hint);

            // return the path we built
            return(ret);
        }
Exemple #8
0
        public A7800Hawk(CoreComm comm, GameInfo game, byte[] rom, string gameDbFn, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            maria = new Maria();
            tia   = new TIA();
            m6532 = new M6532();
            pokey = new Pokey();

            cpu = new MOS6502X <CpuLink>(new CpuLink(this));

            maria = new Maria
            {
                ReadMemory = ReadMemory
            };

            _blip.SetRates(1789773, 44100);

            _settings       = (A7800Settings)settings ?? new A7800Settings();
            _syncSettings   = (A7800SyncSettings)syncSettings ?? new A7800SyncSettings();
            _controllerDeck = new A7800HawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);

            byte[] highscoreBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS.");
            byte[] palBios       = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available.");
            byte[] ntscBios      = comm.CoreFileProvider.GetFirmware("A78", "Bios_NTSC", false, "The game will not run if the correct region BIOS is not available.");

            byte[] header    = new byte[128];
            bool   is_header = false;

            if (rom.Length % 1024 == 128)
            {
                Console.WriteLine("128 byte header detected");
                byte[] newrom = new byte[rom.Length - 128];
                is_header = true;
                Buffer.BlockCopy(rom, 0, header, 0, 128);
                Buffer.BlockCopy(rom, 128, newrom, 0, newrom.Length);
                rom = newrom;
            }

            _isPAL = false;

            // look up hash in gamedb to see what mapper to use
            // if none found default is zero
            // also check for PAL region
            string hash_md5 = null;

            s_mapper = null;
            hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);

            var gi = Database.CheckDatabase(hash_md5);

            if (gi != null)
            {
                var dict = gi.GetOptionsDict();
                if (dict.ContainsKey("PAL"))
                {
                    _isPAL = true;
                }
                if (dict.ContainsKey("board"))
                {
                    s_mapper = dict["board"];
                }
                else
                {
                    throw new Exception("No Board selected for this game");
                }

                // check if the game uses pokey or RAM
                if (dict.ContainsKey("RAM"))
                {
                    int.TryParse(dict["RAM"], out cart_RAM);
                    Console.WriteLine(cart_RAM);
                }

                if (dict.ContainsKey("Pokey"))
                {
                    bool.TryParse(dict["Pokey"], out is_pokey);
                }

                // some games will not function with the high score bios
                // if such a game is being played, tell the user and disable it
                if (dict.ContainsKey("No_HS"))
                {
                    bool.TryParse(dict["No_HS"], out var no_hs);

                    if (no_hs)
                    {
                        Console.WriteLine("This game is incompatible with the High Score BIOS, disabling it");
                        highscoreBios = null;
                    }
                }
            }
            else if (is_header)
            {
                Console.WriteLine("ROM not in DB, inferring mapper info from header");

                byte cart_1 = header[0x35];
                byte cart_2 = header[0x36];

                _isPAL = (header[0x39] > 0);

                if (cart_2.Bit(1))
                {
                    if (cart_2.Bit(3))
                    {
                        s_mapper = "2";
                    }
                    else
                    {
                        s_mapper = "1";
                    }

                    if (cart_2.Bit(2))
                    {
                        cart_RAM = 8;
                    }
                }
                else
                {
                    s_mapper = "0";
                }

                if (cart_2.Bit(0))
                {
                    is_pokey = true;
                }
            }
            else
            {
                throw new Exception("ROM not in gamedb and has no header");
            }

            // some games that use the Super Game mapper only have 4 banks, so let's set a flag to limit bank size
            if (rom.Length < 0x14000)
            {
                small_flag = true;

                // additionally, PAL Karateka  has bank 6 (actually 2) at 0x4000
                if (rom.HashMD5() == "5E0A1E832BBCEA6FACB832FDE23A440A")
                {
                    PAL_Kara = true;
                }
            }

            _rom = rom;

            Reset_Mapper(s_mapper);

            _hsbios = highscoreBios;
            _bios   = _isPAL ? palBios : ntscBios;

            if (_bios == null)
            {
                throw new MissingFirmwareException("The BIOS corresponding to the region of the game you loaded is required to run Atari 7800 games.");
            }

            // set up palette and frame rate
            if (_isPAL)
            {
                _frameHz       = 50;
                _screen_width  = 320;
                _screen_height = 313;
                _vblanklines   = 20;
                maria._palette = PALPalette;
            }
            else
            {
                _frameHz       = 60;
                _screen_width  = 320;
                _screen_height = 263;
                _vblanklines   = 20;
                maria._palette = NTSCPalette;
            }

            maria.Core = this;
            m6532.Core = this;
            tia.Core   = this;
            pokey.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);
            ServiceProvider = ser;

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            SetupMemoryDomains();
            ser.Register <IDisassemblable>(cpu);
            HardReset();
        }
Exemple #9
0
        public SMS(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            Settings        = (SMSSettings)settings ?? new SMSSettings();
            SyncSettings    = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings();
            CoreComm        = comm;
            MemoryCallbacks = new MemoryCallbackSystem();

            IsGameGear = game.System == "GG";
            IsSG1000   = game.System == "SG";
            RomData    = rom;
            Tracer     = new TraceBuffer();
            (ServiceProvider as BasicServiceProvider).Register <ITraceable>(Tracer);
            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }
            RomBanks = (byte)(RomData.Length / BankSize);

            Region = DetermineDisplayType(SyncSettings.DisplayType, game.Region);
            if (game["PAL"] && Region != DisplayType.PAL)
            {
                Region = DisplayType.PAL;
                CoreComm.Notify("Display was forced to PAL mode for game compatibility.");
            }
            if (IsGameGear)
            {
                Region = DisplayType.NTSC;                 // all game gears run at 60hz/NTSC mode
            }
            CoreComm.VsyncNum = Region == DisplayType.NTSC ? 60 : 50;
            CoreComm.VsyncDen = 1;

            RegionStr = SyncSettings.ConsoleRegion;
            if (RegionStr == "Auto")
            {
                RegionStr = DetermineRegion(game.Region);
            }

            if (game["Japan"] && RegionStr != "Japan")
            {
                RegionStr = "Japan";
                CoreComm.Notify("Region was forced to Japan for game compatibility.");
            }

            if ((game.NotInDatabase || game["FM"]) && SyncSettings.EnableFM && !IsGameGear)
            {
                HasYM2413 = true;
            }

            if (Controller == null)
            {
                Controller = NullController.GetNullController();
            }

            Cpu                 = new Z80A();
            Cpu.RegisterSP      = 0xDFF0;
            Cpu.ReadHardware    = ReadPort;
            Cpu.WriteHardware   = WritePort;
            Cpu.MemoryCallbacks = MemoryCallbacks;

            Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, Region);
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(Vdp);
            PSG        = new SN76489();
            YM2413     = new YM2413();
            SoundMixer = new SoundMixer(YM2413, PSG);
            if (HasYM2413 && game["WhenFMDisablePSG"])
            {
                SoundMixer.DisableSource(PSG);
            }
            ActiveSoundProvider = HasYM2413 ? (ISoundProvider)SoundMixer : PSG;

            SystemRam = new byte[0x2000];

            if (game["CMMapper"])
            {
                InitCodeMastersMapper();
            }
            else if (game["CMMapperWithRam"])
            {
                InitCodeMastersMapperRam();
            }
            else if (game["ExtRam"])
            {
                InitExt2kMapper(int.Parse(game.OptionValue("ExtRam")));
            }
            else if (game["KoreaMapper"])
            {
                InitKoreaMapper();
            }
            else if (game["MSXMapper"])
            {
                InitMSXMapper();
            }
            else if (game["NemesisMapper"])
            {
                InitNemesisMapper();
            }
            else if (game["TerebiOekaki"])
            {
                InitTerebiOekaki();
            }
            else
            {
                InitSegaMapper();
            }

            if (Settings.ForceStereoSeparation && !IsGameGear)
            {
                if (game["StereoByte"])
                {
                    ForceStereoByte = byte.Parse(game.OptionValue("StereoByte"));
                }
                PSG.StereoPanning = ForceStereoByte;
            }

            if (SyncSettings.AllowOverlock && game["OverclockSafe"])
            {
                Vdp.IPeriod = 512;
            }

            if (Settings.SpriteLimit)
            {
                Vdp.SpriteLimit = true;
            }

            if (game["3D"])
            {
                IsGame3D = true;
            }

            if (game["BIOS"])
            {
                Port3E = 0xF7;                 // Disable cartridge, enable BIOS rom
                InitBiosMapper();
            }
            else if (game.System == "SMS")
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("SMS", RegionStr, false);
                if (BiosRom != null && (game["RequireBios"] || SyncSettings.UseBIOS))
                {
                    Port3E = 0xF7;
                }

                if (BiosRom == null && game["RequireBios"])
                {
                    throw new MissingFirmwareException("BIOS image not available. This game requires BIOS to function.");
                }
                if (SyncSettings.UseBIOS && BiosRom == null)
                {
                    CoreComm.Notify("BIOS was selected, but rom image not available. BIOS not enabled.");
                }
            }

            if (game["SRAM"])
            {
                SaveRAM = new byte[int.Parse(game.OptionValue("SRAM"))];
            }
            else if (game.NotInDatabase)
            {
                SaveRAM = new byte[0x8000];
            }

            SetupMemoryDomains();
            (ServiceProvider as BasicServiceProvider).Register <IDisassemblable>(new Disassembler());
        }
Exemple #10
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();
            CoreComm = comm;

            comm.RomStatusAnnotation = null;
            comm.RomStatusDetails    = null;
            comm.NominalWidth        = 160;
            comm.NominalHeight       = 144;

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException("gambatte_create() returned null???");
            }

            Console.WriteLine(game.System);

            byte[] BiosRom;

            if (game.System == "GB")
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("GB", "World", false);
            }
            else
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("GBC", "World", false);
            }

            int bios_length = BiosRom == null ? 0 : BiosRom.Length;

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                // copy over non-loadflag syncsettings now; they won't take effect if changed later
                zerotime = (uint)_syncSettings.RTCInitialTime;

                real_rtc_time = !DeterministicEmulation && _syncSettings.RealTimeRTC;

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    // we need to change the BIOS to GB bios
                    if (game.System == "GBC")
                    {
                        BiosRom     = comm.CoreFileProvider.GetFirmware("GB", "World", false);
                        bios_length = BiosRom.Length;
                    }
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    BiosRom     = comm.CoreFileProvider.GetFirmware("GBC", "World", false);
                    bios_length = BiosRom.Length;
                    break;

                default:
                    if (game.System == "GB")
                    {
                        flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    }
                    break;
                }

                if (_syncSettings.EnableBIOS && BiosRom == null)
                {
                    throw new MissingFirmwareException("Boot Rom not found");
                }

                // to disable BIOS loading into gambatte, just set bios_length to 0
                if (!_syncSettings.EnableBIOS)
                {
                    bios_length = 0;
                }

                if (_syncSettings.GBACGB)
                {
                    flags |= LibGambatte.LoadFlags.GBA_CGB;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, BiosRom, (uint)bios_length, GetCurrentTime(), flags) != 0)
                {
                    throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

                Frame      = 0;
                LagCount   = 0;
                IsLagFrame = false;

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                CoreComm.RomStatusDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                TimeCallback = new LibGambatte.RTCCallback(GetCurrentTime);
                LibGambatte.gambatte_setrtccallback(GambatteState, TimeCallback);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemple #11
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();
            CoreComm = comm;

            comm.RomStatusAnnotation = null;
            comm.RomStatusDetails    = null;
            comm.NominalWidth        = 160;
            comm.NominalHeight       = 144;

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_create)}() returned null???");
            }

            Console.WriteLine(game.System);

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    break;

                default:
                    if (game.System == "GB")
                    {
                        flags |= LibGambatte.LoadFlags.FORCE_DMG;
                    }
                    break;
                }

                if (_syncSettings.GBACGB)
                {
                    flags |= LibGambatte.LoadFlags.GBA_CGB;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, flags) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_load)}() returned non-zero (is this not a gb or gbc rom?)");
                }

                byte[] Bios;
                if ((flags & LibGambatte.LoadFlags.FORCE_DMG) == LibGambatte.LoadFlags.FORCE_DMG)
                {
                    Bios  = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
                    IsCgb = false;
                }
                else
                {
                    Bios  = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
                    IsCgb = true;
                }
                if (LibGambatte.gambatte_loadbios(GambatteState, Bios, (uint)Bios.Length) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbios)}() returned non-zero (bios error)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

                Frame      = 0;
                LagCount   = 0;
                IsLagFrame = false;

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                CoreComm.RomStatusDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                if (!DeterministicEmulation && _syncSettings.RealTimeRTC)
                {
                    LibGambatte.gambatte_settimemode(GambatteState, false);
                }
                LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemple #12
0
        public AmstradCPC(CoreComm comm, IEnumerable <byte[]> files, List <GameInfo> game, object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;
            InputCallbacks  = new InputCallbackSystem();
            MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
            CoreComm        = comm;
            _gameInfo       = game;
            _cpu            = new Z80A();
            _tracer         = new TraceBuffer {
                Header = _cpu.TraceHeader
            };
            _files = files?.ToList() ?? new List <byte[]>();

            if (settings == null)
            {
                settings = new AmstradCPCSettings();
            }
            if (syncSettings == null)
            {
                syncSettings = new AmstradCPCSyncSettings();
            }

            PutSyncSettings((AmstradCPCSyncSettings)syncSettings ?? new AmstradCPCSyncSettings());
            PutSettings((AmstradCPCSettings)settings ?? new AmstradCPCSettings());

            deterministicEmulation = ((AmstradCPCSyncSettings)syncSettings as AmstradCPCSyncSettings).DeterministicEmulation;

            switch (SyncSettings.MachineType)
            {
            case MachineType.CPC464:
                ControllerDefinition = AmstradCPCControllerDefinition;
                Init(MachineType.CPC464, _files, ((AmstradCPCSyncSettings)syncSettings as AmstradCPCSyncSettings).AutoStartStopTape,
                     ((AmstradCPCSyncSettings)syncSettings as AmstradCPCSyncSettings).BorderType);
                break;

            case MachineType.CPC6128:
                ControllerDefinition = AmstradCPCControllerDefinition;
                Init(MachineType.CPC6128, _files, ((AmstradCPCSyncSettings)syncSettings as AmstradCPCSyncSettings).AutoStartStopTape, ((AmstradCPCSyncSettings)syncSettings as AmstradCPCSyncSettings).BorderType);
                break;

            default:
                throw new InvalidOperationException("Machine not yet emulated");
            }

            _cpu.MemoryCallbacks = MemoryCallbacks;

            HardReset = _machine.HardReset;
            SoftReset = _machine.SoftReset;

            _cpu.FetchMemory    = _machine.ReadMemory;
            _cpu.ReadMemory     = _machine.ReadMemory;
            _cpu.WriteMemory    = _machine.WriteMemory;
            _cpu.ReadHardware   = _machine.ReadPort;
            _cpu.WriteHardware  = _machine.WritePort;
            _cpu.FetchDB        = _machine.PushBus;
            _cpu.IRQACKCallback = _machine.GateArray.IORQA;
            //_cpu.OnExecFetch = _machine.CPUMon.OnExecFetch;

            ser.Register <ITraceable>(_tracer);
            ser.Register <IDisassemblable>(_cpu);
            ser.Register <IVideoProvider>(_machine.GateArray);

            // initialize sound mixer and attach the various ISoundProvider devices
            SoundMixer = new SoundProviderMixer((int)(32767 / 10), "Tape Audio", (ISoundProvider)_machine.TapeBuzzer);
            if (_machine.AYDevice != null)
            {
                SoundMixer.AddSource(_machine.AYDevice, "AY-3-3912");
            }

            // set audio device settings
            if (_machine.AYDevice != null && _machine.AYDevice.GetType() == typeof(AY38912))
            {
                ((AY38912)_machine.AYDevice as AY38912).PanningConfiguration = ((AmstradCPCSettings)settings as AmstradCPCSettings).AYPanConfig;
                _machine.AYDevice.Volume = ((AmstradCPCSettings)settings as AmstradCPCSettings).AYVolume;
            }

            if (_machine.TapeBuzzer != null)
            {
                ((Beeper)_machine.TapeBuzzer as Beeper).Volume = ((AmstradCPCSettings)settings as AmstradCPCSettings).TapeVolume;
            }

            ser.Register <ISoundProvider>(SoundMixer);

            HardReset();
            SetupMemoryDomains();
        }
Exemple #13
0
        public Lynx(byte[] file, GameInfo game, CoreComm comm)
        {
            ServiceProvider = new BasicServiceProvider(this);
            CoreComm        = comm;

            byte[] bios = CoreComm.CoreFileProvider.GetFirmware("Lynx", "Boot", true, "Boot rom is required");
            if (bios.Length != 512)
            {
                throw new MissingFirmwareException("Lynx Bootrom must be 512 bytes!");
            }

            int pagesize0 = 0;
            int pagesize1 = 0;

            byte[] realfile = null;

            {
                var    ms     = new MemoryStream(file, false);
                var    br     = new BinaryReader(ms);
                string header = Encoding.ASCII.GetString(br.ReadBytes(4));
                int    p0     = br.ReadUInt16();
                int    p1     = br.ReadUInt16();
                int    ver    = br.ReadUInt16();
                string cname  = Encoding.ASCII.GetString(br.ReadBytes(32)).Trim();
                string mname  = Encoding.ASCII.GetString(br.ReadBytes(16)).Trim();
                int    rot    = br.ReadByte();

                ms.Position = 6;
                string bs93 = Encoding.ASCII.GetString(br.ReadBytes(6));
                if (bs93 == "BS93")
                {
                    throw new InvalidOperationException("Unsupported BS93 Lynx ram image");
                }

                if (header == "LYNX" && (ver & 255) == 1)
                {
                    Console.WriteLine("Processing Handy-Lynx header");
                    pagesize0 = p0;
                    pagesize1 = p1;
                    Console.WriteLine("TODO: Rotate {0}", rot);
                    Console.WriteLine("Cart: {0} Manufacturer: {1}", cname, mname);
                    realfile = new byte[file.Length - 64];
                    Buffer.BlockCopy(file, 64, realfile, 0, realfile.Length);
                    Console.WriteLine("Header Listed banking: {0} {1}", p0, p1);
                }
                else
                {
                    Console.WriteLine("No Handy-Lynx header found!  Assuming raw rom image.");
                    realfile = file;
                }
            }

            if (game.OptionPresent("pagesize0"))
            {
                pagesize0 = int.Parse(game.OptionValue("pagesize0"));
                pagesize1 = int.Parse(game.OptionValue("pagesize1"));
                Console.WriteLine("Loading banking options {0} {1} from gamedb", pagesize0, pagesize1);
            }

            if (pagesize0 == 0 && pagesize1 == 0)
            {
                switch (realfile.Length)
                {
                case 0x10000: pagesize0 = 0x100; break;

                case 0x20000: pagesize0 = 0x200; break;                         //

                case 0x40000: pagesize0 = 0x400; break;                         // all known good dumps fall in one of these three categories

                case 0x80000: pagesize0 = 0x800; break;                         //

                case 0x30000: pagesize0 = 0x200; pagesize1 = 0x100; break;

                case 0x50000: pagesize0 = 0x400; pagesize1 = 0x100; break;

                case 0x60000: pagesize0 = 0x400; pagesize1 = 0x200; break;

                case 0x90000: pagesize0 = 0x800; pagesize1 = 0x100; break;

                case 0xa0000: pagesize0 = 0x800; pagesize1 = 0x200; break;

                case 0xc0000: pagesize0 = 0x800; pagesize1 = 0x400; break;

                case 0x100000: pagesize0 = 0x800; pagesize1 = 0x800; break;
                }
                Console.WriteLine("Auto-guessed banking options {0} {1}", pagesize0, pagesize1);
            }

            Core = LibLynx.Create(realfile, realfile.Length, bios, bios.Length, pagesize0, pagesize1, false);
            try
            {
                _savebuff  = new byte[LibLynx.BinStateSize(Core)];
                _savebuff2 = new byte[_savebuff.Length + 13];

                int rot = game.OptionPresent("rotate") ? int.Parse(game.OptionValue("rotate")) : 0;
                LibLynx.SetRotation(Core, rot);
                if ((rot & 1) != 0)
                {
                    BufferWidth  = Height;
                    BufferHeight = Width;
                }
                else
                {
                    BufferWidth  = Width;
                    BufferHeight = Height;
                }
                SetupMemoryDomains();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemple #14
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, Gameboy.GambatteSettings settings, Gameboy.GambatteSyncSettings syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(_disassembler);
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "LR35902: PC, opcode, registers (A, F, B, C, D, E, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_create)}() returned null???");
            }

            Console.WriteLine(game.System);

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    flags |= LibGambatte.LoadFlags.CGB_MODE;
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBA:
                    flags |= LibGambatte.LoadFlags.CGB_MODE | LibGambatte.LoadFlags.GBA_FLAG;
                    break;

                default:
                    if (game.System == "GBC")
                    {
                        flags |= LibGambatte.LoadFlags.CGB_MODE;
                    }
                    break;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                byte[] bios;
                string biosSystemId;
                string biosId;
                if ((flags & LibGambatte.LoadFlags.CGB_MODE) == LibGambatte.LoadFlags.CGB_MODE)
                {
                    biosSystemId = "GBC";
                    biosId       = _syncSettings.ConsoleMode == GambatteSyncSettings.ConsoleModeType.GBA ? "AGB" : "World";
                    IsCgb        = true;
                }
                else
                {
                    biosSystemId = "GB";
                    biosId       = "World";
                    IsCgb        = false;
                }

                if (_syncSettings.EnableBIOS)
                {
                    bios = comm.CoreFileProvider.GetFirmware(biosSystemId, biosId, true, "BIOS Not Found, Cannot Load.  Change SyncSettings to run without BIOS.");
                    if (LibGambatte.gambatte_loadbios(GambatteState, bios, (uint)bios.Length) != 0)
                    {
                        throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbios)}() returned non-zero (bios error)");
                    }
                }
                else
                {
                    flags |= LibGambatte.LoadFlags.NO_BIOS;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, flags) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_load)}() returned non-zero (is this not a gb or gbc rom?)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

                Frame      = 0;
                LagCount   = 0;
                IsLagFrame = false;

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                RomDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                if (!_syncSettings.EnableBIOS && IsCgb && IsCGBDMGMode())                 // without a bios, we need to set the palette for cgbdmg ourselves
                {
                    int[] cgbDmgColors = new int[] { 0xFFFFFF, 0x7BFF31, 0x0063C5, 0x000000, 0xFFFFFF, 0xFF8484, 0x943A3A, 0x000000, 0xFFFFFF, 0xFF8484, 0x943A3A, 0x000000 };
                    if (file[0x14B] == 0x01 || (file[0x14B] == 0x33 && file[0x144] == '0' && file[0x145] == '1'))                     // Nintendo licencees get special palettes
                    {
                        cgbDmgColors = ColorsFromTitleHash(file);
                    }
                    ChangeDMGColors(cgbDmgColors);
                }

                if (!DeterministicEmulation && _syncSettings.RealTimeRTC)
                {
                    LibGambatte.gambatte_settimemode(GambatteState, false);
                }

                if (DeterministicEmulation)
                {
                    int[] rtcRegs = new int[11];
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh] = 0;
                    if (_syncSettings.InternalRTCOverflow)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh] |= 0x80;
                    }
                    if (_syncSettings.InternalRTCHalt)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh] |= 0x40;
                    }
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh]  |= _syncSettings.InternalRTCDays >> 8;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.Dl]   = _syncSettings.InternalRTCDays & 0xFF;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.H]    = (_syncSettings.InternalRTCHours < 0) ? (_syncSettings.InternalRTCHours + 0x20) : _syncSettings.InternalRTCHours;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.M]    = (_syncSettings.InternalRTCMinutes < 0) ? (_syncSettings.InternalRTCMinutes + 0x40) : _syncSettings.InternalRTCMinutes;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.S]    = (_syncSettings.InternalRTCSeconds < 0) ? (_syncSettings.InternalRTCSeconds + 0x40) : _syncSettings.InternalRTCSeconds;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.C]    = _syncSettings.InternalRTCCycles;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh_L] = 0;
                    if (_syncSettings.LatchedRTCOverflow)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh_L] |= 0x80;
                    }
                    if (_syncSettings.LatchedRTCHalt)
                    {
                        rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh_L] |= 0x40;
                    }
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.Dh_L] |= _syncSettings.LatchedRTCDays >> 8;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.Dl_L]  = _syncSettings.LatchedRTCDays & 0xFF;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.H_L]   = _syncSettings.LatchedRTCHours;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.M_L]   = _syncSettings.LatchedRTCMinutes;
                    rtcRegs[(int)LibGambatte.RtcRegIndicies.S_L]   = _syncSettings.LatchedRTCSeconds;
                    LibGambatte.gambatte_setrtcregs(GambatteState, rtcRegs);
                }

                LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

                LibGambatte.gambatte_setcartbuspulluptime(GambatteState, _syncSettings.CartBusPullUpTime);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemple #15
0
        public bool LoadRom(string path, CoreComm nextComm, bool forceAccurateCore = false,
                            int recursiveCount = 0) // forceAccurateCore is currently just for Quicknes vs Neshawk but could be used for other situations
        {
            if (recursiveCount > 1)                 // hack to stop recursive calls from endlessly rerunning if we can't load it
            {
                DoLoadErrorCallback("Failed multiple attempts to load ROM.", "");
                return(false);
            }

            bool cancel = false;

            if (path == null)
            {
                return(false);
            }

            using (var file = new HawkFile())
            {
                //only try mounting a file if a filename was given
                if (!string.IsNullOrEmpty(path))
                {
                    // lets not use this unless we need to
                    // file.NonArchiveExtensions = romExtensions;
                    file.Open(path);

                    // if the provided file doesnt even exist, give up!
                    if (!file.Exists)
                    {
                        return(false);
                    }
                }

                CanonicalFullPath = file.CanonicalFullPath;

                IEmulator nextEmulator = null;
                RomGame   rom          = null;
                GameInfo  game         = null;

                try
                {
                    string ext = null;

                    if (AsLibretro)
                    {
                        string codePathPart = Path.GetFileNameWithoutExtension(nextComm.LaunchLibretroCore);

                        var retro = new LibRetroEmulator(nextComm, nextComm.LaunchLibretroCore);
                        nextEmulator = retro;

                        //kind of dirty.. we need to stash this, and then we can unstash it in a moment, in case the core doesnt fail
                        var oldGame = Global.Game;

                        if (retro.Description.SupportsNoGame && string.IsNullOrEmpty(path))
                        {
                            //must be done before LoadNoGame (which triggers retro_init and the paths to be consumed by the core)
                            //game name == name of core
                            var gameName = codePathPart;
                            Global.Game = game = new GameInfo {
                                Name = gameName, System = "Libretro"
                            };

                            //if we are allowed to run NoGame and we dont have a game, boot up the core that way
                            bool ret = retro.LoadNoGame();

                            Global.Game = oldGame;

                            if (!ret)
                            {
                                DoLoadErrorCallback("LibretroNoGame failed to load. This is weird", "Libretro");
                                retro.Dispose();
                                return(false);
                            }
                        }
                        else
                        {
                            bool ret;

                            //must be done before LoadNoGame (which triggers retro_init and the paths to be consumed by the core)
                            //game name == name of core + extensionless_game_filename
                            var gameName = Path.Combine(codePathPart, Path.GetFileNameWithoutExtension(file.Name));
                            Global.Game = game = new GameInfo {
                                Name = gameName, System = "Libretro"
                            };

                            //if the core requires an archive file, then try passing the filename of the archive
                            //(but do we ever need to actually load the contents of the archive file into ram?)
                            if (retro.Description.NeedsArchives)
                            {
                                if (file.IsArchiveMember)
                                {
                                    throw new InvalidOperationException("Should not have bound file member for libretro block_extract core");
                                }
                                ret = retro.LoadPath(file.FullPathWithoutMember);
                            }
                            else
                            {
                                //otherwise load the data or pass the filename, as requested. but..
                                if (retro.Description.NeedsRomAsPath && file.IsArchiveMember)
                                {
                                    throw new InvalidOperationException("Cannot pass archive member to libretro needs_fullpath core");
                                }

                                if (retro.Description.NeedsRomAsPath)
                                {
                                    ret = retro.LoadPath(file.FullPathWithoutMember);
                                }
                                else
                                {
                                    ret = HandleArchiveBinding(file);
                                    if (ret)
                                    {
                                        ret = retro.LoadData(file.ReadAllBytes());
                                    }
                                }
                            }

                            Global.Game = oldGame;

                            if (!ret)
                            {
                                DoLoadErrorCallback("Libretro failed to load the given file. This is probably due to a core/content mismatch. Moreover, the process is now likely to be hosed. We suggest you restart the program.", "Libretro");
                                retro.Dispose();
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        //if not libretro:

                        //do extension checknig
                        ext = file.Extension.ToLowerInvariant();

                        //do the archive binding we had to skip
                        if (!HandleArchiveBinding(file))
                        {
                            return(false);
                        }
                    }

                    if (string.IsNullOrEmpty(ext))
                    {
                    }
                    else if (ext == ".m3u")
                    {
                        //HACK ZONE - currently only psx supports m3u
                        M3U_File m3u;
                        using (var sr = new StreamReader(path))
                            m3u = M3U_File.Read(sr);
                        if (m3u.Entries.Count == 0)
                        {
                            throw new InvalidOperationException("Can't load an empty M3U");
                        }
                        //load discs for all the m3u
                        m3u.Rebase(Path.GetDirectoryName(path));
                        List <Disc>   discs     = new List <Disc>();
                        List <string> discNames = new List <string>();
                        StringWriter  sw        = new StringWriter();
                        foreach (var e in m3u.Entries)
                        {
                            Disc   disc     = null;
                            string discPath = e.Path;

                            //--- load the disc in a context which will let us abort if it's going to take too long
                            var discMountJob = new DiscMountJob {
                                IN_FromPath = discPath
                            };
                            discMountJob.IN_SlowLoadAbortThreshold = 8;
                            discMountJob.Run();
                            disc = discMountJob.OUT_Disc;

                            if (discMountJob.OUT_SlowLoadAborted)
                            {
                                DoLoadErrorCallback("This disc would take too long to load. Run it through discohawk first, or find a new rip because this one is probably junk", "", LoadErrorType.DiscError);
                                return(false);
                            }

                            if (discMountJob.OUT_ErrorLevel)
                            {
                                throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
                            }

                            if (disc == null)
                            {
                                throw new InvalidOperationException("Can't load one of the files specified in the M3U");
                            }

                            var discName = Path.GetFileNameWithoutExtension(discPath);
                            discNames.Add(discName);
                            discs.Add(disc);

                            var discType = new DiscIdentifier(disc).DetectDiscType();
                            sw.WriteLine("{0}", Path.GetFileName(discPath));
                            if (discType == DiscType.SonyPSX)
                            {
                                string discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");
                                game = Database.CheckDatabase(discHash);
                                if (game == null || game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
                                {
                                    sw.WriteLine("Disc could not be identified as known-good. Look for a better rip.");
                                }
                                else
                                {
                                    sw.WriteLine("Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{0:X8}", discHash);
                                    sw.WriteLine("Nonetheless it could be an unrecognized romhack or patched version.");
                                    sw.WriteLine("According to redump.org, the ideal hash for entire disc is: CRC32:{0:X8}", game.GetStringValue("dh"));
                                    sw.WriteLine("The file you loaded hasn't been hashed entirely (it would take too long)");
                                    sw.WriteLine("Compare it with the full hash calculated by the PSX menu's Hash Discs tool");
                                }
                            }
                            else
                            {
                                sw.WriteLine("Not a PSX disc");
                            }
                            sw.WriteLine("-------------------------");
                        }

                        nextEmulator = new Octoshock(nextComm, discs, discNames, null, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                        nextEmulator.CoreComm.RomStatusDetails = sw.ToString();
                        game = new GameInfo {
                            Name = Path.GetFileNameWithoutExtension(file.Name)
                        };
                        game.System = "PSX";
                    }
                    else if (ext == ".iso" || ext == ".cue" || ext == ".ccd")
                    {
                        if (file.IsArchive)
                        {
                            throw new InvalidOperationException("Can't load CD files from archives!");
                        }

                        string discHash = null;

                        //--- load the disc in a context which will let us abort if it's going to take too long
                        var discMountJob = new DiscMountJob {
                            IN_FromPath = path
                        };
                        discMountJob.IN_SlowLoadAbortThreshold = 8;
                        discMountJob.Run();

                        if (discMountJob.OUT_SlowLoadAborted)
                        {
                            DoLoadErrorCallback("This disc would take too long to load. Run it through discohawk first, or find a new rip because this one is probably junk", "", LoadErrorType.DiscError);
                            return(false);
                        }

                        if (discMountJob.OUT_ErrorLevel)
                        {
                            throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
                        }

                        var disc = discMountJob.OUT_Disc;
                        //-----------

                        //TODO - use more sophisticated IDer
                        var discType = new DiscIdentifier(disc).DetectDiscType();
                        if (discType == DiscType.SonyPSX)
                        {
                            discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");
                        }
                        else
                        {
                            discHash = new DiscHasher(disc).OldHash();
                        }

                        game = Database.CheckDatabase(discHash);
                        if (game == null)
                        {
                            // try to use our wizard methods
                            game = new GameInfo {
                                Name = Path.GetFileNameWithoutExtension(file.Name), Hash = discHash
                            };

                            switch (new DiscIdentifier(disc).DetectDiscType())
                            {
                            case DiscType.SegaSaturn:
                                game.System = "SAT";
                                break;

                            case DiscType.SonyPSP:
                                game.System = "PSP";
                                break;

                            default:
                            case DiscType.SonyPSX:
                                game.System = "PSX";
                                break;

                            case DiscType.MegaCD:
                                game.System = "GEN";
                                break;

                            case DiscType.AudioDisc:
                            case DiscType.TurboCD:
                            case DiscType.UnknownCDFS:
                            case DiscType.UnknownFormat:
                                game.System = "PCECD";
                                break;
                            }
                        }

                        switch (game.System)
                        {
                        case "GEN":
                            var genesis = new GPGX(
                                nextComm, null, disc, GetCoreSettings <GPGX>(), GetCoreSyncSettings <GPGX>());
                            nextEmulator = genesis;
                            break;

                        case "SAT":
                            nextEmulator = new Yabause(nextComm, disc, GetCoreSyncSettings <Yabause>());
                            break;

                        case "PSP":
                            nextEmulator = new PSP(nextComm, file.Name);
                            break;

                        case "PSX":
                            nextEmulator = new Octoshock(nextComm, new List <Disc>(new[] { disc }), new List <string>(new[] { Path.GetFileNameWithoutExtension(path) }), null, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                            if (game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
                            {
                                nextEmulator.CoreComm.RomStatusDetails = "Disc could not be identified as known-good. Look for a better rip.";
                            }
                            else
                            {
                                StringWriter sw = new StringWriter();
                                sw.WriteLine("Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{0:X8}", discHash);
                                sw.WriteLine("Nonetheless it could be an unrecognized romhack or patched version.");
                                sw.WriteLine("According to redump.org, the ideal hash for entire disc is: CRC32:{0:X8}", game.GetStringValue("dh"));
                                sw.WriteLine("The file you loaded hasn't been hashed entirely (it would take too long)");
                                sw.WriteLine("Compare it with the full hash calculated by the PSX menu's Hash Discs tool");
                                nextEmulator.CoreComm.RomStatusDetails = sw.ToString();
                            }
                            break;

                        case "PCE":
                        case "PCECD":
                            nextEmulator = new PCEngine(nextComm, game, disc, GetCoreSettings <PCEngine>(), GetCoreSyncSettings <PCEngine>());
                            break;
                        }
                    }
                    else if (file.Extension.ToLowerInvariant() == ".xml")
                    {
                        try
                        {
                            var xmlGame = XmlGame.Create(file);                             // if load fails, are we supposed to retry as a bsnes XML????????
                            game = xmlGame.GI;

                            switch (game.System)
                            {
                            case "GB":
                            case "DGB":
                                // adelikat: remove need for tags to be hardcoded to left and right, we should clean this up, also maybe the DGB core should just take the xml file and handle it itself
                                var leftBytes  = xmlGame.Assets.First().Value;
                                var rightBytes = xmlGame.Assets.Skip(1).First().Value;

                                var left  = Database.GetGameInfo(leftBytes, "left.gb");
                                var right = Database.GetGameInfo(rightBytes, "right.gb");
                                nextEmulator = new GambatteLink(
                                    nextComm,
                                    left,
                                    leftBytes,
                                    right,
                                    rightBytes,
                                    GetCoreSettings <GambatteLink>(),
                                    GetCoreSyncSettings <GambatteLink>(),
                                    Deterministic);

                                // other stuff todo
                                break;

                            case "AppleII":
                                var assets = xmlGame.Assets.Select(a => Database.GetGameInfo(a.Value, a.Key));
                                var roms   = xmlGame.Assets.Select(a => a.Value);
                                nextEmulator = new AppleII(
                                    nextComm,
                                    assets,
                                    roms,
                                    (AppleII.Settings)GetCoreSettings <AppleII>());
                                break;

                            case "PSX":
                                var entries   = xmlGame.AssetFullPaths;
                                var discs     = new List <Disc>();
                                var discNames = new List <string>();
                                var sw        = new StringWriter();
                                foreach (var e in entries)
                                {
                                    Disc   disc     = null;
                                    string discPath = e;

                                    //--- load the disc in a context which will let us abort if it's going to take too long
                                    var discMountJob = new DiscMountJob {
                                        IN_FromPath = discPath
                                    };
                                    discMountJob.IN_SlowLoadAbortThreshold = 8;
                                    discMountJob.Run();
                                    disc = discMountJob.OUT_Disc;

                                    if (discMountJob.OUT_SlowLoadAborted)
                                    {
                                        DoLoadErrorCallback("This disc would take too long to load. Run it through discohawk first, or find a new rip because this one is probably junk", "PSX", LoadErrorType.DiscError);
                                        return(false);
                                    }

                                    if (discMountJob.OUT_ErrorLevel)
                                    {
                                        throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
                                    }

                                    if (disc == null)
                                    {
                                        throw new InvalidOperationException("Can't load one of the files specified in the M3U");
                                    }

                                    var discName = Path.GetFileNameWithoutExtension(discPath);
                                    discNames.Add(discName);
                                    discs.Add(disc);

                                    var discType = new DiscIdentifier(disc).DetectDiscType();
                                    sw.WriteLine("{0}", Path.GetFileName(discPath));
                                    if (discType == DiscType.SonyPSX)
                                    {
                                        string discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");
                                        game = Database.CheckDatabase(discHash);
                                        if (game == null || game.IsRomStatusBad() || game.Status == RomStatus.NotInDatabase)
                                        {
                                            sw.WriteLine("Disc could not be identified as known-good. Look for a better rip.");
                                        }
                                        else
                                        {
                                            sw.WriteLine("Disc was identified (99.99% confidently) as known good with disc id hash CRC32:{0:X8}", discHash);
                                            sw.WriteLine("Nonetheless it could be an unrecognized romhack or patched version.");
                                            sw.WriteLine("According to redump.org, the ideal hash for entire disc is: CRC32:{0:X8}", game.GetStringValue("dh"));
                                            sw.WriteLine("The file you loaded hasn't been hashed entirely (it would take too long)");
                                            sw.WriteLine("Compare it with the full hash calculated by the PSX menu's Hash Discs tool");
                                        }
                                    }
                                    else
                                    {
                                        sw.WriteLine("Not a PSX disc");
                                    }
                                    sw.WriteLine("-------------------------");
                                }

                                // todo: copy pasta from PSX .cue section
                                nextEmulator = new Octoshock(nextComm, discs, discNames, null, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                                nextEmulator.CoreComm.RomStatusDetails = sw.ToString();
                                game = new GameInfo {
                                    Name = Path.GetFileNameWithoutExtension(file.Name)
                                };
                                game.System = "PSX";

                                break;

                            default:
                                return(false);
                            }
                        }
                        catch (Exception ex)
                        {
                            try
                            {
                                // need to get rid of this hack at some point
                                rom = new RomGame(file);
                                ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", string.Empty));                                 // Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
                                byte[] romData = null;
                                byte[] xmlData = rom.FileData;

                                game        = rom.GameInfo;
                                game.System = "SNES";

                                var snes = new LibsnesCore(game, romData, Deterministic, xmlData, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                nextEmulator = snes;
                            }
                            catch
                            {
                                DoLoadErrorCallback(ex.ToString(), "DGB", LoadErrorType.XML);
                                return(false);
                            }
                        }
                    }
                    else if (file.Extension.ToLowerInvariant() == ".psf" || file.Extension.ToLowerInvariant() == ".minipsf")
                    {
                        Func <Stream, int, byte[]> cbDeflater = (Stream instream, int size) =>
                        {
                            var          inflater = new ICSharpCode.SharpZipLib.Zip.Compression.Inflater(false);
                            var          iis      = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(instream, inflater);
                            MemoryStream ret      = new MemoryStream();
                            iis.CopyTo(ret);
                            return(ret.ToArray());
                        };
                        PSF psf = new PSF();
                        psf.Load(path, cbDeflater);
                        nextEmulator = new Octoshock(nextComm, psf, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                        nextEmulator.CoreComm.RomStatusDetails = "It's a PSF, what do you want. Oh, tags maybe?";

                        //total garbage, this
                        rom  = new RomGame(file);
                        game = rom.GameInfo;
                    }
                    else if (ext != null)                     // most extensions
                    {
                        rom = new RomGame(file);

                        //hacky for now
                        if (file.Extension.ToLowerInvariant() == ".exe")
                        {
                            rom.GameInfo.System = "PSX";
                        }
                        else if (file.Extension.ToLowerInvariant() == ".nsf")
                        {
                            rom.GameInfo.System = "NES";
                        }


                        if (string.IsNullOrEmpty(rom.GameInfo.System))
                        {
                            // Has the user picked a preference for this extension?
                            if (PreferredPlatformIsDefined(rom.Extension.ToLowerInvariant()))
                            {
                                rom.GameInfo.System = Global.Config.PreferredPlatformsForExtensions[rom.Extension.ToLowerInvariant()];
                            }
                            else if (ChoosePlatform != null)
                            {
                                var result = ChoosePlatform(rom);
                                if (!string.IsNullOrEmpty(result))
                                {
                                    rom.GameInfo.System = result;
                                }
                                else
                                {
                                    cancel = true;
                                }
                            }
                        }

                        game = rom.GameInfo;

                        var isXml = false;

                        // other xml has already been handled
                        if (file.Extension.ToLowerInvariant() == ".xml")
                        {
                            game.System = "SNES";
                            isXml       = true;
                        }


                        CoreInventory.Core core = null;

                        switch (game.System)
                        {
                        default:
                            core = CoreInventory.Instance[game.System];
                            break;

                        case null:
                            // The user picked nothing in the Core picker
                            break;

                        case "83P":
                            var ti83Bios     = ((CoreFileProvider)nextComm.CoreFileProvider).GetFirmware("TI83", "Rom", true);
                            var ti83BiosPath = ((CoreFileProvider)nextComm.CoreFileProvider).GetFirmwarePath("TI83", "Rom", true);
                            using (var ti83AsHawkFile = new HawkFile())
                            {
                                ti83AsHawkFile.Open(ti83BiosPath);
                                var ti83BiosAsRom = new RomGame(ti83AsHawkFile);
                                var ti83          = new TI83(nextComm, ti83BiosAsRom.GameInfo, ti83Bios, GetCoreSettings <TI83>());
                                ti83.LinkPort.SendFileToCalc(File.OpenRead(path), false);
                                nextEmulator = ti83;
                            }
                            break;

                        case "SNES":
                            if (Global.Config.SNES_InSnes9x && VersionInfo.DeveloperBuild)
                            {
                                core = CoreInventory.Instance["SNES", "Snes9x"];
                            }
                            else
                            {
                                // need to get rid of this hack at some point
                                ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", String.Empty));                                         // Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
                                var romData = isXml ? null : rom.FileData;
                                var xmlData = isXml ? rom.FileData : null;
                                var snes    = new LibsnesCore(game, romData, Deterministic, xmlData, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                nextEmulator = snes;
                            }

                            break;

                        case "NES":
                            if (!Global.Config.NES_InQuickNES || forceAccurateCore)
                            {
                                core = CoreInventory.Instance["NES", "NesHawk"];
                            }
                            else
                            {
                                core = CoreInventory.Instance["NES", "QuickNes"];
                            }

                            break;

                        case "GB":
                        case "GBC":
                            if (!Global.Config.GB_AsSGB)
                            {
                                core = CoreInventory.Instance["GB", "Gambatte"];
                            }
                            else
                            {
                                try
                                {
                                    game.System = "SNES";
                                    game.AddOption("SGB");
                                    var snes = new LibsnesCore(game, rom.FileData, Deterministic, null, nextComm, GetCoreSettings <LibsnesCore>(), GetCoreSyncSettings <LibsnesCore>());
                                    nextEmulator = snes;
                                }
                                catch
                                {
                                    // failed to load SGB bios or game does not support SGB mode.
                                    // To avoid catch-22, disable SGB mode
                                    Global.Config.GB_AsSGB = false;
                                    throw;
                                }
                            }

                            break;

                        case "A78":
                            var gamedbpath = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "EMU7800.csv");
                            nextEmulator = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
                            break;

                        case "C64":
                            var c64 = new C64(nextComm, game, rom.RomData, rom.Extension, GetCoreSettings <C64>(), GetCoreSyncSettings <C64>());
                            nextEmulator = c64;
                            break;

                        case "GBA":
                            //core = CoreInventory.Instance["GBA", "Meteor"];
                            if (Global.Config.GBA_UsemGBA)
                            {
                                core = CoreInventory.Instance["GBA", "mGBA"];
                            }
                            else
                            {
                                core = CoreInventory.Instance["GBA", "VBA-Next"];
                            }
                            break;

                        case "PSX":
                            nextEmulator = new Octoshock(nextComm, null, null, rom.FileData, GetCoreSettings <Octoshock>(), GetCoreSyncSettings <Octoshock>());
                            nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
                            break;
                        }

                        if (core != null)
                        {
                            // use coreinventory
                            nextEmulator = core.Create(nextComm, game, rom.RomData, rom.FileData, Deterministic, GetCoreSettings(core.Type), GetCoreSyncSettings(core.Type));
                        }
                    }

                    if (nextEmulator == null)
                    {
                        if (!cancel)
                        {
                            DoLoadErrorCallback("No core could load the rom.", null);
                        }
                        return(false);
                    }
                }
                catch (Exception ex)
                {
                    string system = null;
                    if (game != null)
                    {
                        system = game.System;
                    }

                    // all of the specific exceptions we're trying to catch here aren't expected to have inner exceptions,
                    // so drill down in case we got a TargetInvocationException or something like that
                    while (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }

                    // Specific hack here, as we get more cores of the same system, this isn't scalable
                    if (ex is UnsupportedGameException)
                    {
                        if (system == "NES")
                        {
                            DoMessageCallback("Unable to use quicknes, using NESHawk instead");
                        }

                        return(LoadRom(path, nextComm, true, recursiveCount + 1));
                    }
                    else if (ex is MissingFirmwareException)
                    {
                        DoLoadErrorCallback(ex.Message, system, path, Deterministic, LoadErrorType.MissingFirmware);
                    }
                    else if (ex is CGBNotSupportedException)
                    {
                        // Note: GB as SGB was set to false by this point, otherwise we would want to do it here
                        DoMessageCallback("Failed to load a GB rom in SGB mode.  Disabling SGB Mode.");
                        return(LoadRom(path, nextComm, false, recursiveCount + 1));
                    }
                    else
                    {
                        DoLoadErrorCallback("A core accepted the rom, but threw an exception while loading it:\n\n" + ex, system);
                    }

                    return(false);
                }

                Rom            = rom;
                LoadedEmulator = nextEmulator;
                Game           = game;
                return(true);
            }
        }
Exemple #16
0
        public O2Hawk(CoreComm comm, GameInfo game, byte[] rom, O2Settings settings, O2SyncSettings syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new I8048
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                ReadPort        = ReadPort,
                WritePort       = WritePort,
                OnExecFetch     = ExecFetch,
            };

            _settings     = settings ?? new O2Settings();
            _syncSettings = syncSettings ?? new O2SyncSettings();

            is_G7400 = _syncSettings.G7400_Enable;

            _controllerDeck = new O2HawkControllerDeck("O2 Controller", "O2 Controller", is_G7400);

            if (is_G7400)
            {
                _bios = comm.CoreFileProvider.GetFirmware("O2", "BIOS-G7400", true, "BIOS Not Found, Cannot Load")
                        ?? throw new MissingFirmwareException("Missing G7400 Bios");
            }
            else
            {
                _bios = comm.CoreFileProvider.GetFirmware("O2", "BIOS-O2", true, "BIOS Not Found, Cannot Load")
                        ?? throw new MissingFirmwareException("Missing Odyssey2 Bios");
            }

            Buffer.BlockCopy(rom, 0x100, header, 0, 0x50);

            Console.WriteLine("MD5: " + rom.HashMD5(0, rom.Length));
            Console.WriteLine("SHA1: " + rom.HashSHA1(0, rom.Length));
            _rom = rom;

            if (game["XROM"])
            {
                is_XROM = true;
            }
            Setup_Mapper();

            _frameHz = 60;

            ser.Register <IVideoProvider>(this);
            ServiceProvider = ser;

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register(_tracer);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            SetupMemoryDomains();
            cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);

            // set up differences between PAL and NTSC systems
            if ((game.Region == "US" || game.Region == "EU-US" || game.Region == null) && !is_G7400)
            {
                is_pal     = false;
                pic_height = 240;
                _frameHz   = 60;

                ppu = new NTSC_PPU();
            }
            else
            {
                is_pal     = true;
                pic_height = 240;
                _frameHz   = 50;
                ppu        = new PAL_PPU();
            }

            ppu.Core = this;
            ppu.set_region(is_pal, is_G7400);
            ser.Register <ISoundProvider>(ppu);

            _vidbuffer   = new int[372 * pic_height];
            frame_buffer = new int[320 * pic_height];

            HardReset();
        }
Exemple #17
0
        //[CoreConstructor("GB", "GBC")]
        public GBHawkLink4x(CoreComm comm, GameInfo game_A, byte[] rom_A, GameInfo game_B, byte[] rom_B, GameInfo game_C, byte[] rom_C, GameInfo game_D, byte[] rom_D, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            Link4xSettings     = (GBLink4xSettings)settings ?? new GBLink4xSettings();
            Link4xSyncSettings = (GBLink4xSyncSettings)syncSettings ?? new GBLink4xSyncSettings();
            _controllerDeck    = new GBHawkLink4xControllerDeck(GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName,
                                                                GBHawkLink4xControllerDeck.DefaultControllerName, GBHawkLink4xControllerDeck.DefaultControllerName);

            var tempSetA = new GBHawk.GBHawk.GBSettings();
            var tempSetB = new GBHawk.GBHawk.GBSettings();
            var tempSetC = new GBHawk.GBHawk.GBSettings();
            var tempSetD = new GBHawk.GBHawk.GBSettings();

            var tempSyncA = new GBHawk.GBHawk.GBSyncSettings();
            var tempSyncB = new GBHawk.GBHawk.GBSyncSettings();
            var tempSyncC = new GBHawk.GBHawk.GBSyncSettings();
            var tempSyncD = new GBHawk.GBHawk.GBSyncSettings();

            tempSyncA.ConsoleMode = Link4xSyncSettings.ConsoleMode_A;
            tempSyncB.ConsoleMode = Link4xSyncSettings.ConsoleMode_B;
            tempSyncC.ConsoleMode = Link4xSyncSettings.ConsoleMode_C;
            tempSyncD.ConsoleMode = Link4xSyncSettings.ConsoleMode_D;

            tempSyncA.GBACGB = Link4xSyncSettings.GBACGB;
            tempSyncB.GBACGB = Link4xSyncSettings.GBACGB;
            tempSyncC.GBACGB = Link4xSyncSettings.GBACGB;
            tempSyncD.GBACGB = Link4xSyncSettings.GBACGB;

            tempSyncA.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_A;
            tempSyncB.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_B;
            tempSyncC.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_C;
            tempSyncD.RTCInitialTime = Link4xSyncSettings.RTCInitialTime_D;
            tempSyncA.RTCOffset      = Link4xSyncSettings.RTCOffset_A;
            tempSyncB.RTCOffset      = Link4xSyncSettings.RTCOffset_B;
            tempSyncC.RTCOffset      = Link4xSyncSettings.RTCOffset_C;
            tempSyncD.RTCOffset      = Link4xSyncSettings.RTCOffset_D;

            A = new GBHawk.GBHawk(comm, game_A, rom_A, tempSetA, tempSyncA);
            B = new GBHawk.GBHawk(comm, game_B, rom_B, tempSetB, tempSyncB);
            C = new GBHawk.GBHawk(comm, game_C, rom_C, tempSetC, tempSyncC);
            D = new GBHawk.GBHawk(comm, game_D, rom_D, tempSetD, tempSyncD);

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(this);

            _tracer = new TraceBuffer {
                Header = A.cpu.TraceHeader
            };
            ser.Register(_tracer);

            ServiceProvider = ser;

            _aStates = A.ServiceProvider.GetService <IStatable>();
            _bStates = B.ServiceProvider.GetService <IStatable>();
            _cStates = C.ServiceProvider.GetService <IStatable>();
            _dStates = D.ServiceProvider.GetService <IStatable>();

            SetupMemoryDomains();

            HardReset();
        }
Exemple #18
0
        public SMS(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            Settings        = (SMSSettings)settings ?? new SMSSettings();
            SyncSettings    = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings();
            CoreComm        = comm;
            MemoryCallbacks = new MemoryCallbackSystem();

            IsGameGear = game.System == "GG";
            IsSG1000   = game.System == "SG";
            RomData    = rom;

            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }

            RomBanks = (byte)(RomData.Length / BankSize);

            Region = DetermineDisplayType(SyncSettings.DisplayType, game.Region);
            if (game["PAL"] && Region != DisplayType.PAL)
            {
                Region = DisplayType.PAL;
                CoreComm.Notify("Display was forced to PAL mode for game compatibility.");
            }

            if (IsGameGear)
            {
                Region = DisplayType.NTSC;                 // all game gears run at 60hz/NTSC mode
            }

            RegionStr = SyncSettings.ConsoleRegion;
            if (RegionStr == "Auto")
            {
                RegionStr = DetermineRegion(game.Region);
            }

            if (game["Japan"] && RegionStr != "Japan")
            {
                RegionStr = "Japan";
                CoreComm.Notify("Region was forced to Japan for game compatibility.");
            }

            if ((game.NotInDatabase || game["FM"]) && SyncSettings.EnableFM && !IsGameGear)
            {
                HasYM2413 = true;
            }

            Cpu = new Z80A()
            {
                ReadHardware    = ReadPort,
                WriteHardware   = WritePort,
                FetchMemory     = ReadMemory,
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                MemoryCallbacks = MemoryCallbacks
            };

            Vdp = new VDP(this, Cpu, IsGameGear ? VdpMode.GameGear : VdpMode.SMS, Region);
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(Vdp);
            PSG        = new SN76489();
            YM2413     = new YM2413();
            SoundMixer = new SoundMixer(YM2413, PSG);
            if (HasYM2413 && game["WhenFMDisablePSG"])
            {
                SoundMixer.DisableSource(PSG);
            }

            ActiveSoundProvider = HasYM2413 ? (IAsyncSoundProvider)SoundMixer : PSG;
            _fakeSyncSound      = new FakeSyncSound(ActiveSoundProvider, 735);
            (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(_fakeSyncSound);

            SystemRam = new byte[0x2000];

            if (game["CMMapper"])
            {
                InitCodeMastersMapper();
            }
            else if (game["CMMapperWithRam"])
            {
                InitCodeMastersMapperRam();
            }
            else if (game["ExtRam"])
            {
                InitExt2kMapper(int.Parse(game.OptionValue("ExtRam")));
            }
            else if (game["KoreaMapper"])
            {
                InitKoreaMapper();
            }
            else if (game["MSXMapper"])
            {
                InitMSXMapper();
            }
            else if (game["NemesisMapper"])
            {
                InitNemesisMapper();
            }
            else if (game["TerebiOekaki"])
            {
                InitTerebiOekaki();
            }
            else if (game["EEPROM"])
            {
                InitEEPROMMapper();
            }
            else
            {
                InitSegaMapper();
            }

            if (Settings.ForceStereoSeparation && !IsGameGear)
            {
                if (game["StereoByte"])
                {
                    ForceStereoByte = byte.Parse(game.OptionValue("StereoByte"));
                }

                PSG.StereoPanning = ForceStereoByte;
            }

            if (SyncSettings.AllowOverlock && game["OverclockSafe"])
            {
                Vdp.IPeriod = 512;
            }

            if (Settings.SpriteLimit)
            {
                Vdp.SpriteLimit = true;
            }

            if (game["3D"])
            {
                IsGame3D = true;
            }

            if (game["BIOS"])
            {
                Port3E = 0xF7;                 // Disable cartridge, enable BIOS rom
                InitBiosMapper();
            }
            else if (game.System == "SMS")
            {
                BiosRom = comm.CoreFileProvider.GetFirmware("SMS", RegionStr, false);

                if (BiosRom == null)
                {
                    throw new MissingFirmwareException("No BIOS found");
                }
                else if (!game["RequireBios"] && !SyncSettings.UseBIOS)
                {
                    // we are skipping the BIOS
                    // but only if it won't break the game
                }
                else
                {
                    Port3E = 0xF7;
                }
            }

            if (game["SRAM"])
            {
                SaveRAM = new byte[int.Parse(game.OptionValue("SRAM"))];
                Console.WriteLine(SaveRAM.Length);
            }
            else if (game.NotInDatabase)
            {
                SaveRAM = new byte[0x8000];
            }

            SetupMemoryDomains();

            //this manages the linkage between the cpu and mapper callbacks so it needs running before bootup is complete
            ((ICodeDataLogger)this).SetCDL(null);

            InputCallbacks = new InputCallbackSystem();

            Tracer = new TraceBuffer {
                Header = Cpu.TraceHeader
            };

            var serviceProvider = ServiceProvider as BasicServiceProvider;

            serviceProvider.Register <ITraceable>(Tracer);
            serviceProvider.Register <IDisassemblable>(Cpu);
            Vdp.ProcessOverscan();

            Cpu.ReadMemory  = ReadMemory;
            Cpu.WriteMemory = WriteMemory;
        }
Exemple #19
0
        public N64(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            InputCallbacks  = new InputCallbackSystem();
            MemoryCallbacks = new MemoryCallbackSystem
            {
                ExecuteCallbacksAvailable = false
            };

            int SaveType = 0;

            if (game.OptionValue("SaveType") == "EEPROM_16K")
            {
                SaveType = 1;
            }

            CoreComm = comm;

            _syncSettings = (N64SyncSettings)syncSettings ?? new N64SyncSettings();
            _settings     = (N64Settings)settings ?? new N64Settings();

            _disableExpansionSlot = _syncSettings.DisableExpansionSlot;

            // Override the user's expansion slot setting if it is mentioned in the gamedb (it is mentioned but the game MUST have this setting or else not work
            if (game.OptionValue("expansionpak") != null && game.OptionValue("expansionpak") == "1")
            {
                _disableExpansionSlot = false;
                IsOverridingUserExpansionSlotSetting = true;
            }

            byte country_code = file[0x3E];

            switch (country_code)
            {
            // PAL codes
            case 0x44:
            case 0x46:
            case 0x49:
            case 0x50:
            case 0x53:
            case 0x55:
            case 0x58:
            case 0x59:
                _display_type = DisplayType.PAL;
                break;

            // NTSC codes
            case 0x37:
            case 0x41:
            case 0x45:
            case 0x4a:
            default:                     // Fallback for unknown codes
                _display_type = DisplayType.NTSC;
                break;
            }
            switch (DisplayType)
            {
            case DisplayType.NTSC:
                comm.VsyncNum = 60000;
                comm.VsyncDen = 1001;
                break;

            default:
                comm.VsyncNum = 50;
                comm.VsyncDen = 1;
                break;
            }

            StartThreadLoop();

            var videosettings = _syncSettings.GetVPS(game, _settings.VideoSizeX, _settings.VideoSizeY);
            var coreType      = _syncSettings.Core;

            //zero 19-apr-2014 - added this to solve problem with SDL initialization corrupting the main thread (I think) and breaking subsequent emulators (for example, NES)
            //not sure why this works... if we put the plugin initializations in here, we get deadlocks in some SDL initialization. doesnt make sense to me...
            RunThreadAction(() =>
            {
                api = new mupen64plusApi(this, file, videosettings, SaveType, (int)coreType, _disableExpansionSlot);
            });

            // Order is important because the register with the mupen core
            _videoProvider = new N64VideoProvider(api, videosettings);
            _audioProvider = new N64Audio(api);
            _inputProvider = new N64Input(this.AsInputPollable(), api, comm, this._syncSettings.Controllers);
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(_videoProvider);

            string rsp = _syncSettings.Rsp == N64SyncSettings.RspType.Rsp_Hle ?
                         "mupen64plus-rsp-hle.dll" :
                         "mupen64plus-rsp-z64-hlevideo.dll";

            api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp);

            InitMemoryDomains();
            RefreshMemoryCallbacks();

            api.AsyncExecuteEmulator();

            // Hack: Saving a state on frame 0 has been shown to not be sync stable. Advance past that frame to avoid the problem.
            // Advancing 2 frames was chosen to deal with a problem with the dynamic recompiler. The dynarec seems to take 2 frames to set
            // things up correctly. If a state is loaded on frames 0 or 1 mupen tries to access null pointers and the emulator crashes, so instead
            // advance past both to again avoid the problem.
            api.frame_advance();
            api.frame_advance();

            SetControllerButtons();
        }
Exemple #20
0
        public MSX(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            Settings        = (MSXSettings)settings ?? new MSXSettings();
            SyncSettings    = (MSXSyncSettings)syncSettings ?? new MSXSyncSettings();

            RomData = rom;
            int size = RomData.Length;

            if (RomData.Length % BankSize != 0)
            {
                Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
            }

            // we want all ROMS to be multiples of 64K for easy memory mapping later
            if (RomData.Length != 0x10000)
            {
                Array.Resize(ref RomData, 0x10000);
            }

            // if the original was not 64 or 48 k, move it (may need to do this case by case)

            if (size == 0x8000)
            {
                for (int i = 0x7FFF; i >= 0; i--)
                {
                    RomData[i + 0x4000] = RomData[i];
                }
                for (int i = 0; i < 0x4000; i++)
                {
                    RomData[i] = 0;
                }
            }

            if (size == 0x4000)
            {
                for (int i = 0; i < 0x4000; i++)
                {
                    RomData[i + 0x4000] = RomData[i];
                    RomData[i + 0x8000] = RomData[i];
                    RomData[i + 0xC000] = RomData[i];
                }
            }

            Bios = comm.CoreFileProvider.GetFirmware("MSX", "bios_jp", false, "BIOS Not Found, Cannot Load");

            if (Bios == null)
            {
                Bios = comm.CoreFileProvider.GetFirmware("MSX", "bios_test_ext", true, "BIOS Not Found, Cannot Load");
            }
            //Basic = comm.CoreFileProvider.GetFirmware("MSX", "basic_test", true, "BIOS Not Found, Cannot Load");


            Basic = new byte[0x4000];

            MSX_Pntr = LibMSX.MSX_create();

            LibMSX.MSX_load_bios(MSX_Pntr, Bios, Basic);
            LibMSX.MSX_load(MSX_Pntr, RomData, (uint)RomData.Length, 0, RomData, (uint)RomData.Length, 0);

            blip.SetRates(3579545, 44100);

            (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(this);

            SetupMemoryDomains();

            Header_Length     = LibMSX.MSX_getheaderlength(MSX_Pntr);
            Disasm_Length     = LibMSX.MSX_getdisasmlength(MSX_Pntr);
            Reg_String_Length = LibMSX.MSX_getregstringlength(MSX_Pntr);

            var newHeader = new StringBuilder(Header_Length);

            LibMSX.MSX_getheader(MSX_Pntr, newHeader, Header_Length);

            Console.WriteLine(Header_Length + " " + Disasm_Length + " " + Reg_String_Length);

            Tracer = new TraceBuffer {
                Header = newHeader.ToString()
            };

            var serviceProvider = ServiceProvider as BasicServiceProvider;

            serviceProvider.Register <ITraceable>(Tracer);
            serviceProvider.Register <IStatable>(new StateSerializer(SyncState));

            current_controller = SyncSettings.Contr_Setting == MSXSyncSettings.ContrType.Keyboard ? MSXControllerKB : MSXControllerJS;
        }
Exemple #21
0
        public VectrexHawk(CoreComm comm, byte[] rom, VectrexHawk.VectrexSyncSettings syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new MC6809
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                OnExecFetch     = ExecFetch,
            };

            audio      = new Audio();
            ppu        = new PPU();
            serialport = new SerialPort();

            _settings       = new object();       // TODO: wtf is this
            _syncSettings   = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();
            _controllerDeck = new VectrexHawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);

            /*var Bios =*/ _bios     = comm.CoreFileProvider.GetFirmwareOrThrow(new("VEC", "Bios"), "BIOS Not Found, Cannot Load");
            /*var Mine =*/ minestorm = comm.CoreFileProvider.GetFirmwareOrThrow(new("VEC", "Minestorm"), "Minestorm Not Found, Cannot Load");

            var romHashSHA1 = SHA1Checksum.ComputePrefixedHex(rom);

            Console.WriteLine(romHashSHA1);

            _rom = rom;

            // If the game is minestorm, then no cartridge is inserted, retun 0xFF
            if (romHashSHA1 == RomChecksums.Minestorm)
            {
                _rom = new byte[0x8000];

                for (int i = 0; i < 0x8000; i++)
                {
                    _rom[i] = 0xFF;
                }
            }

            // mirror games that are too small
            if (_rom.Length < 0x8000)
            {
                _rom = new byte[0x8000];

                for (int i = 0; i < 0x8000 / rom.Length; i++)
                {
                    for (int j = 0; j < rom.Length; j++)
                    {
                        _rom[j + i * rom.Length] = rom[j];
                    }
                }
            }

            // RAM appears to power up to either random values or 0xFF, otherwise all the asteroids in minestorm are on the same side if RAM[0x7E]=0
            for (int i = 0; i < RAM.Length; i++)
            {
                RAM[i] = 0xFF;
            }

            Setup_Mapper();

            _frameHz = 50;

            audio.Core      = this;
            ppu.Core        = this;
            serialport.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(audio);
            ServiceProvider = ser;

            _settings     = new object();         // TODO: wtf is this
            _syncSettings = (VectrexSyncSettings)syncSettings ?? new VectrexSyncSettings();

            _tracer = new TraceBuffer(cpu.TraceHeader);
            ser.Register <ITraceable>(_tracer);
            ser.Register <IStatable>(new StateSerializer(SyncState));
            SetupMemoryDomains();
            HardReset();

            cpu.SetCallbacks(ReadMemory, PeekMemory, PeekMemory, WriteMemory);
        }
Exemple #22
0
        public LibsnesCore(GameInfo game, byte[] romData, byte[] xmlData, string baseRomPath, CoreComm comm, object settings, object syncSettings)
        {
            _baseRomPath = baseRomPath;
            var ser = new BasicServiceProvider(this);

            ServiceProvider = ser;

            _tracer = new TraceBuffer
            {
                Header = "65816: PC, mnemonic, operands, registers (A, X, Y, S, D, DB, flags (NVMXDIZC), V, H)"
            };

            ser.Register <IDisassemblable>(new W65816_DisassemblerService());

            _game    = game;
            CoreComm = comm;
            byte[] sgbRomData = null;

            if (game["SGB"])
            {
                if ((romData[0x143] & 0xc0) == 0xc0)
                {
                    throw new CGBNotSupportedException();
                }

                sgbRomData        = CoreComm.CoreFileProvider.GetFirmware("SNES", "Rom_SGB", true, "SGB Rom is required for SGB emulation.");
                game.FirmwareHash = sgbRomData.HashSHA1();
            }

            _settings     = (SnesSettings)settings ?? new SnesSettings();
            _syncSettings = (SnesSyncSettings)syncSettings ?? new SnesSyncSettings();

            // TODO: pass profile here
            Api = new LibsnesApi(CoreComm.CoreFileProvider.DllPath())
            {
                ReadHook      = ReadHook,
                ExecHook      = ExecHook,
                WriteHook     = WriteHook,
                ReadHook_SMP  = ReadHook_SMP,
                ExecHook_SMP  = ExecHook_SMP,
                WriteHook_SMP = WriteHook_SMP,
            };

            ScanlineHookManager = new MyScanlineHookManager(this);

            _controllerDeck = new LibsnesControllerDeck(_syncSettings);
            _controllerDeck.NativeInit(Api);

            Api.CMD_init();

            Api.QUERY_set_path_request(snes_path_request);

            _scanlineStartCb = snes_scanlineStart;
            _tracecb         = snes_trace;

            _soundcb = snes_audio_sample;

            // start up audio resampler
            InitAudio();
            ser.Register <ISoundProvider>(_resampler);

            // strip header
            if ((romData?.Length & 0x7FFF) == 512)
            {
                var newData = new byte[romData.Length - 512];
                Array.Copy(romData, 512, newData, 0, newData.Length);
                romData = newData;
            }

            if (game["SGB"])
            {
                IsSGB    = true;
                SystemId = "SNES";
                ser.Register <IBoardInfo>(new SGBBoardInfo());

                _currLoadParams = new LoadParams
                {
                    type     = LoadParamType.SuperGameBoy,
                    rom_xml  = null,
                    rom_data = sgbRomData,
                    rom_size = (uint)sgbRomData.Length,
                    dmg_data = romData,
                };

                if (!LoadCurrent())
                {
                    throw new Exception("snes_load_cartridge_normal() failed");
                }
            }
            else
            {
                // we may need to get some information out of the cart, even during the following bootup/load process
                if (xmlData != null)
                {
                    _romxml = new XmlDocument();
                    _romxml.Load(new MemoryStream(xmlData));

                    // bsnes wont inspect the xml to load the necessary sfc file.
                    // so, we have to do that here and pass it in as the romData :/
                    if (_romxml["cartridge"]?["rom"] != null)
                    {
                        romData = File.ReadAllBytes(PathSubfile(_romxml["cartridge"]["rom"].Attributes["name"].Value));
                    }
                    else
                    {
                        throw new Exception("Could not find rom file specification in xml file. Please check the integrity of your xml file");
                    }
                }

                SystemId        = "SNES";
                _currLoadParams = new LoadParams
                {
                    type     = LoadParamType.Normal,
                    xml_data = xmlData,
                    rom_data = romData
                };

                if (!LoadCurrent())
                {
                    throw new Exception("snes_load_cartridge_normal() failed");
                }
            }

            if (Api.Region == LibsnesApi.SNES_REGION.NTSC)
            {
                // similar to what aviout reports from snes9x and seems logical from bsnes first principles. bsnes uses that numerator (ntsc master clockrate) for sure.
                VsyncNumerator   = 21477272;
                VsyncDenominator = 4 * 341 * 262;
            }
            else
            {
                // http://forums.nesdev.com/viewtopic.php?t=5367&start=19
                VsyncNumerator   = 21281370;
                VsyncDenominator = 4 * 341 * 312;
            }

            Api.CMD_power();

            SetupMemoryDomains(romData, sgbRomData);

            if (CurrentProfile == "Compatibility")
            {
                ser.Register <ITraceable>(_tracer);
            }

            Api.QUERY_set_path_request(null);
            Api.QUERY_set_video_refresh(snes_video_refresh);
            Api.QUERY_set_input_poll(snes_input_poll);
            Api.QUERY_set_input_state(snes_input_state);
            Api.QUERY_set_input_notify(snes_input_notify);
            Api.QUERY_set_audio_sample(_soundcb);
            Api.Seal();
            RefreshPalette();
        }
Exemple #23
0
 public Tst(CoreComm comm, byte[] rom)
     : base(comm, new Configuration())
 {
     throw new InvalidOperationException("To load a PC-FX game, please load the CUE file and not the BIN file.");
 }
Exemple #24
0
        public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings)
        {
            var ser = new BasicServiceProvider(this);

            cpu = new LR35902
            {
                ReadMemory      = ReadMemory,
                WriteMemory     = WriteMemory,
                PeekMemory      = PeekMemory,
                DummyReadMemory = ReadMemory,
                OnExecFetch     = ExecFetch,
                SpeedFunc       = SpeedFunc,
            };

            timer      = new Timer();
            audio      = new Audio();
            serialport = new SerialPort();

            CoreComm = comm;

            _settings       = (GBSettings)settings ?? new GBSettings();
            _syncSettings   = (GBSyncSettings)syncSettings ?? new GBSyncSettings();
            _controllerDeck = new GBHawkControllerDeck(_syncSettings.Port1);

            byte[] Bios = null;

            // Load up a BIOS and initialize the correct PPU
            if (_syncSettings.ConsoleMode == GBSyncSettings.ConsoleModeType.Auto)
            {
                if (game.System == "GB")
                {
                    Bios = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
                    ppu  = new GB_PPU();
                }
                else
                {
                    Bios   = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
                    ppu    = new GBC_PPU();
                    is_GBC = true;
                }
            }
            else if (_syncSettings.ConsoleMode == GBSyncSettings.ConsoleModeType.GB)
            {
                Bios = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
                ppu  = new GB_PPU();
            }
            else
            {
                Bios   = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
                ppu    = new GBC_PPU();
                is_GBC = true;
            }

            if (Bios == null)
            {
                throw new MissingFirmwareException("Missing Gamboy Bios");
            }

            _bios = Bios;

            // Here we modify the BIOS if GBA mode is set (credit to ExtraTricky)
            if (is_GBC && _syncSettings.GBACGB)
            {
                for (int i = 0; i < 13; i++)
                {
                    _bios[i + 0xF3] = (byte)((GBA_override[i] + _bios[i + 0xF3]) & 0xFF);
                }
            }

            // CPU needs to know about GBC status too
            cpu.is_GBC = is_GBC;

            Buffer.BlockCopy(rom, 0x100, header, 0, 0x50);

            string hash_md5 = null;

            hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);
            Console.WriteLine(hash_md5);

            _rom = rom;
            Setup_Mapper();

            _frameHz = 60;

            timer.Core      = this;
            audio.Core      = this;
            ppu.Core        = this;
            serialport.Core = this;

            ser.Register <IVideoProvider>(this);
            ser.Register <ISoundProvider>(audio);
            ServiceProvider = ser;

            _settings     = (GBSettings)settings ?? new GBSettings();
            _syncSettings = (GBSyncSettings)syncSettings ?? new GBSyncSettings();

            _tracer = new TraceBuffer {
                Header = cpu.TraceHeader
            };
            ser.Register <ITraceable>(_tracer);

            SetupMemoryDomains();
            HardReset();

            iptr0 = Marshal.AllocHGlobal(VRAM.Length + 1);
            iptr1 = Marshal.AllocHGlobal(OAM.Length + 1);
            iptr2 = Marshal.AllocHGlobal(color_palette.Length * 8 * 8 + 1);
            iptr3 = Marshal.AllocHGlobal(color_palette.Length * 8 * 8 + 1);

            _scanlineCallback = null;
        }
Exemple #25
0
        public Genesis(CoreComm comm, GameInfo game, byte[] rom)
        {
            ServiceProvider = new BasicServiceProvider(this);
            CoreComm        = comm;
            MainCPU         = new MC68000();
            SoundCPU        = new Z80A();
            YM2612          = new YM2612()
            {
                MaxVolume = 23405
            };
            PSG = new SN76489()
            {
                MaxVolume = 4681
            };
            VDP = new GenVDP();
            VDP.DmaReadFrom68000 = ReadWord;
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(VDP);
            SoundMixer = new SoundMixer(YM2612, PSG);

            MainCPU.ReadByte    = ReadByte;
            MainCPU.ReadWord    = ReadWord;
            MainCPU.ReadLong    = ReadLong;
            MainCPU.WriteByte   = WriteByte;
            MainCPU.WriteWord   = WriteWord;
            MainCPU.WriteLong   = WriteLong;
            MainCPU.IrqCallback = InterruptCallback;

            // ---------------------- musashi -----------------------
#if MUSASHI
            _vdp    = vdpcallback;
            read8   = Read8;
            read16  = Read16;
            read32  = Read32;
            write8  = Write8;
            write16 = Write16;
            write32 = Write32;

            Musashi.RegisterVdpCallback(Marshal.GetFunctionPointerForDelegate(_vdp));
            Musashi.RegisterRead8(Marshal.GetFunctionPointerForDelegate(read8));
            Musashi.RegisterRead16(Marshal.GetFunctionPointerForDelegate(read16));
            Musashi.RegisterRead32(Marshal.GetFunctionPointerForDelegate(read32));
            Musashi.RegisterWrite8(Marshal.GetFunctionPointerForDelegate(write8));
            Musashi.RegisterWrite16(Marshal.GetFunctionPointerForDelegate(write16));
            Musashi.RegisterWrite32(Marshal.GetFunctionPointerForDelegate(write32));
#endif
            // ---------------------- musashi -----------------------

            SoundCPU.ReadMemory    = ReadMemoryZ80;
            SoundCPU.WriteMemory   = WriteMemoryZ80;
            SoundCPU.WriteHardware = (a, v) => { Console.WriteLine("Z80: Attempt I/O Write {0:X2}:{1:X2}", a, v); };
            SoundCPU.ReadHardware  = x => 0xFF;
            SoundCPU.IRQCallback   = () => SoundCPU.Interrupt = false;
            Z80Reset = true;
            RomData  = new byte[0x400000];
            for (int i = 0; i < rom.Length; i++)
            {
                RomData[i] = rom[i];
            }

            SetupMemoryDomains();
#if MUSASHI
            Musashi.Init();
            Musashi.Reset();
            VDP.GetPC = () => Musashi.PC;
#else
            MainCPU.Reset();
            VDP.GetPC = () => MainCPU.PC;
#endif
            InitializeCartHardware(game);
        }
Exemple #26
0
 public NeoGeoPort(CoreComm comm, byte[] rom, GameInfo game,
                   NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic, string extension)
     : base(comm, "NGP", "NeoGeo Portable Controller", settings, syncSettings)
 {
     _neopop = DoInit <LibNeoGeoPort>(game, rom, null, "ngp.wbx", extension, deterministic);
 }
Exemple #27
0
 public Sameboy(CoreComm comm, byte[] rom, Settings settings, SyncSettings syncSettings, bool deterministic)
     : this(rom, comm, false, settings, syncSettings, deterministic)
 {
 }
Exemple #28
0
        public Gameboy(CoreComm comm, GameInfo game, byte[] file, Gameboy.GambatteSettings settings, Gameboy.GambatteSyncSettings syncSettings, bool deterministic)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new GBDisassembler());
            ServiceProvider = ser;
            Tracer          = new TraceBuffer
            {
                Header = "Z80: PC, opcode, registers (A, B, C, D, E, F, H, L, LY, SP, CY)"
            };
            ser.Register <ITraceable>(Tracer);
            InitMemoryCallbacks();

            ThrowExceptionForBadRom(file);
            BoardName = MapperName(file);

            DeterministicEmulation = deterministic;

            GambatteState = LibGambatte.gambatte_create();

            if (GambatteState == IntPtr.Zero)
            {
                throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_create)}() returned null???");
            }

            Console.WriteLine(game.System);

            try
            {
                _syncSettings = (GambatteSyncSettings)syncSettings ?? new GambatteSyncSettings();

                LibGambatte.LoadFlags flags = 0;

                switch (_syncSettings.ConsoleMode)
                {
                case GambatteSyncSettings.ConsoleModeType.GB:
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBC:
                    flags |= LibGambatte.LoadFlags.CGB_MODE;
                    break;

                case GambatteSyncSettings.ConsoleModeType.GBA:
                    flags |= LibGambatte.LoadFlags.CGB_MODE | LibGambatte.LoadFlags.GBA_FLAG;
                    break;

                default:
                    if (game.System == "GBC")
                    {
                        flags |= LibGambatte.LoadFlags.CGB_MODE;
                    }
                    break;
                }

                if (_syncSettings.MulticartCompat)
                {
                    flags |= LibGambatte.LoadFlags.MULTICART_COMPAT;
                }

                if (LibGambatte.gambatte_load(GambatteState, file, (uint)file.Length, flags) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_load)}() returned non-zero (is this not a gb or gbc rom?)");
                }

                byte[] bios;
                string biosSystemId;
                string biosId;
                if ((flags & LibGambatte.LoadFlags.CGB_MODE) == LibGambatte.LoadFlags.CGB_MODE)
                {
                    biosSystemId = "GBC";
                    biosId       = _syncSettings.ConsoleMode == GambatteSyncSettings.ConsoleModeType.GBA ? "AGB" : "World";
                    IsCgb        = true;
                }
                else
                {
                    biosSystemId = "GB";
                    biosId       = "World";
                    IsCgb        = false;
                }

                if (_syncSettings.EnableBIOS)
                {
                    bios = comm.CoreFileProvider.GetFirmware(biosSystemId, biosId, true, "BIOS Not Found, Cannot Load.  Change SyncSettings to run without BIOS.");
                }
                else
                {
                    var builtinBios = (biosSystemId, biosId) switch {
                        ("GB", "World") => Resources.FastDmgBoot,
                        ("GBC", "World") => Resources.FastCgbBoot,
                        ("GBC", "AGB") => Resources.FastAgbBoot,
                        (_, _) => throw new Exception("Internal GB Error (BIOS??)"),
                    };
                    bios = BizHawk.Common.Util.DecompressGzipFile(new MemoryStream(builtinBios.Value, false));
                }

                if (LibGambatte.gambatte_loadbios(GambatteState, bios, (uint)bios.Length) != 0)
                {
                    throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbios)}() returned non-zero (bios error)");
                }

                // set real default colors (before anyone mucks with them at all)
                PutSettings((GambatteSettings)settings ?? new GambatteSettings());

                InitSound();

                Frame      = 0;
                LagCount   = 0;
                IsLagFrame = false;

                InputCallback = new LibGambatte.InputGetter(ControllerCallback);

                LibGambatte.gambatte_setinputgetter(GambatteState, InputCallback);

                InitMemoryDomains();

                RomDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n";

                byte[] buff = new byte[32];
                LibGambatte.gambatte_romtitle(GambatteState, buff);
                string romname = System.Text.Encoding.ASCII.GetString(buff);
                Console.WriteLine("Core reported rom name: {0}", romname);

                if (!DeterministicEmulation && _syncSettings.RealTimeRTC)
                {
                    LibGambatte.gambatte_settimemode(GambatteState, false);
                }
                LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

                _cdCallback = new LibGambatte.CDCallback(CDCallbackProc);

                NewSaveCoreSetBuff();
            }
Exemple #29
0
        public VBANext(byte[] file, CoreComm comm, GameInfo game, bool deterministic, object syncsettings)
        {
            var ser = new BasicServiceProvider(this);

            ser.Register <IDisassemblable>(new ArmV4Disassembler());
            ServiceProvider = ser;

            CoreComm = comm;

            byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");
            if (file.Length > 32 * 1024 * 1024)
            {
                throw new ArgumentException("ROM is too big to be a GBA ROM!");
            }
            if (biosfile.Length != 16 * 1024)
            {
                throw new ArgumentException("BIOS file is not exactly 16K!");
            }

            var FES = new LibVBANext.FrontEndSettings
            {
                saveType        = (LibVBANext.FrontEndSettings.SaveType)game.GetInt("saveType", 0),
                flashSize       = (LibVBANext.FrontEndSettings.FlashSize)game.GetInt("flashSize", 0x10000),
                enableRtc       = game.GetInt("rtcEnabled", 0) != 0,
                mirroringEnable = game.GetInt("mirroringEnabled", 0) != 0
            };

            Console.WriteLine("GameDB loaded settings: saveType={0}, flashSize={1}, rtcEnabled={2}, mirroringEnabled={3}",
                              FES.saveType, FES.flashSize, FES.enableRtc, FES.mirroringEnable);

            _syncSettings          = (SyncSettings)syncsettings ?? new SyncSettings();
            DeterministicEmulation = deterministic;

            FES.skipBios       = _syncSettings.SkipBios;
            FES.RTCUseRealTime = _syncSettings.RTCUseRealTime;
            FES.RTCwday        = (int)_syncSettings.RTCInitialDay;
            FES.RTCyear        = _syncSettings.RTCInitialTime.Year % 100;
            FES.RTCmonth       = _syncSettings.RTCInitialTime.Month - 1;
            FES.RTCmday        = _syncSettings.RTCInitialTime.Day;
            FES.RTChour        = _syncSettings.RTCInitialTime.Hour;
            FES.RTCmin         = _syncSettings.RTCInitialTime.Minute;
            FES.RTCsec         = _syncSettings.RTCInitialTime.Second;
            if (DeterministicEmulation)
            {
                // FES.skipBios = false; // this is OK; it is deterministic and probably accurate
                FES.RTCUseRealTime = false;
            }

            Core = LibVBANext.Create();
            if (Core == IntPtr.Zero)
            {
                throw new InvalidOperationException("Create() returned nullptr!");
            }
            try
            {
                if (!LibVBANext.LoadRom(Core, file, (uint)file.Length, biosfile, (uint)biosfile.Length, FES))
                {
                    throw new InvalidOperationException("LoadRom() returned false!");
                }

                Tracer = new TraceBuffer()
                {
                    Header = "ARM7: PC, machine code, mnemonic, operands, registers (r0-r16)"
                };
                ser.Register <ITraceable>(Tracer);

                CoreComm.NominalWidth  = 240;
                CoreComm.NominalHeight = 160;

                GameCode = Encoding.ASCII.GetString(file, 0xac, 4);
                Console.WriteLine("Game code \"{0}\"", GameCode);

                _savebuff  = new byte[LibVBANext.BinStateSize(Core)];
                _savebuff2 = new byte[_savebuff.Length + 13];
                InitMemoryDomains();
                InitRegisters();
                InitCallbacks();

                // todo: hook me up as a setting
                SetupColors();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemple #30
0
		public GbaManager(CoreComm comm)
		{
			_corecomm = comm;

			this.memory = new Memory();
			this.arm7 = new Arm7Processor(this.memory);
			this.videoManager = new VideoManager(this);
			this.videoManager.Memory = this.memory;
			this.soundManager = new SoundManager(this.memory, 44100);
		
			this.framesRendered = 0;
			Renderer renderer = new Renderer();
			renderer.Initialize(null);
			VideoManager.Renderer = renderer;

			videoManager.Presenter = delegate(uint[] data)
			{
				Buffer.BlockCopy(data, 0, this.vbuf, 0, 240 * 160 * 4);
			};
		}
Exemple #31
0
        public Saturnus(CoreComm comm, IEnumerable <Disc> disks, bool deterministic, Settings settings,
                        SyncSettings syncSettings)
            : base(comm, new Configuration
        {
            MaxSamples    = 8192,
            DefaultWidth  = 320,
            DefaultHeight = 240,
            MaxWidth      = 1024,
            MaxHeight     = 1024,
            SystemId      = "SAT"
        })
        {
            settings     = settings ?? new Settings();
            syncSettings = syncSettings ?? new SyncSettings();

            _disks       = disks.ToArray();
            _diskReaders = disks.Select(d => new DiscSectorReader(d)
            {
                Policy = _diskPolicy
            }).ToArray();
            if (!CheckDisks(_diskReaders))
            {
                throw new InvalidOperationException("Some disks are not valid");
            }
            InitCallbacks();

            _core = PreInit <LibSaturnus>(new PeRunnerOptions
            {
                Filename            = "ss.wbx",
                SbrkHeapSizeKB      = 128,
                SealedHeapSizeKB    = 4096,         // 512KB of bios, 2MB of kof95/ultraman carts
                InvisibleHeapSizeKB = 8 * 1024,     // 4MB of framebuffer
                MmapHeapSizeKB      = 0,            // not used?
                PlainHeapSizeKB     = 24 * 1024,    // up to 16MB of cart ram
                StartAddress        = LibSaturnus.StartAddress
            });

            SetFirmwareCallbacks();
            SetCdCallbacks();

            if (!_core.Init(_disks.Length, syncSettings.ExpansionCart, syncSettings.Region, syncSettings.RegionAutodetect))
            {
                throw new InvalidOperationException("Core rejected the disks!");
            }
            ClearAllCallbacks();

            _controllerDeck = new SaturnusControllerDeck(new[]
            {
                syncSettings.Port1Multitap,
                syncSettings.Port2Multitap
            }, new[]
            {
                syncSettings.Port1,
                syncSettings.Port2,
                syncSettings.Port3,
                syncSettings.Port4,
                syncSettings.Port5,
                syncSettings.Port6,
                syncSettings.Port7,
                syncSettings.Port8,
                syncSettings.Port9,
                syncSettings.Port10,
                syncSettings.Port11,
                syncSettings.Port12
            }, _core);
            ControllerDefinition      = _controllerDeck.Definition;
            ControllerDefinition.Name = "Saturn Controller";
            ControllerDefinition.BoolButtons.AddRange(new[]
            {
                "Power", "Reset", "Previous Disk", "Next Disk"
            });

            _core.SetRtc((long)syncSettings.InitialTime.Subtract(new DateTime(1970, 1, 1)).TotalSeconds,
                         syncSettings.Language);

            PostInit();
            SetCdCallbacks();
            _core.SetDisk(0, false);
            PutSettings(settings);
            _syncSettings          = syncSettings;
            DeterministicEmulation = deterministic || !_syncSettings.UseRealTime;
        }