/// <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; }; }
/// <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); }
/// <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)"); }
/// <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; }
/// <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; }