/// <summary>
        /// Renders to the screen buffer based on the current cycle
        /// </summary>
        public void RenderScreen(int toCycle)
        {
            // check boundaries
            if (toCycle > FrameCycleLength)
            {
                toCycle = FrameCycleLength;
            }

            // render the required number of cycles
            for (int t = LastTState; t < toCycle; t++)
            {
                if (!Border4T || (t & 3) == Border4TStage)
                {
                    fetchBorder = BorderColor;
                }
                else
                {
                }

                //fetchBorder = BorderColor;

                // get the table entry
                var item = RenderingTable.Renderer[t];

                switch (item.RAction)
                {
                case RenderTable.RenderAction.None:
                    break;

                case RenderTable.RenderAction.Border:
                    ScreenBuffer[item.LineOffset]     = ULAPalette[fetchBorder];
                    ScreenBuffer[item.LineOffset + 1] = ULAPalette[fetchBorder];
                    break;

                case RenderTable.RenderAction.BorderAndFetchByte1:
                    ScreenBuffer[item.LineOffset]     = ULAPalette[fetchBorder];
                    ScreenBuffer[item.LineOffset + 1] = ULAPalette[fetchBorder];
                    fetchB1 = _machine.FetchScreenMemory(item.ByteAddress);
                    break;

                case RenderTable.RenderAction.BorderAndFetchAttribute1:
                    ScreenBuffer[item.LineOffset]     = ULAPalette[fetchBorder];
                    ScreenBuffer[item.LineOffset + 1] = ULAPalette[fetchBorder];
                    fetchA1 = _machine.FetchScreenMemory(item.AttributeAddress);
                    ProcessInkPaper(fetchA1);
                    break;

                case RenderTable.RenderAction.Shift1AndFetchByte2:
                    ScreenBuffer[item.LineOffset]     = ((fetchB1 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB1 & 0x40) != 0) ? palInk : palPaper;
                    fetchB1 <<= 2;
                    fetchB2   = _machine.FetchScreenMemory(item.ByteAddress);
                    break;

                case RenderTable.RenderAction.Shift1AndFetchAttribute2:
                    ScreenBuffer[item.LineOffset]     = ((fetchB1 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB1 & 0x40) != 0) ? palInk : palPaper;
                    fetchB1 <<= 2;
                    fetchA2   = _machine.FetchScreenMemory(item.AttributeAddress);
                    break;

                case RenderTable.RenderAction.Shift1:
                    ScreenBuffer[item.LineOffset]     = ((fetchB1 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB1 & 0x40) != 0) ? palInk : palPaper;
                    fetchB1 <<= 2;
                    break;

                case RenderTable.RenderAction.Shift1Last:
                    ScreenBuffer[item.LineOffset]     = ((fetchB1 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB1 & 0x40) != 0) ? palInk : palPaper;
                    fetchB1 <<= 2;
                    ProcessInkPaper(fetchA2);
                    break;

                case RenderTable.RenderAction.Shift2:
                    ScreenBuffer[item.LineOffset]     = ((fetchB2 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB2 & 0x40) != 0) ? palInk : palPaper;
                    fetchB2 <<= 2;
                    break;

                case RenderTable.RenderAction.Shift2AndFetchByte1:
                    ScreenBuffer[item.LineOffset]     = ((fetchB2 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB2 & 0x40) != 0) ? palInk : palPaper;
                    fetchB2 <<= 2;
                    fetchB1   = _machine.FetchScreenMemory(item.ByteAddress);
                    break;

                case RenderTable.RenderAction.Shift2AndFetchAttribute1:
                    ScreenBuffer[item.LineOffset]     = ((fetchB2 & 0x80) != 0) ? palInk : palPaper;
                    ScreenBuffer[item.LineOffset + 1] = ((fetchB2 & 0x40) != 0) ? palInk : palPaper;
                    fetchB2 <<= 2;
                    fetchA1   = _machine.FetchScreenMemory(item.AttributeAddress);
                    ProcessInkPaper(fetchA1);
                    break;
                }
            }

            LastTState = toCycle;
        }
Exemple #2
0
        /// <summary>
        /// Updates the screen buffer based on the number of T-States supplied
        /// </summary>
        /// <param name="_tstates"></param>
        public virtual void UpdateScreenBuffer(long _tstates)
        {
            if (_tstates < actualULAStart)
            {
                return;
            }
            else if (_tstates >= FrameLength)
            {
                _tstates = FrameLength - 1;

                needsPaint = true;
            }

            //the additional 1 tstate is required to get correct number of bytes to output in ircontention.sna
            elapsedTStates = (_tstates + 1 - lastTState) - 1;

            //It takes 4 tstates to write 1 byte. Or, 2 pixels per t-state.

            long numBytes = (elapsedTStates >> 2) + ((elapsedTStates % 4) > 0 ? 1 : 0);

            int pixelData;
            int pixel2Data = 0xff;
            int attrData;
            int attr2Data;
            int bright;
            int ink;
            int paper;
            int flash;

            for (int i = 0; i < numBytes; i++)
            {
                if (tstateToDisp[lastTState] > 1)
                {
                    screenByteCtr = tstateToDisp[lastTState] - 16384;                              //adjust for actual screen offset

                    pixelData = _machine.FetchScreenMemory((ushort)screenByteCtr);                 //screen[screenByteCtr];
                    attrData  = _machine.FetchScreenMemory((ushort)(attr[screenByteCtr] - 16384)); //screen[attr[screenByteCtr] - 16384];

                    lastPixelValue = pixelData;
                    lastAttrValue  = attrData;

                    bright = (attrData & 0x40) >> 3;
                    flash  = (attrData & 0x80) >> 7;
                    ink    = (attrData & 0x07);
                    paper  = ((attrData >> 3) & 0x7);
                    int paletteInk   = ULAPalette[ink + bright];
                    int palettePaper = ULAPalette[paper + bright];

                    if (flashOn && (flash != 0)) //swap paper and ink when flash is on
                    {
                        int temp = paletteInk;
                        paletteInk   = palettePaper;
                        palettePaper = temp;
                    }

                    for (int a = 0; a < 8; ++a)
                    {
                        if ((pixelData & 0x80) != 0)
                        {
                            ScreenBuffer[ULAByteCtr++] = paletteInk;
                            lastAttrValue = ink;
                            //pixelIsPaper = false;
                        }
                        else
                        {
                            ScreenBuffer[ULAByteCtr++] = palettePaper;
                            lastAttrValue = paper;
                        }
                        pixelData <<= 1;
                    }
                }
                else if (tstateToDisp[lastTState] == 1)
                {
                    int bor = ULAPalette[borderColour];

                    for (int g = 0; g < 8; g++)
                    {
                        ScreenBuffer[ULAByteCtr++] = bor;
                    }
                }
                lastTState += 4;
            }
        }