Beispiel #1
0
        public static int[] CreateContentionTable(
            SpectrumRendererParams timing,
            int[] byteContention)
        {
            // build early model table...
            var contention = new int[timing.c_frameTactCount];
            for (int t = 0; t < timing.c_frameTactCount; t++)
            {
                int shifted = t - timing.c_ulaIntBegin;
                if (shifted < 0)
                    shifted += timing.c_frameTactCount;

                contention[shifted] = 0;
                int line = t / timing.c_ulaLineTime;
                int pix = t % timing.c_ulaLineTime;
                if (line < timing.c_ulaFirstPaperLine || line >= (timing.c_ulaFirstPaperLine + 192))
                {
                    contention[shifted] = 0;
                    continue;
                }
                int scrPix = pix - timing.c_ulaFirstPaperTact + 1;
                if (scrPix < 0 || scrPix >= 128)
                {
                    contention[shifted] = 0;
                    continue;
                }
                int pixByte = scrPix % 8;

                contention[shifted] = byteContention[pixByte];
            }
            return contention;
        }
Beispiel #2
0
        public static int[] CreateContentionTable(
            SpectrumRendererParams timing,
            int[] byteContention)
        {
            // build early model table...
            var contention = new int[timing.c_frameTactCount];

            for (int t = 0; t < timing.c_frameTactCount; t++)
            {
                int shifted = (t + 1) + timing.c_ulaIntBegin;
                // check overflow
                if (shifted < 0)
                {
                    shifted += timing.c_frameTactCount;
                }
                shifted %= timing.c_frameTactCount;

                contention[t] = 0;
                int line = shifted / timing.c_ulaLineTime;
                int pix  = shifted % timing.c_ulaLineTime;
                if (line < timing.c_ulaFirstPaperLine || line >= (timing.c_ulaFirstPaperLine + 192))
                {
                    contention[t] = 0;
                    continue;
                }
                int scrPix = pix - timing.c_ulaFirstPaperTact;
                if (scrPix < 0 || scrPix >= 128)
                {
                    contention[t] = 0;
                    continue;
                }
                int pixByte = scrPix % 8;

                contention[t] = byteContention[pixByte];
            }
            return(contention);
        }
Beispiel #3
0
        private static int[] CreateContentionTable(
            SpectrumRendererParams rendererParams,
            byte[] romDd10,
            byte[] romDd11)
        {
            // Simulate full ULA signals according to DD10/DD11 ROM
            // Catch INT and then start scanning until second INT...
            // Store contentions to the list and then check frame length
            const int dd3dd4set  = 0x280 >> 1;
            const int dd5dd6set  = 0x0F0;
            var       dd10addr   = dd3dd4set;
            var       dd11addr   = dd5dd6set;
            var       lastHsync  = (romDd10[dd3dd4set & 0x1FF] & 0x01) != 0;
            var       intgt      = true;
            var       scanning   = false;
            var       scanning2  = false;
            var       contention = new List <int>();
            var       scanTact   = 0;
            var       contIndex  = 0;

            while (true)
            {
                {
                    //var vsync = (romDd11[dd11addr & 0x1FF] & 1) != 0;
                    //var pre56 = (romDd11[dd11addr & 0x1FF] & 2) != 0;
                    var hlock = (romDd11[dd11addr & 0x1FF] & 0x10) != 0;
                    //var vretr = (romDd11[dd11addr & 0x1FF] & 0x20) != 0;
                    var bus75 = (romDd11[dd11addr & 0x1FF] & 0x80) != 0;

                    var dd10val = romDd10[dd10addr & 0x1FF];
                    //var dd11val = romDd11[dd11addr & 0x1FF];
                    // D0 - ССИ (horizontal sync pulse)
                    var hsync = (dd10val & 1) != 0;
                    // D1 - preload DD3/DD4
                    //var pre34 = (dd10val & 2) != 0;
                    // D2 - BUS20 = A1 for DD38-DD41 (vram address generator)
                    // D3 - RAS
                    // D4 - CAS
                    // D5 - BUS23 = block CLK when BUS23=1 and mem access #4000-7FFF
                    var blclk = (dd10val & 0x20) != 0;
                    // D6 - BUS24 = attr/pixel latch, BUS24=0 -> attr latch
                    //var latch = (dd10val & 0x40) != 0;
                    // D7 - BUS142 = horizontal retrace
                    var hretr = (dd10val & 0x80) != 0;

                    if (hretr)                      // TM2 - always set on S=0
                    {
                        intgt = true;
                    }
                    else if (hsync && !lastHsync)   // TM2 - capture D on UP CLK transition
                    {
                        intgt = false;
                    }
                    var intrq = intgt | bus75;

                    //var bus23 = blclk && !hlock;

                    lastHsync = hsync;

                    if (!scanning && !intrq)
                    {
                        scanning = true;
                    }
                    if (scanning && intrq)
                    {
                        scanning2 = true;
                    }
                    if (scanning2 && !intrq)
                    {
                        break;
                    }
                    if (scanning)
                    {
                        contention.Add(0);
                        if (blclk && !hlock)
                        {
                            for (var j = contIndex; j <= scanTact; j++)
                            {
                                contention[j]++;
                            }
                        }
                        else
                        {
                            contIndex = scanTact + 1;
                        }
                        scanTact++;
                    }
                }
                // Counters DD3/DD4, DD5/DD6 simulation
                for (var j = 0; j < 2; j++)
                {
                    // DD2=#E=>#F -> UP-DOWN transition on DD3-C
                    // DD2=#F=>#0 -> DOWN-UP transition on DD3-C
                    // DD3/DD4-C DOWN-UP transition = increment or load
                    var pre34      = (romDd10[dd10addr & 0x1FF] & 2) == 0;
                    var lastVblank = (romDd10[dd10addr & 0x1FF] & 0x80) == 0;
                    dd10addr++;
                    var dd3c = (dd10addr & 7) == 0;
                    var dd4c = dd3c && (dd10addr & 0x78) == 0;
                    if (dd3c && pre34)
                    {
                        dd10addr = (dd10addr & 0x187) | (dd3dd4set & 0x078);
                    }
                    if (dd4c && pre34)
                    {
                        dd10addr = (dd10addr & 0x07F) | (dd3dd4set & 0x180);
                    }
                    // DD5/DD6 - load always when PE=0
                    // increment on +1 DOWN-UP transition
                    var pre56  = (romDd11[dd11addr & 0x1FF] & 2) == 0;
                    var vblank = (romDd10[dd10addr & 0x1FF] & 0x80) == 0;
                    if (pre56)
                    {
                        dd11addr = (dd11addr & 0x100) | (dd5dd6set & 0xFF);
                    }
                    else if (vblank && !lastVblank)
                    {
                        dd11addr++;
                    }
                }
            }
            if (contention.Count != rendererParams.c_frameTactCount)
            {
                throw new ArgumentException("Invalid frame length!");
            }
            return(contention.ToArray());
        }
Beispiel #4
0
        // TODO: check with UlaSpectrum128_Early,
        //      which one should be removed?
        private static int[] CreateContentionTable(SpectrumRendererParams timing)
        {
            // build early model table...
            var contention = new int[timing.c_frameTactCount];
            int[] byteContention = new int[] { 6, 5, 4, 3, 2, 1, 0, 0, };
            for (int t = 0; t < timing.c_frameTactCount; t++)
            {
                int shifted = (t + 1) + timing.c_ulaIntBegin;
                // check overflow
                if (shifted < 0)
                    shifted += timing.c_frameTactCount;
                shifted %= timing.c_frameTactCount;

                contention[t] = 0;
                int line = shifted / timing.c_ulaLineTime;
                int pix = shifted % timing.c_ulaLineTime;
                if (line < timing.c_ulaFirstPaperLine || line >= (timing.c_ulaFirstPaperLine + 192))
                {
                    contention[t] = 0;
                    continue;
                }
                int scrPix = pix - timing.c_ulaFirstPaperTact;
                if (scrPix < 0 || scrPix >= 128)
                {
                    contention[t] = 0;
                    continue;
                }
                int pixByte = scrPix % 8;

                contention[t] = byteContention[pixByte];
            }
            return contention;
        }
Beispiel #5
0
 public static void ValidateParams(SpectrumRendererParams timing)
 {
     //...
 }