Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CpuCoreBase" /> class.
        /// </summary>
        /// <param name="registers">The registers.</param>
        /// <param name="interruptManager">The interrupt manager.</param>
        /// <param name="peripheralManager">The peripheral manager.</param>
        /// <param name="mmu">The mmu.</param>
        /// <param name="instructionTimer">The instruction timer.</param>
        /// <param name="alu">The alu.</param>
        /// <param name="opCodeDecoder">The opcode decoder.</param>
        /// <param name="instructionBlockFactory">The instruction block decoder.</param>
        /// <param name="dmaController">The dma controller.</param>
        /// <param name="messageBus">The message bus.</param>
        /// <param name="requireInstructionBlockCaching">if set to <c>true</c> [require instruction block caching].</param>
        /// <exception cref="ArgumentException">Instruction block decoder must support caching</exception>
        protected CpuCoreBase(IRegisters registers,
                              IInterruptManager interruptManager,
                              IPeripheralManager peripheralManager,
                              IMmu mmu,
                              IInstructionTimer instructionTimer,
                              IAlu alu,
                              IOpCodeDecoder opCodeDecoder,
                              IInstructionBlockFactory instructionBlockFactory,
                              IDmaController dmaController,
                              IMessageBus messageBus,
                              bool requireInstructionBlockCaching)
        {
            CoreId             = Guid.NewGuid();
            _registers         = registers;
            _interruptManager  = interruptManager;
            _peripheralManager = peripheralManager;
            _mmu = mmu;
            _instructionTimer = instructionTimer;
            _alu                     = alu;
            _opCodeDecoder           = opCodeDecoder;
            _instructionBlockFactory = instructionBlockFactory;
            _dmaController           = dmaController;
            _messageBus              = messageBus;
            messageBus.RegisterHandler(Message.PauseCpu, Pause);
            messageBus.RegisterHandler(Message.ResumeCpu, Resume);

            if (requireInstructionBlockCaching && !_instructionBlockFactory.SupportsInstructionBlockCaching)
            {
                throw new ArgumentException("Instruction block decoder must support caching");
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Gpu"/> class.
        /// </summary>
        /// <param name="gameBoyConfig">The game boy configuration.</param>
        /// <param name="interruptFlagsRegister">The interrupt flags register.</param>
        /// <param name="gpuRegisters">The gpu registers.</param>
        /// <param name="renderer">The renderer.</param>
        /// <param name="timer">The timer.</param>
        public Gpu(IGameBoyConfig gameBoyConfig,
                   IInterruptFlagsRegister interruptFlagsRegister,
                   IGpuRegisters gpuRegisters,
                   IRenderer renderer,
                   IInstructionTimer timer)
        {
            _interruptFlagsRegister = interruptFlagsRegister;
            _gpuRegisters           = gpuRegisters;
            _renderer = renderer;

            _spriteRam = new ArrayBackedMemoryBank(SpriteRamConfig);
            _tileRam   = new ArrayBackedMemoryBank(MapRamConfig);

            _gpuRegisters.GpuMode = GpuMode.VerticalBlank;
            _currentTimings       = 0;

            _gpuRegisters.GpuMode = GpuMode.VerticalBlank;
            _currentTimings       = 0;
            _gpuRegisters.CurrentScanlineRegister.Scanline = 0x92;

            if (gameBoyConfig.RunGpu)
            {
                timer.TimingSync += Sync;
            }

            _lcdBuffer = new Frame(LcdWidth, LcdHeight);
            _paintingTaskCompletionSource = new TaskCompletionSource <bool>();
            _disposed = false;

            Task.Factory.StartNew(() => PaintLoop().Wait(), TaskCreationOptions.LongRunning);

            var timerFrequency = TimeSpan.FromSeconds(1);

            _metricsTimer = new Timer(UpdateMetricsCallback, null, timerFrequency, timerFrequency);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CacheAwareZ80Mmu"/> class.
 /// </summary>
 /// <param name="peripheralManager">The peripheral manager.</param>
 /// <param name="platformConfig">The platform configuration.</param>
 /// <param name="memoryBankController">The memory bank controller.</param>
 /// <param name="dmaController">The dma controller.</param>
 /// <param name="instructionTimer">The instruction timer.</param>
 public Z80Mmu(IPeripheralManager peripheralManager,
               IPlatformConfig platformConfig,
               IMemoryBankController memoryBankController,
               IDmaController dmaController,
               IInstructionTimer instructionTimer)
     : base(GetAddressSegments(peripheralManager, platformConfig, memoryBankController), dmaController, instructionTimer)
 {
 }
Exemplo n.º 4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InterruptManager"/> class.
 /// </summary>
 /// <param name="registers">The registers.</param>
 /// <param name="instructionTimer">The instruction timer.</param>
 public InterruptManager(IRegisters registers, IInstructionTimer instructionTimer)
 {
     _registers           = registers;
     _instructionTimer    = instructionTimer;
     _haltTaskSource      = new TaskCompletionSource <bool>();
     _nextInterruptSource = new TaskCompletionSource <ushort>();
     _cancellationSource  = new CancellationTokenSource();
     Task.Factory.StartNew(InterruptTask, TaskCreationOptions.LongRunning);
 }
Exemplo n.º 5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CacheAwareZ80Mmu"/> class.
 /// </summary>
 /// <param name="peripheralManager">The peripheral manager.</param>
 /// <param name="platformConfig">The platform configuration.</param>
 /// <param name="memoryBankController">The memory bank controller.</param>
 /// <param name="dmaController">The dma controller.</param>
 /// <param name="instructionTimer">The instruction timer.</param>
 public CacheAwareZ80Mmu(IPeripheralManager peripheralManager,
                         IPlatformConfig platformConfig,
                         IMemoryBankController memoryBankController,
                         IDmaController dmaController,
                         IInstructionTimer instructionTimer,
                         IInstructionBlockCache instructionBlockCache)
     : base(peripheralManager, platformConfig, memoryBankController, dmaController, instructionTimer)
 {
     _instructionBlockCache = instructionBlockCache;
 }
Exemplo n.º 6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CpuCore" /> class.
 /// </summary>
 /// <param name="registers">The registers.</param>
 /// <param name="interruptManager">The interrupt manager.</param>
 /// <param name="peripheralManager">The peripheral manager.</param>
 /// <param name="mmu">The mmu.</param>
 /// <param name="instructionTimer">The instruction timer.</param>
 /// <param name="alu">The alu.</param>
 /// <param name="opCodeDecoder">The opcode decoder.</param>
 /// <param name="instructionBlockFactory">The instruction block decoder.</param>
 /// <param name="dmaController">The dma controller.</param>
 /// <param name="messageBus">The message bus.</param>
 public CpuCore(IRegisters registers,
                IInterruptManager interruptManager,
                IPeripheralManager peripheralManager,
                IMmu mmu,
                IInstructionTimer instructionTimer,
                IAlu alu,
                IOpCodeDecoder opCodeDecoder,
                IInstructionBlockFactory instructionBlockFactory,
                IDmaController dmaController,
                IMessageBus messageBus)
     : base(registers, interruptManager, peripheralManager, mmu, instructionTimer, alu, opCodeDecoder, instructionBlockFactory, dmaController, messageBus, false)
 {
 }
Exemplo n.º 7
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="SegmentMmu" /> class.
        /// </summary>
        /// <param name="addressSegments">The address segments.</param>
        /// <param name="dmaController">The dma controller.</param>
        /// <param name="instructionTimer">The instruction timer.</param>
        public SegmentMmu(IEnumerable <IAddressSegment> addressSegments,
                          IDmaController dmaController,
                          IInstructionTimer instructionTimer)
        {
            _dmaController    = dmaController;
            _instructionTimer = instructionTimer;
            var sortedSegments = addressSegments.OrderBy(x => x.Address).ToArray();

            _readSegments         = sortedSegments.OfType <IReadableAddressSegment>().ToArray();
            _readSegmentAddresses = _readSegments.Select(x => x.Address).ToArray();

            _writeSegments         = sortedSegments.OfType <IWriteableAddressSegment>().ToArray();
            _writeSegmentAddresses = _writeSegments.Select(x => x.Address).ToArray();

            CheckSegments(_readSegments);
            CheckSegments(_writeSegments);

            _lockedAddressRanges = new List <AddressRange>();

            // Dma task.
            _dmaThreadCancellation = new CancellationTokenSource();
            Task.Factory.StartNew(DmaTask, TaskCreationOptions.LongRunning);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TimerRegisters"/> class.
        /// </summary>
        /// <param name="timerControlRegister">The timer control register.</param>
        /// <param name="interruptFlagsRegister">The interrupt flags register.</param>
        /// <param name="instructionTimer">The instruction timer.</param>
        public TimerRegisters(ITimerControlRegister timerControlRegister, IInterruptFlagsRegister interruptFlagsRegister, IInstructionTimer instructionTimer)
        {
            TimerControlRegister         = timerControlRegister;
            _interruptFlagsRegister      = interruptFlagsRegister;
            TimerModuloRegister          = new SimpleRegister(0xff06, "Timer Modulo (TMA R/W)");
            TimerCounterRegister         = new SimpleRegister(0xff05, "Timer counter (TIMA R/W)");
            instructionTimer.TimingSync += timings =>
            {
                if (!TimerControlRegister.TimerEnabled)
                {
                    return;
                }

                _cyclesSinceLastIncrement += timings.MachineCycles;
                if (_cyclesSinceLastIncrement > TimerControlRegister.TimerFrequency)
                {
                    if (TimerCounterRegister.Register == 0xff)
                    {
                        // Overflow.
                        TimerCounterRegister.Register = TimerModuloRegister.Register;
                        _interruptFlagsRegister.UpdateInterrupts(InterruptFlag.TimerOverflow);
                    }
                    else
                    {
                        TimerCounterRegister.Register++;
                    }
                }

                _cyclesSinceLastIncrement -= TimerControlRegister.TimerFrequency;
            };
        }