Example #1
0
        public VPC(PCEngine pce, VDC vdc1, VDC vdc2, VCE vce, HuC6280 cpu)
        {
            PCE  = pce;
            VDC1 = vdc1;
            VDC2 = vdc2;
            VCE  = vce;
            CPU  = cpu;

            // latch initial video buffer
            FrameBuffer = vdc1.GetVideoBuffer();
            FrameWidth  = vdc1.BufferWidth;
            FrameHeight = vdc1.BufferHeight;
        }
Example #2
0
		public VPC(PCEngine pce, VDC vdc1, VDC vdc2, VCE vce, HuC6280 cpu)
		{
			PCE = pce;
			VDC1 = vdc1;
			VDC2 = vdc2;
			VCE = vce;
			CPU = cpu;

			// latch initial video buffer
			FrameBuffer = vdc1.GetVideoBuffer();
			FrameWidth = vdc1.BufferWidth;
			FrameHeight = vdc1.BufferHeight;
		}
Example #3
0
        public void ExecFrame(bool render)
        {
            // Determine the effective priority mode.
            if (Window1Width < 0x40 && Window2Width < 0x40)
            {
                EffectivePriorityMode = PriorityModeSlot3 >> 2;
            }
            else if (Window2Width > 512)
            {
                EffectivePriorityMode = PriorityModeSlot1 >> 2;
            }
            else
            {
                Console.WriteLine("Unsupported VPC window settings");
                EffectivePriorityMode = 0;
            }

            // Latch frame dimensions and framebuffer, for purely dumb reasons
            FrameWidth  = VDC1.BufferWidth;
            FrameHeight = VDC1.BufferHeight;
            FrameBuffer = VDC1.GetVideoBuffer();

            int ScanLine = 0;
            int ActiveDisplayStartLine = VDC1.DisplayStartLine;

            while (true)
            {
                VDC1.ScanLine = ScanLine;
                VDC2.ScanLine = ScanLine;

                int VBlankLine = ActiveDisplayStartLine + VDC1.Registers[VDW] + 1;
                if (VBlankLine > 261)
                {
                    VBlankLine = 261;
                }
                VDC1.ActiveLine = ScanLine - ActiveDisplayStartLine;
                VDC2.ActiveLine = VDC1.ActiveLine;
                bool InActiveDisplay = (ScanLine >= ActiveDisplayStartLine) && (ScanLine < VBlankLine);

                if (ScanLine == ActiveDisplayStartLine)
                {
                    VDC1.RCRCounter = 0x40;
                    VDC2.RCRCounter = 0x40;
                }

                if (ScanLine == VBlankLine)
                {
                    VDC1.UpdateSpriteAttributeTable();
                    VDC2.UpdateSpriteAttributeTable();
                }

                if (VDC1.RCRCounter == (VDC1.Registers[RCR] & 0x3FF))
                {
                    if (VDC1.RasterCompareInterruptEnabled)
                    {
                        VDC1.StatusByte |= VDC.StatusRasterCompare;
                        CPU.IRQ1Assert   = true;
                    }
                }

                if (VDC2.RCRCounter == (VDC2.Registers[RCR] & 0x3FF))
                {
                    if (VDC2.RasterCompareInterruptEnabled)
                    {
                        VDC2.StatusByte |= VDC.StatusRasterCompare;
                        CPU.IRQ1Assert   = true;
                    }
                }

                CPU.Execute(24);

                if (InActiveDisplay)
                {
                    if (ScanLine == ActiveDisplayStartLine)
                    {
                        VDC1.BackgroundY = VDC1.Registers[BYR];
                        VDC2.BackgroundY = VDC2.Registers[BYR];
                    }
                    else
                    {
                        VDC1.BackgroundY++;
                        VDC1.BackgroundY &= 0x01FF;
                        VDC2.BackgroundY++;
                        VDC2.BackgroundY &= 0x01FF;
                    }
                }

                CPU.Execute(VDC1.HBlankCycles - 24);

                if (InActiveDisplay)
                {
                    if (render)
                    {
                        RenderScanLine();
                    }
                }


                if (ScanLine == VBlankLine && VDC1.VBlankInterruptEnabled)
                {
                    VDC1.StatusByte |= VDC.StatusVerticalBlanking;
                }

                if (ScanLine == VBlankLine && VDC2.VBlankInterruptEnabled)
                {
                    VDC2.StatusByte |= VDC.StatusVerticalBlanking;
                }

                if (ScanLine == VBlankLine + 4 && VDC1.SatDmaPerformed)
                {
                    VDC1.SatDmaPerformed = false;
                    if ((VDC1.Registers[DCR] & 1) > 0)
                    {
                        VDC1.StatusByte |= VDC.StatusVramSatDmaComplete;
                    }
                }

                if (ScanLine == VBlankLine + 4 && VDC2.SatDmaPerformed)
                {
                    VDC2.SatDmaPerformed = false;
                    if ((VDC2.Registers[DCR] & 1) > 0)
                    {
                        VDC2.StatusByte |= VDC.StatusVramSatDmaComplete;
                    }
                }

                CPU.Execute(2);

                if ((VDC1.StatusByte & (VDC.StatusVerticalBlanking | VDC.StatusVramSatDmaComplete)) != 0)
                {
                    CPU.IRQ1Assert = true;
                }

                if ((VDC2.StatusByte & (VDC.StatusVerticalBlanking | VDC.StatusVramSatDmaComplete)) != 0)
                {
                    CPU.IRQ1Assert = true;
                }

                CPU.Execute(455 - VDC1.HBlankCycles - 2);

                if (InActiveDisplay == false && VDC1.DmaRequested)
                {
                    VDC1.RunDmaForScanline();
                }

                if (InActiveDisplay == false && VDC2.DmaRequested)
                {
                    VDC2.RunDmaForScanline();
                }

                VDC1.RCRCounter++;
                VDC2.RCRCounter++;
                ScanLine++;

                if (ScanLine == VCE.NumberOfScanlines)
                {
                    break;
                }
            }
        }