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