Example #1
0
        public Gpu(IDisplay display, InterruptManager interruptManager, Dma dma, Ram oamRam, bool gbc)
        {
            _r                = new MemoryRegisters(GpuRegister.Values().ToArray());
            _lcdc             = new Lcdc();
            _interruptManager = interruptManager;
            _gbc              = gbc;
            _videoRam0        = new Ram(0x8000, 0x2000);
            _videoRam1        = gbc ? new Ram(0x8000, 0x2000) : null;
            _oamRam           = oamRam;
            _dma              = dma;

            _bgPalette  = new ColorPalette(0xff68);
            _oamPalette = new ColorPalette(0xff6a);
            _oamPalette.FillWithFf();

            _oamSearchPhase     = new OamSearch(oamRam, _lcdc, _r);
            _pixelTransferPhase = new PixelTransfer(_videoRam0, _videoRam1, oamRam, display, _lcdc, _r, gbc, _bgPalette,
                                                    _oamPalette);
            _hBlankPhase = new HBlankPhase();
            _vBlankPhase = new VBlankPhase();

            _mode  = Mode.OamSearch;
            _phase = _oamSearchPhase.Start();

            _display = display;
        }
Example #2
0
 private void DisableLcd()
 {
     _r.Put(GpuRegister.Ly, 0);
     _ticksInLine     = 0;
     _phase           = _hBlankPhase.Start(250);
     _mode            = Mode.HBlank;
     _lcdEnabled      = false;
     _lcdEnabledDelay = -1;
     _display.Enabled = false;
 }
Example #3
0
        public Mode?Tick()
        {
            if (!_lcdEnabled)
            {
                if (_lcdEnabledDelay != -1)
                {
                    if (--_lcdEnabledDelay == 0)
                    {
                        _display.Enabled = true;
                        _lcdEnabled      = true;
                    }
                }
            }

            if (!_lcdEnabled)
            {
                return(null);
            }

            var oldMode = _mode;

            _ticksInLine++;
            if (_phase.Tick())
            {
                // switch line 153 to 0
                if (_ticksInLine == 4 && _mode == Mode.VBlank && _r.Get(GpuRegister.Ly) == 153)
                {
                    _r.Put(GpuRegister.Ly, 0);
                    RequestLycEqualsLyInterrupt();
                }
            }
            else
            {
                switch (oldMode)
                {
                case Mode.OamSearch:
                    _mode  = Mode.PixelTransfer;
                    _phase = _pixelTransferPhase.Start(_oamSearchPhase.GetSprites());
                    break;

                case Mode.PixelTransfer:
                    _mode  = Mode.HBlank;
                    _phase = _hBlankPhase.Start(_ticksInLine);
                    RequestLcdcInterrupt(3);
                    break;

                case Mode.HBlank:
                    _ticksInLine = 0;
                    if (_r.PreIncrement(GpuRegister.Ly) == 144)
                    {
                        _mode  = Mode.VBlank;
                        _phase = _vBlankPhase.Start();
                        _interruptManager.RequestInterrupt(InterruptManager.InterruptType.VBlank);
                        RequestLcdcInterrupt(4);
                    }
                    else
                    {
                        _mode  = Mode.OamSearch;
                        _phase = _oamSearchPhase.Start();
                    }

                    RequestLcdcInterrupt(5);
                    RequestLycEqualsLyInterrupt();
                    break;

                case Mode.VBlank:
                    _ticksInLine = 0;
                    if (_r.PreIncrement(GpuRegister.Ly) == 1)
                    {
                        _mode = Mode.OamSearch;
                        _r.Put(GpuRegister.Ly, 0);
                        _phase = _oamSearchPhase.Start();
                        RequestLcdcInterrupt(5);
                    }
                    else
                    {
                        _phase = _vBlankPhase.Start();
                    }

                    RequestLycEqualsLyInterrupt();
                    break;
                }
            }

            if (oldMode == _mode)
            {
                return(null);
            }

            return(_mode);
        }