Beispiel #1
0
        private void RunVBlank()
        {
            if (lcdClock >= 144)
            {
                lcdClock -= 144;

                LY++; // Move to next line

                // If LY == LYC, set the flag and raise interrupt if it's enabled
                matchFlag = LY == LYC;
                if (matchFlag && (enabledInterrupts & GPUInterrupts.OnMatch) != 0)
                {
                    LCDCInterrupt?.Invoke();
                }

                if (LY == 154)
                {
                    renderTask.Wait(); // Wait for the frame to finish rendering

                    // Start rendering the next frame
                    LY = 0;
                    if (LY == LYC && (enabledInterrupts & GPUInterrupts.OnMatch) != 0)
                    {
                        LCDCInterrupt?.Invoke();
                    }

                    lcdMode = GPUMode.OAMRead;
                    if ((enabledInterrupts & GPUInterrupts.OnOAMRead) != 0)
                    {
                        LCDCInterrupt?.Invoke();
                    }
                    renderTask = Task.Run(() => LoadSpriteData());
                }
            }
        }
Beispiel #2
0
        private void RunVRAMRead()
        {
            if (lcdClock >= 43)
            {
                renderTask.Wait(); // Wait for pre-rendering to finish
                lcdClock -= 43;

                // Switch to HBlank mode
                lcdMode = GPUMode.HBlank;
                if ((enabledInterrupts & GPUInterrupts.OnHBlank) != 0)
                {
                    LCDCInterrupt?.Invoke();
                }
                // No task is run during HBlank
            }
        }
Beispiel #3
0
        private void RunHBlank()
        {
            if (lcdClock >= 51) // Horizontal Blank lasts for ~51 m-clock ticks
            {
                lcdClock -= 51;

                LY++; // Move to next line

                // If LY == LYC, set the flag and raise interrupt if it's enabled
                matchFlag = LY == LYC;
                if (matchFlag && (enabledInterrupts & GPUInterrupts.OnMatch) != 0)
                {
                    LCDCInterrupt?.Invoke();
                }

                if (LY == 144) // Switch to vertical blank mode
                {
                    // Begin rendering the frame
                    renderTask = Task.Run(() => RenderFrame());

                    lcdMode = GPUMode.VBlank;

                    // signal vertical blank interrupt and LCD interrupt (if enabled)
                    VBlankInterrupt?.Invoke();
                    if ((enabledInterrupts & GPUInterrupts.OnVBlank) != 0)
                    {
                        LCDCInterrupt?.Invoke();
                    }
                }
                else // Start rendering the next line
                {
                    lcdMode = GPUMode.OAMRead;
                    if ((enabledInterrupts & GPUInterrupts.OnOAMRead) != 0)
                    {
                        LCDCInterrupt?.Invoke();
                    }
                    renderTask = Task.Run(() => LoadSpriteData());
                }
            }
        }