Beispiel #1
0
        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;
                }
            }
        }
Beispiel #2
0
        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();
        }
Beispiel #4
0
        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;
        }