Beispiel #1
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;
            };
        }
Beispiel #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);
        }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GpuRegisters"/> class.
 /// </summary>
 /// <param name="lcdControlRegister">The LCD control register.</param>
 /// <param name="currentScanlineRegister">The current scanline register.</param>
 /// <param name="lcdMonochromePaletteRegister">The LCD monochrome palette register.</param>
 /// <param name="lcdStatusRegister">The LCD status register.</param>
 /// <param name="interruptFlagsRegister">The interrupt flags register.</param>
 public GpuRegisters(ILcdControlRegister lcdControlRegister,
                     ICurrentScanlineRegister currentScanlineRegister,
                     ILcdMonochromePaletteRegister lcdMonochromePaletteRegister,
                     ILcdStatusRegister lcdStatusRegister,
                     IInterruptFlagsRegister interruptFlagsRegister)
 {
     LcdStatusRegister            = lcdStatusRegister;
     _interruptFlagsRegister      = interruptFlagsRegister;
     LcdControlRegister           = lcdControlRegister;
     CurrentScanlineRegister      = currentScanlineRegister;
     LcdMonochromePaletteRegister = lcdMonochromePaletteRegister;
     ScrollXRegister = new SimpleRegister(0xff43, "Background Horizontal Scrolling (SCROLLX R/W)");
     ScrollYRegister = new SimpleRegister(0xff42, "Background Vertical Scrolling (SCROLLY R/W)");
     CurrentScanlineCompareRegister = new SimpleRegister(0xff45, "LY Compare (LYC R/W)");
     WindowYPositionRegister        = new SimpleRegister(0xff4a, "Window Y Position (WY R/W)");
     WindowXPositionRegister        = new SimpleRegister(0xff4b, "Window X Position minus 7 (WX R/W)");
 }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SyncSerialPort"/> class.
 /// </summary>
 /// <param name="interruptFlagsRegister">The interrupt flags register.</param>
 public SyncSerialPort(IInterruptFlagsRegister interruptFlagsRegister)
 {
     _interruptFlagsRegister = interruptFlagsRegister;
 }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="JoyPad"/> class.
 /// </summary>
 /// <param name="interruptFlagsRegister">The interrupt flags register.</param>
 public JoyPad(IInterruptFlagsRegister interruptFlagsRegister)
 {
     _interruptFlagsRegister = interruptFlagsRegister;
     _matrixColumn           = MatrixColumn.None;
     _buttons = JoyPadButtonFlags.None;
 }