Esempio n. 1
0
        public N64(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            InputCallbacks  = new InputCallbackSystem();
            _memorycallbacks.ActiveChanged += RefreshMemoryCallbacks;

            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 (Region)
            {
            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);
            (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(_audioProvider.Resampler);

            string rsp;

            switch (_syncSettings.Rsp)
            {
            default:
            case N64SyncSettings.RspType.Rsp_Hle:
                rsp = "mupen64plus-rsp-hle.dll";
                break;

            case N64SyncSettings.RspType.Rsp_Z64_hlevideo:
                rsp = "mupen64plus-rsp-z64-hlevideo.dll";
                break;

            case N64SyncSettings.RspType.Rsp_cxd4:
                rsp = "mupen64plus-rsp-cxd4.dll";
                break;
            }

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

            InitMemoryDomains();
            RefreshMemoryCallbacks();
            if (_syncSettings.Core != N64SyncSettings.CoreType.Dynarec)
            {
                ConnectTracer();
            }

            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();
        }
Esempio n. 2
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(new[] { "System Bus" });

            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;
        }
Esempio n. 3
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();
        }
Esempio n. 4
0
 /// <summary>
 /// for use in dual core
 /// </summary>
 /// <param name="ics"></param>
 public void ConnectInputCallbackSystem(InputCallbackSystem ics)
 {
     _inputCallbacks = ics;
 }
Esempio n. 5
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();
        }