private void RebootCore() { // Regenerate mapper here to make sure its state is entirely clean switch (_game.GetOptionsDict()["m"]) { case "2IN1": _mapper = SetMultiCartMapper(Rom.Length, 2); break; case "4IN1": _mapper = SetMultiCartMapper(Rom.Length, 4); break; case "8IN1": _mapper = SetMultiCartMapper(Rom.Length, 8); break; case "16IN1": _mapper = SetMultiCartMapper(Rom.Length, 16); break; case "32IN1": _mapper = SetMultiCartMapper(Rom.Length, 32); break; case "AR": _mapper = new mAR(this); // This mapper has to set up configurations in the contructor. break; case "4K": _mapper = new m4K(); break; case "2K": _mapper = new m2K(); break; case "CM": _mapper = new mCM(); break; case "CV": _mapper = new mCV(); break; case "DPC": _mapper = new mDPC(); break; case "DPC+": _mapper = new mDPCPlus(); break; case "F8": _mapper = new mF8(); break; case "F8SC": _mapper = new mF8SC(); break; case "F6": _mapper = new mF6(); break; case "F6SC": _mapper = new mF6SC(); break; case "F4": _mapper = new mF4(); break; case "F4SC": _mapper = new mF4SC(); break; case "FE": _mapper = new mFE(); break; case "E0": _mapper = new mE0(); break; case "3F": _mapper = new m3F(); break; case "FA": _mapper = new mFA(); break; case "FA2": _mapper = new mFA2(); break; case "E7": _mapper = new mE7(); break; case "F0": _mapper = new mF0(); break; case "UA": _mapper = new mUA(); break; // Special Sega Mapper which has swapped banks case "F8_sega": _mapper = new mF8_sega(); break; // Homebrew mappers case "3E": _mapper = new m3E(); break; case "0840": _mapper = new m0840(); break; case "MC": _mapper = new mMC(); break; case "EF": _mapper = new mEF(); break; case "EFSC": _mapper = new mEFSC(); break; case "X07": _mapper = new mX07(); break; case "4A50": _mapper = new m4A50(); break; case "SB": _mapper = new mSB(); break; default: throw new InvalidOperationException("mapper not supported: " + _game.GetOptionsDict()["m"]); } _mapper.Core = this; _lagcount = 0; Cpu = new MOS6502X <CpuLink>(new CpuLink(this)); if (_game["PAL"]) { _pal = true; } else if (_game["NTSC"]) { _pal = false; } else { _pal = DetectPal(_game, Rom); } // dcfilter coefficent is from real observed hardware behavior: a latched "1" will fully decay by ~170 or so tia sound cycles _tia = new TIA(this, _pal, Settings.SECAMColors); _dcfilter = new DCFilter(_tia, 256); _m6532 = new M6532(this); HardReset(); // Show mapper class on romstatusdetails CoreComm.RomStatusDetails = $"{this._game.Name}\r\nSHA1:{Rom.HashSHA1()}\r\nMD5:{Rom.HashMD5()}\r\nMapper Impl \"{_mapper.GetType()}\""; // Some games (ex. 3D tic tac toe), turn off the screen for extended periods, so we need to allow for this here. if (_game.GetOptionsDict().ContainsKey("SP_FRAME")) { if (_game.GetOptionsDict()["SP_FRAME"] == "true") { SP_FRAME = true; } } if (_game.GetOptionsDict().ContainsKey("SP_RESET")) { if (_game.GetOptionsDict()["SP_RESET"] == "true") { SP_RESET = true; } } }
public ZXSpectrum(CoreComm comm, IEnumerable <byte[]> files, List <GameInfo> game, object settings, object syncSettings, bool?deterministic) { 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 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; if (deterministic != null && deterministic == true) { if (deterministicEmulation == false) { CoreComm.Notify("Forcing Deterministic Emulation"); } deterministicEmulation = deterministic.Value; } 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; _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 SoundProviderMixer((int)(32767 / 10), "System Beeper", (ISoundProvider)_machine.BuzzerDevice); SoundMixer.AddSource((ISoundProvider)_machine.TapeBuzzer, "Tape Audio"); 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 = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).AYPanConfig; _machine.AYDevice.Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).AYVolume; } if (_machine.BuzzerDevice != null) { ((Beeper)_machine.BuzzerDevice as Beeper).Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).EarVolume; } if (_machine.TapeBuzzer != null) { ((Beeper)_machine.TapeBuzzer as Beeper).Volume = ((ZXSpectrumSettings)settings as ZXSpectrumSettings).TapeVolume; } DCFilter dc = new DCFilter(SoundMixer, 512); ser.Register <ISoundProvider>(dc); HardReset(); SetupMemoryDomains(); }
public ZXSpectrum( CoreLoadParameters <ZXSpectrumSettings, ZXSpectrumSyncSettings> lp) { var ser = new BasicServiceProvider(this); ServiceProvider = ser; CoreComm = lp.Comm; _gameInfo = lp.Roms.Select(r => r.Game).ToList(); _cpu = new Z80A(); _tracer = new TraceBuffer(_cpu.TraceHeader); _files = lp.Roms.Select(r => r.RomData).ToList(); var settings = lp.Settings ?? new ZXSpectrumSettings(); var syncSettings = lp.SyncSettings ?? new ZXSpectrumSyncSettings(); PutSyncSettings(syncSettings); PutSettings(settings); var joysticks = new List <JoystickType> { ((ZXSpectrumSyncSettings)syncSettings).JoystickType1, ((ZXSpectrumSyncSettings)syncSettings).JoystickType2, ((ZXSpectrumSyncSettings)syncSettings).JoystickType3 }; DeterministicEmulation = ((ZXSpectrumSyncSettings)syncSettings).DeterministicEmulation; if (lp.DeterministicEmulationRequested) { if (!DeterministicEmulation) { CoreComm.Notify("Forcing Deterministic Emulation"); } DeterministicEmulation = lp.DeterministicEmulationRequested; } 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(); }
private void RebootCore() { // Regenerate mapper here to make sure its state is entirely clean switch (_game.GetOptionsDict()["m"]) { case "2IN1": _mapper = SetMultiCartMapper(Rom.Length, 2); break; case "4IN1": _mapper = SetMultiCartMapper(Rom.Length, 4); break; case "8IN1": _mapper = SetMultiCartMapper(Rom.Length, 8); break; case "16IN1": _mapper = SetMultiCartMapper(Rom.Length, 16); break; case "32IN1": _mapper = SetMultiCartMapper(Rom.Length, 32); break; case "AR": _mapper = new mAR(this); // This mapper has to set up configurations in the contructor. break; case "4K": _mapper = new m4K(); break; case "2K": _mapper = new m2K(); break; case "CM": _mapper = new mCM(); break; case "CV": _mapper = new mCV(); break; case "DPC": _mapper = new mDPC(); break; case "DPC+": _mapper = new mDPCPlus(); break; case "F8": _mapper = new mF8(); break; case "F8SC": _mapper = new mF8SC(); break; case "F6": _mapper = new mF6(); break; case "F6SC": _mapper = new mF6SC(); break; case "F4": _mapper = new mF4(); break; case "F4SC": _mapper = new mF4SC(); break; case "FE": _mapper = new mFE(); break; case "E0": _mapper = new mE0(); break; case "3F": _mapper = new m3F(); break; case "FA": _mapper = new mFA(); break; case "FA2": _mapper = new mFA2(); break; case "E7": _mapper = new mE7(); break; case "F0": _mapper = new mF0(); break; case "UA": _mapper = new mUA(); break; // Special Sega Mapper which has swapped banks case "F8_sega": _mapper = new mF8_sega(); break; // Homebrew mappers case "3E": _mapper = new m3E(); break; case "0840": _mapper = new m0840(); break; case "MC": _mapper = new mMC(); break; case "EF": _mapper = new mEF(); break; case "EFSC": _mapper = new mEFSC(); break; case "X07": _mapper = new mX07(); break; case "4A50": _mapper = new m4A50(); break; case "SB": _mapper = new mSB(); break; default: throw new InvalidOperationException("mapper not supported: " + _game.GetOptionsDict()["m"]); } _mapper.Core = this; _lagcount = 0; Cpu = new MOS6502X { ReadMemory = this.ReadMemory, WriteMemory = this.WriteMemory, PeekMemory = this.PeekMemory, DummyReadMemory = this.ReadMemory, OnExecFetch = this.ExecFetch }; if (_game["PAL"]) { _pal = true; } else if (_game["NTSC"]) { _pal = false; } else { _pal = DetectPal(_game, Rom); } _tia = new TIA(this, _pal, Settings.SECAMColors); _tia.GetFrameRate(out CoreComm.VsyncNum, out CoreComm.VsyncDen); // dcfilter coefficent is from real observed hardware behavior: a latched "1" will fully decay by ~170 or so tia sound cycles _dcfilter = DCFilter.AsISoundProvider(_tia, 256); M6532 = new M6532(this); // Set up the system state here. for instance.. // Read from the reset vector for where to start Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC // Show mapper class on romstatusdetails CoreComm.RomStatusDetails = string.Format( "{0}\r\nSHA1:{1}\r\nMD5:{2}\r\nMapper Impl \"{3}\"", this._game.Name, Rom.HashSHA1(), Rom.HashMD5(), _mapper.GetType()); // as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves. // some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532 // executing a reset sequence at power on, but it's needed so let's hard code it for now Cpu.S = 0xFD; }