public void RunPPU(int runto) { // Idle Scanline - 1 Scanline (AKA Scanline 240) while (cntScanline == -2 && !tn.bolReset) { while (cntScanlineCycle < 341) { tsPpu += 5; cntScanlineCycle++; if (tsPpu >= runto) { return; } } cntScanline = -1; scanlineChanged = true; } // VBLANK Time - 20 Scanlines if (tsPpu < tn.VBlankTime) { if (!tn.bolReset) { memory.setVblank(true); } // Make sure the system has not just been reset and check to see if Interrupt is enabled on VBLANK if ((memory.memCPU[0x2000] & 0x80) == 0x80 && !tn.bolReset) { tn.NMIHandler(); } tn.bolReset = false; tsPpu = tn.VBlankTime; // Do nothing during VBlank until the next 'if' statement is false //tsPpu += tn.VBlankTime; // (FIX ME!!!!!!) THIS SHOULD BE +=, but it slows down a lot for some reason!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! cntScanline = -1; cntScanlineCycle = 0; } // Check for VBlank over if (tsPpu >= runto) { return; } else { // Clear Sprite Hit, Sprite Overflow and VBLANK at the end of VBlank // For reason, clearing Sprite Hit causes the scroll offset to change seemingly randomly // So I have disabled the reset of that below if (!tn.bolReset) { memory.memCPU[0x2002] &= 0x40; // (FIX) Should also clear Sprite Hit 0 } // Clear VBlank memory.setVblank(false); } // PreRender Scanline - 1 Scanline while (cntScanline == -1) { while (cntScanlineCycle < 340) { tsPpu += 5; cntScanlineCycle++; if (tsPpu >= runto) { return; } } pixelM = 0; cntScanlineCycle = 0; cntScanline++; scanlineChanged = true; } // Render Scanlines - 240 Scanlines while (cntScanline < 240) { // Set Rendering TRUE tn.rendering = true; while (cntScanlineCycle < 256) { if ((memory.memCPU[0x2001] & 0x08) == 0x08 || (memory.memCPU[0x2001] & 0x10) == 0x10) { renderPixel(); } pixelM++; tsPpu += 5; cntScanlineCycle++; if (tsPpu >= runto) { return; } } while (cntScanlineCycle < 341) { tsPpu += 5; cntScanlineCycle++; if (tsPpu >= runto) { return; } } cntScanlineCycle = 0; cntScanline++; scanlineChanged = true; } if (cntScanline >= 240) { // Set Rendering to FALSE tn.rendering = false; tsPpu = 0; bolReadyToRender = true; cntScanline = -2; } }
private void btnVBlankToggle_Click(object sender, EventArgs e) { //bolSetVBlank = true; memory.setVblank(!memory.bolVBlank); btnVBlankToggle.Text = "VBlank:" + Convert.ToString(memory.bolVBlank); }