Ejemplo n.º 1
0
        void RenderFromStartClockTo(ulong endClock)
        {

        RenderClock:
            if (StartClock >= endClock)
                return;

            ++HSync;

            if (StartClock == StartHMOVEClock)
            {
                // turn on HMOVE
                HMoveLatch = true;
                HMoveCounter = 0xf;
                P0mmr = P1mmr = M0mmr = M1mmr = BLmmr = true;
            }
            else if (HSync == 0)
            {
                // just wrapped around, clear late HBLANK
                HMoveLatch = false;
            }

            // position counters are incremented during the visible portion of the scanline
            if (HSync >= 68 + (HMoveLatch ? 8 : 0))
            {
                ++P0; ++P1; ++M0; ++M1; ++BL;
            }

            // HMOVE compare, once every 1/4 CLK when on
            if (HMoveCounter >= 0 && (HSync & 3) == 0)
            {
                if (((HMoveCounter ^ RegW[HMP0]) & 0xf) == 0xf) P0mmr = false;
                if (((HMoveCounter ^ RegW[HMP1]) & 0xf) == 0xf) P1mmr = false;
                if (((HMoveCounter ^ RegW[HMM0]) & 0xf) == 0xf) M0mmr = false;
                if (((HMoveCounter ^ RegW[HMM1]) & 0xf) == 0xf) M1mmr = false;
                if (((HMoveCounter ^ RegW[HMBL]) & 0xf) == 0xf) BLmmr = false;
                if (HMoveCounter >= 0) HMoveCounter--;
            }

            // HMOVE increment, once every 1/4 CLK, 2 CLK after first compare when on
            if (HMoveCounter < 0xf && (HSync & 3) == 2)
            {
                if (HSync < 68 + (HMoveLatch ? 8 : 0))
                {
                    if (P0mmr) ++P0;
                    if (P1mmr) ++P1;
                    if (M0mmr) ++M0;
                    if (M1mmr) ++M1;
                    if (BLmmr) ++BL;
                }
            }

            if (HSync == 68 + 76) PFReflectionState = RegW[CTRLPF] & 0x01;

            var fbyte = (byte)0;
            var fbyte_colupf = colupf;
            TIACxFlags cxflags = 0;

            if (vblankon || HSync < 68 + (HMoveLatch ? 8 : 0)) goto WritePixel;

            fbyte = colubk;

            var colupfon = false;
            if ((PF210 & TIATables.PFMask[PFReflectionState][HSync - 68]) != 0)
            {
                if (scoreon) fbyte_colupf = (HSync - 68) < 80 ? colup0 : colup1;
                colupfon = true;
                cxflags |= TIACxFlags.PF;
            }
            if (blon && BL >= 0 && TIATables.BLMask[BLsize][BL])
            {
                colupfon = true;
                cxflags |= TIACxFlags.BL;
            }
            if (!pfpriority && colupfon)
            {
                fbyte = fbyte_colupf;
            }
            if (m1on && M1 >= 0 && TIATables.MxMask[M1size][M1type][M1])
            {
                fbyte = colup1;
                cxflags |= TIACxFlags.M1;
            }
            if (P1 >= 0 && (TIATables.PxMask[P1suppress][P1type][P1] & EffGRP1) != 0)
            {
                fbyte = colup1;
                cxflags |= TIACxFlags.P1;
            }
            if (m0on && M0 >= 0 && TIATables.MxMask[M0size][M0type][M0])
            {
                fbyte = colup0;
                cxflags |= TIACxFlags.M0;
            }
            if (P0 >= 0 && (TIATables.PxMask[P0suppress][P0type][P0] & EffGRP0) != 0)
            {
                fbyte = colup0;
                cxflags |= TIACxFlags.P0;
            } 
            if (pfpriority && colupfon)
            {
                fbyte = fbyte_colupf;
            }

        WritePixel:
            Collisions |= TIATables.CollisionMask[(int)cxflags];

            if (HSync >= 68)
            {
				M.FrameBuffer.VideoBuffer[FrameBufferIndex++] = fbyte;
				if (FrameBufferIndex == M.FrameBuffer.VideoBufferByteLength)
					FrameBufferIndex = 0;
                if (HSync == 227)
                    ScanLine++;
            }

            if (P0 >= 156) P0suppress = 0;
            if (P1 >= 156) P1suppress = 0;

            // denote this CLK has been completed by incrementing to the next
            StartClock++;

            goto RenderClock;
        }
Ejemplo n.º 2
0
 void opCXCLR(ushort addr, byte data)
 {
     Collisions = 0;
 }
Ejemplo n.º 3
0
        public TIA(DeserializationContext input, MachineBase m) : this()
        {
            if (input == null)
                throw new ArgumentNullException("input");
            if (m == null)
                throw new ArgumentNullException("m");

            M = m;
            TIASound = input.ReadTIASound(M, CPU_TICKS_PER_AUDIO_SAMPLE);

            input.CheckVersion(2);
            RegW = input.ReadExpectedBytes(0x40);
            HSync = input.ReadInt32();
            HMoveCounter = input.ReadInt32();
            ScanLine = input.ReadInt32();
            FrameBufferIndex = input.ReadInt32();
            //FrameBufferElement = input.ReadBufferElement();
            StartHMOVEClock = input.ReadUInt64();
            HMoveLatch = input.ReadBoolean();
            StartClock = input.ReadUInt64();
            P0 = input.ReadInt32();
            P0mmr = input.ReadBoolean();
            EffGRP0 = input.ReadByte();
            OldGRP0 = input.ReadByte();
            P0type = input.ReadInt32();
            P0suppress = input.ReadInt32();
            P1 = input.ReadInt32();
            P1mmr = input.ReadBoolean();
            EffGRP1 = input.ReadByte();
            OldGRP1 = input.ReadByte();
            P1type = input.ReadInt32();
            P1suppress = input.ReadInt32();
            M0 = input.ReadInt32();
            M0mmr = input.ReadBoolean();
            M0type = input.ReadInt32();
            M0size = input.ReadInt32();
            m0on = input.ReadBoolean();
            M1 = input.ReadInt32();
            M1mmr = input.ReadBoolean();
            M1type = input.ReadInt32();
            M1size = input.ReadInt32();
            m1on = input.ReadBoolean();
            BL = input.ReadInt32();
            BLmmr = input.ReadBoolean();
            OldENABL = input.ReadBoolean();
            BLsize = input.ReadInt32();
            blon = input.ReadBoolean();
            PF210 = input.ReadUInt32();
            PFReflectionState = input.ReadInt32();
            colubk = input.ReadByte();
            colupf = input.ReadByte();
            colup0 = input.ReadByte();
            colup1 = input.ReadByte();
            vblankon = input.ReadBoolean();
            scoreon = input.ReadBoolean();
            pfpriority = input.ReadBoolean();
            DumpEnabled = input.ReadBoolean();
            DumpDisabledCycle = input.ReadUInt64();
            Collisions = (TIACxPairFlags)input.ReadInt32();
            WSYNCDelayClocks = input.ReadInt32();
            EndOfFrame = input.ReadBoolean();
        }
Ejemplo n.º 4
0
        void RenderFromStartClockTo(ulong endClock)
        {
RenderClock:
            if (StartClock >= endClock)
            {
                return;
            }

            ++HSync;

            if (StartClock == StartHMOVEClock)
            {
                // turn on HMOVE
                HMoveLatch   = true;
                HMoveCounter = 0xf;
                P0mmr        = P1mmr = M0mmr = M1mmr = BLmmr = true;
            }
            else if (HSync == 0)
            {
                // just wrapped around, clear late HBLANK
                HMoveLatch = false;
            }

            // position counters are incremented during the visible portion of the scanline
            if (HSync >= 68 + (HMoveLatch ? 8 : 0))
            {
                ++P0; ++P1; ++M0; ++M1; ++BL;
            }

            // HMOVE compare, once every 1/4 CLK when on
            if (HMoveCounter >= 0 && (HSync & 3) == 0)
            {
                if (((HMoveCounter ^ RegW[HMP0]) & 0xf) == 0xf)
                {
                    P0mmr = false;
                }
                if (((HMoveCounter ^ RegW[HMP1]) & 0xf) == 0xf)
                {
                    P1mmr = false;
                }
                if (((HMoveCounter ^ RegW[HMM0]) & 0xf) == 0xf)
                {
                    M0mmr = false;
                }
                if (((HMoveCounter ^ RegW[HMM1]) & 0xf) == 0xf)
                {
                    M1mmr = false;
                }
                if (((HMoveCounter ^ RegW[HMBL]) & 0xf) == 0xf)
                {
                    BLmmr = false;
                }
                if (HMoveCounter >= 0)
                {
                    HMoveCounter--;
                }
            }

            // HMOVE increment, once every 1/4 CLK, 2 CLK after first compare when on
            if (HMoveCounter < 0xf && (HSync & 3) == 2)
            {
                if (HSync < 68 + (HMoveLatch ? 8 : 0))
                {
                    if (P0mmr)
                    {
                        ++P0;
                    }
                    if (P1mmr)
                    {
                        ++P1;
                    }
                    if (M0mmr)
                    {
                        ++M0;
                    }
                    if (M1mmr)
                    {
                        ++M1;
                    }
                    if (BLmmr)
                    {
                        ++BL;
                    }
                }
            }

            if (HSync == 68 + 76)
            {
                PFReflectionState = RegW[CTRLPF] & 0x01;
            }

            var        fbyte        = (byte)0;
            var        fbyte_colupf = colupf;
            TIACxFlags cxflags      = 0;

            if (vblankon || HSync < 68 + (HMoveLatch ? 8 : 0))
            {
                goto WritePixel;
            }

            fbyte = colubk;

            var colupfon = false;

            if ((PF210 & TIATables.PFMask[PFReflectionState][HSync - 68]) != 0)
            {
                if (scoreon)
                {
                    fbyte_colupf = (HSync - 68) < 80 ? colup0 : colup1;
                }
                colupfon = true;
                cxflags |= TIACxFlags.PF;
            }
            if (blon && BL >= 0 && TIATables.BLMask[BLsize][BL])
            {
                colupfon = true;
                cxflags |= TIACxFlags.BL;
            }
            if (!pfpriority && colupfon)
            {
                fbyte = fbyte_colupf;
            }
            if (m1on && M1 >= 0 && TIATables.MxMask[M1size][M1type][M1])
            {
                fbyte    = colup1;
                cxflags |= TIACxFlags.M1;
            }
            if (P1 >= 0 && (TIATables.PxMask[P1suppress][P1type][P1] & EffGRP1) != 0)
            {
                fbyte    = colup1;
                cxflags |= TIACxFlags.P1;
            }
            if (m0on && M0 >= 0 && TIATables.MxMask[M0size][M0type][M0])
            {
                fbyte    = colup0;
                cxflags |= TIACxFlags.M0;
            }
            if (P0 >= 0 && (TIATables.PxMask[P0suppress][P0type][P0] & EffGRP0) != 0)
            {
                fbyte    = colup0;
                cxflags |= TIACxFlags.P0;
            }
            if (pfpriority && colupfon)
            {
                fbyte = fbyte_colupf;
            }

WritePixel:
            Collisions |= TIATables.CollisionMask[(int)cxflags];

            if (HSync >= 68)
            {
                M.FrameBuffer.VideoBuffer[FrameBufferIndex++] = fbyte;
                if (FrameBufferIndex == M.FrameBuffer.VideoBufferByteLength)
                {
                    FrameBufferIndex = 0;
                }
                if (HSync == 227)
                {
                    ScanLine++;
                }
            }

            if (P0 >= 156)
            {
                P0suppress = 0;
            }
            if (P1 >= 156)
            {
                P1suppress = 0;
            }

            // denote this CLK has been completed by incrementing to the next
            StartClock++;

            goto RenderClock;
        }
Ejemplo n.º 5
0
        public TIA(DeserializationContext input, MachineBase m) : this()
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            M        = m;
            TIASound = input.ReadTIASound(M, CPU_TICKS_PER_AUDIO_SAMPLE);

            input.CheckVersion(2);
            RegW             = input.ReadExpectedBytes(0x40);
            HSync            = input.ReadInt32();
            HMoveCounter     = input.ReadInt32();
            ScanLine         = input.ReadInt32();
            FrameBufferIndex = input.ReadInt32();
            //FrameBufferElement = input.ReadBufferElement();
            StartHMOVEClock = input.ReadUInt64();
            HMoveLatch      = input.ReadBoolean();
            StartClock      = input.ReadUInt64();
            P0                = input.ReadInt32();
            P0mmr             = input.ReadBoolean();
            EffGRP0           = input.ReadByte();
            OldGRP0           = input.ReadByte();
            P0type            = input.ReadInt32();
            P0suppress        = input.ReadInt32();
            P1                = input.ReadInt32();
            P1mmr             = input.ReadBoolean();
            EffGRP1           = input.ReadByte();
            OldGRP1           = input.ReadByte();
            P1type            = input.ReadInt32();
            P1suppress        = input.ReadInt32();
            M0                = input.ReadInt32();
            M0mmr             = input.ReadBoolean();
            M0type            = input.ReadInt32();
            M0size            = input.ReadInt32();
            m0on              = input.ReadBoolean();
            M1                = input.ReadInt32();
            M1mmr             = input.ReadBoolean();
            M1type            = input.ReadInt32();
            M1size            = input.ReadInt32();
            m1on              = input.ReadBoolean();
            BL                = input.ReadInt32();
            BLmmr             = input.ReadBoolean();
            OldENABL          = input.ReadBoolean();
            BLsize            = input.ReadInt32();
            blon              = input.ReadBoolean();
            PF210             = input.ReadUInt32();
            PFReflectionState = input.ReadInt32();
            colubk            = input.ReadByte();
            colupf            = input.ReadByte();
            colup0            = input.ReadByte();
            colup1            = input.ReadByte();
            vblankon          = input.ReadBoolean();
            scoreon           = input.ReadBoolean();
            pfpriority        = input.ReadBoolean();
            DumpEnabled       = input.ReadBoolean();
            DumpDisabledCycle = input.ReadUInt64();
            Collisions        = (TIACxPairFlags)input.ReadInt32();
            WSYNCDelayClocks  = input.ReadInt32();
            EndOfFrame        = input.ReadBoolean();
        }
Ejemplo n.º 6
0
 void opCXCLR(ushort addr, byte data)
 {
     Collisions = 0;
 }
Ejemplo n.º 7
0
        static TIACxPairFlags[] BuildCollisionMaskTable()
        {
            var tabl = new TIACxPairFlags[64];

            for (var i = 0; i < 64; i++)
            {
                tabl[i] = 0;
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.P1))
                {
                    tabl[i] |= TIACxPairFlags.M0P1;
                }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.P0))
                {
                    tabl[i] |= TIACxPairFlags.M0P0;
                }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.P0))
                {
                    tabl[i] |= TIACxPairFlags.M1P0;
                }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.P1))
                {
                    tabl[i] |= TIACxPairFlags.M1P1;
                }
                if (tstCx(i, TIACxFlags.P0, TIACxFlags.PF))
                {
                    tabl[i] |= TIACxPairFlags.P0PF;
                }
                if (tstCx(i, TIACxFlags.P0, TIACxFlags.BL))
                {
                    tabl[i] |= TIACxPairFlags.P0BL;
                }
                if (tstCx(i, TIACxFlags.P1, TIACxFlags.PF))
                {
                    tabl[i] |= TIACxPairFlags.P1PF;
                }
                if (tstCx(i, TIACxFlags.P1, TIACxFlags.BL))
                {
                    tabl[i] |= TIACxPairFlags.P1BL;
                }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.PF))
                {
                    tabl[i] |= TIACxPairFlags.M0PF;
                }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.BL))
                {
                    tabl[i] |= TIACxPairFlags.M0BL;
                }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.PF))
                {
                    tabl[i] |= TIACxPairFlags.M1PF;
                }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.BL))
                {
                    tabl[i] |= TIACxPairFlags.M1BL;
                }
                if (tstCx(i, TIACxFlags.BL, TIACxFlags.PF))
                {
                    tabl[i] |= TIACxPairFlags.BLPF;
                }
                if (tstCx(i, TIACxFlags.P0, TIACxFlags.P1))
                {
                    tabl[i] |= TIACxPairFlags.P0P1;
                }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.M1))
                {
                    tabl[i] |= TIACxPairFlags.M0M1;
                }
            }
            return(tabl);
        }
Ejemplo n.º 8
0
        static TIACxPairFlags[] BuildCollisionMaskTable()
        {
            var tabl = new TIACxPairFlags[64];

            for (var i = 0; i < 64; i++)
            {
                tabl[i] = 0;
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.P1)) { tabl[i] |= TIACxPairFlags.M0P1; }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.P0)) { tabl[i] |= TIACxPairFlags.M0P0; }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.P0)) { tabl[i] |= TIACxPairFlags.M1P0; }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.P1)) { tabl[i] |= TIACxPairFlags.M1P1; }
                if (tstCx(i, TIACxFlags.P0, TIACxFlags.PF)) { tabl[i] |= TIACxPairFlags.P0PF; }
                if (tstCx(i, TIACxFlags.P0, TIACxFlags.BL)) { tabl[i] |= TIACxPairFlags.P0BL; }
                if (tstCx(i, TIACxFlags.P1, TIACxFlags.PF)) { tabl[i] |= TIACxPairFlags.P1PF; }
                if (tstCx(i, TIACxFlags.P1, TIACxFlags.BL)) { tabl[i] |= TIACxPairFlags.P1BL; }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.PF)) { tabl[i] |= TIACxPairFlags.M0PF; }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.BL)) { tabl[i] |= TIACxPairFlags.M0BL; }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.PF)) { tabl[i] |= TIACxPairFlags.M1PF; }
                if (tstCx(i, TIACxFlags.M1, TIACxFlags.BL)) { tabl[i] |= TIACxPairFlags.M1BL; }
                if (tstCx(i, TIACxFlags.BL, TIACxFlags.PF)) { tabl[i] |= TIACxPairFlags.BLPF; }
                if (tstCx(i, TIACxFlags.P0, TIACxFlags.P1)) { tabl[i] |= TIACxPairFlags.P0P1; }
                if (tstCx(i, TIACxFlags.M0, TIACxFlags.M1)) { tabl[i] |= TIACxPairFlags.M0M1; }
            }
            return tabl;
        }