Beispiel #1
0
        /// <summary>
        /// Initializes a class instance using a collection of devices
        /// </summary>
        public SpectrumEngine(DeviceInfoCollection deviceData, string ulaIssue = "3")
        {
            DeviceData = deviceData ?? throw new ArgumentNullException(nameof(deviceData));
            UlaIssue   = ulaIssue == "3" ? "3" : "2";

            // --- Prepare the memory device
            var memoryInfo = GetDeviceInfo <IMemoryDevice>();

            MemoryDevice        = memoryInfo?.Device ?? new Spectrum48MemoryDevice();
            MemoryConfiguration = (IMemoryConfiguration)memoryInfo?.ConfigurationData;

            // --- Prepare the port device
            var portInfo = GetDeviceInfo <IPortDevice>();

            PortDevice = portInfo?.Device ?? new Spectrum48PortDevice();

            // --- Init the CPU
            var cpuConfig = GetDeviceConfiguration <IZ80Cpu, ICpuConfiguration>();
            var mult      = 1;

            if (cpuConfig != null)
            {
                BaseClockFrequency = cpuConfig.BaseClockFrequency;
                mult = cpuConfig.ClockMultiplier;
                if (mult < 1)
                {
                    mult = 1;
                }
                else if (mult >= 2 && mult <= 3)
                {
                    mult = 2;
                }
                else if (mult >= 4 && mult <= 7)
                {
                    mult = 4;
                }
                else if (mult > 8)
                {
                    mult = 8;
                }
            }
            ClockMultiplier = mult;
            Cpu             = new Z80Cpu(MemoryDevice,
                                         PortDevice,
                                         cpuConfig?.SupportsNextOperations ?? false)
            {
                UseGateArrayContention = MemoryConfiguration.ContentionType == MemoryContentionType.GateArray
            };

            // --- Init the ROM
            var romInfo = GetDeviceInfo <IRomDevice>();

            RomProvider      = (IRomProvider)romInfo.Provider;
            RomDevice        = romInfo.Device ?? new SpectrumRomDevice();
            RomConfiguration = (IRomConfiguration)romInfo.ConfigurationData;

            // --- Init the screen device
            var screenInfo    = GetDeviceInfo <IScreenDevice>();
            var pixelRenderer = (IScreenFrameProvider)screenInfo.Provider;

            ScreenConfiguration = new ScreenConfiguration((IScreenConfiguration)screenInfo.ConfigurationData);
            ScreenDevice        = screenInfo.Device ?? new Spectrum48ScreenDevice();
            ShadowScreenDevice  = new Spectrum48ScreenDevice();

            // --- Init the beeper device
            var beeperInfo = GetDeviceInfo <IBeeperDevice>();

            AudioConfiguration = (IAudioConfiguration)beeperInfo?.ConfigurationData;
            BeeperProvider     = (IBeeperProvider)beeperInfo?.Provider;
            BeeperDevice       = beeperInfo?.Device ?? new BeeperDevice();

            // --- Init the keyboard device
            var keyboardInfo = GetDeviceInfo <IKeyboardDevice>();

            KeyboardProvider = (IKeyboardProvider)keyboardInfo?.Provider;
            KeyboardDevice   = keyboardInfo?.Device ?? new KeyboardDevice();

            // --- Init the Kempston device
            var kempstonInfo = GetDeviceInfo <IKempstonDevice>();

            KempstonProvider = (IKempstonProvider)kempstonInfo?.Provider;
            KempstonDevice   = kempstonInfo?.Device ?? new KempstonDevice();

            // --- Init the interrupt device
            InterruptDevice = new InterruptDevice(InterruptTact);

            // --- Init the tape device
            var tapeSaveInfo = GetDeviceInfo <ITapeSaveDevice>();

            TapeSaveProvider = (ITapeSaveProvider)tapeSaveInfo?.Provider;
            var tapeLoadInfo = GetDeviceInfo <ITapeLoadDevice>();

            TapeLoadProvider = (ITapeLoadProvider)tapeLoadInfo?.Provider;
            var tapeDevice = new TapeDevice(TapeLoadProvider, TapeSaveProvider);

            TapeLoadDevice = tapeDevice;
            TapeSaveDevice = tapeDevice;

            // === Init optional devices
            // --- Init the sound device
            var soundInfo = GetDeviceInfo <ISoundDevice>();

            SoundConfiguration = (IAudioConfiguration)soundInfo?.ConfigurationData;
            SoundProvider      = (ISoundProvider)soundInfo?.Provider;
            SoundDevice        = soundInfo == null
                ? null
                : soundInfo.Device ?? new SoundDevice();

            // --- Init the floppy device
            var floppyInfo = GetDeviceInfo <IFloppyDevice>();

            if (floppyInfo != null)
            {
                FloppyDevice        = floppyInfo.Device;
                FloppyConfiguration = (IFloppyConfiguration)floppyInfo.ConfigurationData ?? new FloppyConfiguration();
            }

            // --- Carry out frame calculations
            ResetUlaTact();
            FrameTacts        = ScreenConfiguration.ScreenRenderingFrameTactCount;
            FrameCount        = 0;
            Overflow          = 0;
            HasFrameCompleted = true;
            _lastBreakpoint   = null;

            // --- Attach providers
            AttachProvider(RomProvider);
            AttachProvider(pixelRenderer);
            AttachProvider(BeeperProvider);
            AttachProvider(KeyboardProvider);
            AttachProvider(KempstonProvider);
            AttachProvider(TapeLoadProvider);
            AttachProvider(DebugInfoProvider);

            // --- Attach optional providers
            if (SoundProvider != null)
            {
                AttachProvider(SoundProvider);
            }

            // --- Collect Spectrum devices
            _spectrumDevices.Add(RomDevice);
            _spectrumDevices.Add(MemoryDevice);
            _spectrumDevices.Add(PortDevice);
            _spectrumDevices.Add(ScreenDevice);
            _spectrumDevices.Add(ShadowScreenDevice);
            _spectrumDevices.Add(BeeperDevice);
            _spectrumDevices.Add(KeyboardDevice);
            _spectrumDevices.Add(KempstonDevice);
            _spectrumDevices.Add(InterruptDevice);
            _spectrumDevices.Add(TapeLoadDevice);

            // --- Collect optional devices
            if (SoundDevice != null)
            {
                _spectrumDevices.Add(SoundDevice);
            }
            if (FloppyDevice != null)
            {
                _spectrumDevices.Add(FloppyDevice);
            }

            // --- Now, prepare devices to find each other
            foreach (var device in _spectrumDevices)
            {
                device.OnAttachedToVm(this);
            }

            // --- Prepare bound devices
            _frameBoundDevices = _spectrumDevices
                                 .OfType <IRenderFrameBoundDevice>()
                                 .ToList();
            _cpuBoundDevices = _spectrumDevices
                               .OfType <ICpuOperationBoundDevice>()
                               .ToList();

            DebugInfoProvider = new SpectrumDebugInfoProvider();

            // --- Init the ROM
            InitRom(RomDevice, RomConfiguration);
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a class instance using a collection of devices
        /// </summary>
        public SpectrumEngine(DeviceInfoCollection deviceData)
        {
            DeviceData = deviceData ?? throw new ArgumentNullException(nameof(deviceData));

            // --- Check for Spectrum Next
            var nextInfo = GetDeviceInfo <INextFeatureSetDevice>();

            NextDevice = nextInfo?.Device;

            // --- Prepare the memory device
            var memoryInfo = GetDeviceInfo <IMemoryDevice>();

            MemoryDevice        = memoryInfo?.Device ?? new Spectrum48MemoryDevice();
            MemoryConfiguration = (IMemoryConfiguration)memoryInfo?.ConfigurationData;

            // --- Prepare the port device
            var portInfo = GetDeviceInfo <IPortDevice>();

            PortDevice = portInfo?.Device ?? new Spectrum48PortDevice();

            // --- Init the CPU
            var cpuConfig = GetDeviceConfiguration <IZ80Cpu, ICpuConfiguration>();
            var mult      = 1;

            if (cpuConfig != null)
            {
                BaseClockFrequency = cpuConfig.BaseClockFrequency;
                mult = cpuConfig.ClockMultiplier;
                if (mult < 1)
                {
                    mult = 1;
                }
                else if (mult >= 2 && mult <= 3)
                {
                    mult = 2;
                }
                else if (mult >= 4 && mult <= 7)
                {
                    mult = 4;
                }
                else if (mult > 8)
                {
                    mult = 8;
                }
            }
            ClockMultiplier = mult;
            Cpu             = new Z80Cpu(MemoryDevice,
                                         PortDevice,
                                         cpuConfig?.SupportsNextOperations ?? false,
                                         NextDevice)
            {
                UseGateArrayContention = MemoryConfiguration.ContentionType == MemoryContentionType.GateArray
            };

            // --- Init the ROM
            var romInfo = GetDeviceInfo <IRomDevice>();

            RomProvider      = (IRomProvider)romInfo.Provider;
            RomDevice        = romInfo.Device ?? new SpectrumRomDevice();
            RomConfiguration = (IRomConfiguration)romInfo.ConfigurationData;

            // --- Init the clock
            var clockInfo = GetDeviceInfo <IClockDevice>();

            Clock = (IClockProvider)clockInfo.Provider
                    ?? throw new InvalidOperationException("The virtual machine needs a clock provider!");

            // --- Init the screen device
            var screenInfo    = GetDeviceInfo <IScreenDevice>();
            var pixelRenderer = (IScreenFrameProvider)screenInfo.Provider;

            ScreenConfiguration = new ScreenConfiguration((IScreenConfiguration)screenInfo.ConfigurationData);
            ScreenDevice        = screenInfo.Device ?? new Spectrum48ScreenDevice();

            // --- Init the beeper device
            var beeperInfo = GetDeviceInfo <IBeeperDevice>();

            AudioConfiguration = (IAudioConfiguration)beeperInfo?.ConfigurationData;
            BeeperProvider     = (IBeeperProvider)beeperInfo?.Provider;
            BeeperDevice       = beeperInfo?.Device ?? new BeeperDevice();

            // --- Init the keyboard device
            var keyboardInfo = GetDeviceInfo <IKeyboardDevice>();

            KeyboardProvider = (IKeyboardProvider)keyboardInfo?.Provider;
            KeyboardDevice   = keyboardInfo?.Device ?? new KeyboardDevice();

            // --- Init the interrupt device
            InterruptDevice = new InterruptDevice(InterruptTact);

            // --- Init the tape device
            var tapeInfo = GetDeviceInfo <ITapeDevice>();

            TapeProvider = (ITapeProvider)tapeInfo?.Provider;
            TapeDevice   = tapeInfo?.Device
                           ?? new TapeDevice(TapeProvider);

            // === Init optional devices
            // --- Init the sound device
            var soundInfo = GetDeviceInfo <ISoundDevice>();

            SoundConfiguration = (IAudioConfiguration)soundInfo?.ConfigurationData;
            SoundProvider      = (ISoundProvider)soundInfo?.Provider;
            SoundDevice        = soundInfo == null
                ? null
                : soundInfo.Device ?? new SoundDevice();

            // --- Init the DivIDE device
            var divIdeInfo = GetDeviceInfo <IDivIdeDevice>();

            DivIdeDevice = divIdeInfo?.Device;

            // --- Carry out frame calculations
            ResetUlaTact();
            _frameTacts             = ScreenConfiguration.ScreenRenderingFrameTactCount;
            PhysicalFrameClockCount = Clock.GetFrequency() / (double)BaseClockFrequency * _frameTacts;
            FrameCount              = 0;
            Overflow                = 0;
            _frameCompleted         = true;
            _lastBreakpoint         = null;
            RunsInMaskableInterrupt = false;

            // --- Attach providers
            AttachProvider(RomProvider);
            AttachProvider(Clock);
            AttachProvider(pixelRenderer);
            AttachProvider(BeeperProvider);
            AttachProvider(KeyboardProvider);
            AttachProvider(TapeProvider);
            AttachProvider(DebugInfoProvider);

            // --- Attach optional providers
            if (SoundProvider != null)
            {
                AttachProvider(SoundProvider);
            }

            // --- Collect Spectrum devices
            _spectrumDevices.Add(RomDevice);
            _spectrumDevices.Add(MemoryDevice);
            _spectrumDevices.Add(PortDevice);
            _spectrumDevices.Add(ScreenDevice);
            _spectrumDevices.Add(BeeperDevice);
            _spectrumDevices.Add(KeyboardDevice);
            _spectrumDevices.Add(InterruptDevice);
            _spectrumDevices.Add(TapeDevice);

            // --- Collect optional devices
            if (SoundDevice != null)
            {
                _spectrumDevices.Add(SoundDevice);
            }
            if (NextDevice != null)
            {
                _spectrumDevices.Add(NextDevice);
            }
            if (DivIdeDevice != null)
            {
                _spectrumDevices.Add(DivIdeDevice);
            }

            // --- Now, prepare devices to find each other
            foreach (var device in _spectrumDevices)
            {
                device.OnAttachedToVm(this);
            }

            // --- Prepare bound devices
            _frameBoundDevices = _spectrumDevices
                                 .OfType <IFrameBoundDevice>()
                                 .ToList();
            _cpuBoundDevices = _spectrumDevices
                               .OfType <ICpuOperationBoundDevice>()
                               .ToList();

            DebugInfoProvider = new SpectrumDebugInfoProvider();

            // --- Init the ROM
            InitRom(RomDevice, RomConfiguration);
        }
Beispiel #3
0
        /// <summary>Initializes a new instance of the <see cref="T:System.Object" /> class.</summary>
        public Spectrum48(
            IRomProvider romProvider,
            IClockProvider clockProvider,
            IKeyboardProvider keyboardProvider,
            IScreenFrameProvider pixelRenderer,
            IEarBitFrameProvider earBitFrameProvider   = null,
            ITapeContentProvider loadContentProvider   = null,
            ISaveToTapeProvider tapeSaveToTapeProvider = null)
        {
            // --- Init the CPU
            MemoryDevice  = new Spectrum48MemoryDevice();
            PortDevice    = new Spectrum48PortDevice();
            Cpu           = new Z80Cpu(MemoryDevice, PortDevice);
            OsInitialized = false;

            // --- Setup the clock
            Clock = clockProvider;

            // --- Set up Spectrum devices
            BorderDevice    = new BorderDevice();
            ScreenDevice    = new Spectrum48ScreenDevice(pixelRenderer);
            BeeperDevice    = new BeeperDevice(earBitFrameProvider);
            KeyboardDevice  = new KeyboardDevice(keyboardProvider);
            InterruptDevice = new InterruptDevice(InterruptTact);
            TapeDevice      = new TapeDevice(loadContentProvider, tapeSaveToTapeProvider);

            // --- Carry out frame calculations

            ResetUlaTact();
            _frameTacts             = ScreenDevice.ScreenConfiguration.UlaFrameTactCount;
            PhysicalFrameClockCount = Clock.GetFrequency() / (double)ClockFrequeny * _frameTacts;
            FrameCount      = 0;
            Overflow        = 0;
            _frameCompleted = true;

            // --- Collect Spectrum devices
            _spectrumDevices.Add(MemoryDevice);
            _spectrumDevices.Add(PortDevice);
            _spectrumDevices.Add(BorderDevice);
            _spectrumDevices.Add(ScreenDevice);
            _spectrumDevices.Add(BeeperDevice);
            _spectrumDevices.Add(KeyboardDevice);
            _spectrumDevices.Add(InterruptDevice);
            _spectrumDevices.Add(TapeDevice);

            // --- Now, prepare devices to find each other
            foreach (var device in _spectrumDevices)
            {
                device.OnAttachedToVm(this);
            }

            // --- Prepare bound devices
            _frameBoundDevices = _spectrumDevices
                                 .OfType <IFrameBoundDevice>()
                                 .ToList();
            _cpuBoundDevices = _spectrumDevices
                               .OfType <ICpuOperationBoundDevice>()
                               .ToList();

            DebugInfoProvider = new SpectrumDebugInfoProvider();

            // --- Init the ROM
            InitRom(romProvider, "ZXSpectrum48");
        }