Esempio n. 1
0
        /// <summary>
        /// Return the operation(s) to perform at the beginning or end of a
        /// scan line, given a dest and source word.
        /// </summary>
        private EdgeStrategy GetEdgeStrategy(CombinerFlags dstMask, CombinerFlags srcMask)
        {
            int lookup = (((int)_direction << 6) |
                          (((int)dstMask & 0x6) << 3) |          // XXX
                          (((int)srcMask & 0x6) << 1) |          // XXX
                          ((_leftOver ? 1 : 0) << 1) |
                          ((_extraSrcWord && _xOffset > 0) ? 1 : 0));

            EdgeStrategy result = _rscTable[lookup];

#if TRACING_ENABLED
            if (Trace.TraceOn)
            {
                Trace.Log(LogType.RasterOp, "RasterOp: EdgeStrategy lookup {0:x3} --> {1}", lookup, result);
            }
#endif
#if DEBUG
            // Draw attention for debugging; should throw an exception in release version...
            if (result == EdgeStrategy.Unknown)
            {
                Console.WriteLine("==> Unknown edge strategy {0:x3}! <==", lookup);
            }
#endif
            return(result);
        }
Esempio n. 2
0
        private RasterOp()
        {
            _ropShifter = new Shifter();            // Our own private Idaho
            _srcFifo    = new Queue <ROpWord>(16);  // 4 quads (hardware limit)
            _destFifo   = new Queue <ROpWord>(4);   // 1 quad
            _halfPipe   = new ROpWord();            // 1 word, for overlap
            _rdsTable   = new CombinerFlags[512];   // 9 bit index
            _rscTable   = new EdgeStrategy[128];    // 7 bit index

            LoadRasterOpROMs();
        }
Esempio n. 3
0
        /// <summary>
        /// </summary>
        /// <param name="browser"></param>
        /// <exception cref="System.NotImplementedException" />
        /// <exception cref="System.ArgumentOutOfRangeException" />
        /// <returns>
        /// </returns>
        public static IWebDriver Init(SupportedBrowsers.Browser browser)
        {
            Logger.Debug($"Attempting to start browser: {browser}");
            IBrowserStrategy browserStrategy;

            switch (browser)
            {
            case SupportedBrowsers.Browser.Firefox:
                browserStrategy = new FirefoxStrategy();
                break;

            case SupportedBrowsers.Browser.Chrome:
                browserStrategy = new ChromeStrategy();
                break;

            case SupportedBrowsers.Browser.Iexplore:
                browserStrategy = new InternetExplorerStrategy();
                break;

            case SupportedBrowsers.Browser.Phantomjs:
                browserStrategy = new PhantomjsStrategy();
                break;

            case SupportedBrowsers.Browser.Chromeemulation:
                browserStrategy = new ChromeEmulationStrategy();
                break;

            case SupportedBrowsers.Browser.Edge:
                browserStrategy = new EdgeStrategy();
                break;

            case SupportedBrowsers.Browser.Opera:
            case SupportedBrowsers.Browser.Safari:
                throw new NotImplementedException();

            default:
                throw new ArgumentOutOfRangeException(nameof(browser), browser, null);
            }

            var webDriver = string.IsNullOrWhiteSpace(DriverProvider.Grid)
                ? browserStrategy.GetDriver()
                : new RemoteWebDriver(new Uri(DriverProvider.Grid), browserStrategy.GetOptions());

            Logger.Debug($"Started browser: {browser}");
            return(webDriver);
        }
Esempio n. 4
0
        /// <summary>
        /// Aligns and combines the Source and Destination words to produce a RasterOp
        /// result word.  Called during DestFetch as each word arrives to avoid
        /// complications from the delay in the overlapped Fetch/Store cycle.
        /// </summary>
        private ROpWord ComputeResult(ROpWord dest)
        {
            ROpWord      src = dest;                    // init to silence the Xamarin compiler...
            EdgeStrategy e = EdgeStrategy.NoPopNoPeek;  // assume nothing!  n/a in non-edge cases anyway
            ushort       aligned, combined;

#if TRACING_ENABLED
            if (Trace.TraceOn)
            {
                Trace.Log(LogType.RasterOp, "RasterOp: Result dest word: {0}", dest);
            }
#endif

            #region Align Words

            // The Emperor has made a critical error, and the time for our word
            // alignment has come.  Admiral Ackbar will explain the plan of attack:
            //
            // 1.   At the start of a scanline, our source FIFO is aligned and the
            //      half-pipeline register is "primed".  This means we should be
            //      guaranteed to have at least the first edge word in the FIFO;
            // 2.   If the source spans the quad but the destination doesn't (or
            //      vice versa), we have to account for the "two edges into one"
            //      problem - pull in the extra source word (source L+R -> dest B)
            //      or hold the source word one extra cycle (dest L+R <- source B);
            // 3.   In all other modes, we should be able to just pop the next word
            //      so the FIFOs move in lock step (while in the source region), he
            //      said, handwaving furiously.
            //
            // The RSC03 ROM tells the hardware how to cope with the source FIFO; here
            // we use a lookup table to deal with all the complicated edge alignment
            // rules outlined above.
            //
            // Many Bothans died to bring us this information...

            // Look at the destination word to find our edges and set the _leftOver flag
            switch (dest.Mask)
            {
            // Outside the first edge: return dest unmodified, don't touch the source FIFO
            case CombinerFlags.DontMask:
                return(dest);

            // Outside the second edge: return dest unmodified, but pop the source word too.
            // In some cases we do legitimately clear the last source word, so test for that.
            case CombinerFlags.Leftover:
                if (_srcFifo.Count > 0)
                {
                    src = _srcFifo.Dequeue();
#if DEBUG
                    src.Mask = SrcWordMask(src.Index);      // for debugging, not necessary otherwise
#endif
#if TRACING_ENABLED
                    if (Trace.TraceOn)
                    {
                        Trace.Log(LogType.RasterOp, "RasterOp: Dropped src word: {0}", src);
                    }
#endif
                }
                return(dest);

            // Full word (any phase): should always have a matching source word
            case CombinerFlags.FullWord:
                try
                {
                    src = _srcFifo.Dequeue();
#if DEBUG
                    src.Mask = SrcWordMask(src.Index);      // for debugging, not necessary otherwise
#endif
                }
                catch (InvalidOperationException)
                {
#if DEBUG
                    Console.WriteLine("Source FIFO empty at Full word!");       // continuing will probably fail...
#else
                    throw new InvalidOperationException("Source FIFO empty and Result expected");
#endif
                }
                break;

            // Left edge: flag the beginning or end of the update region
            // Right edge: opposite of left, flag the other end :-)
            case CombinerFlags.LeftEdge:
            case CombinerFlags.RightEdge:
                _leftOver = (dest.Mask == CombinerFlags.LeftEdge && _direction == Direction.RightToLeft) ||
                            (dest.Mask == CombinerFlags.RightEdge && _direction == Direction.LeftToRight);

                if (_srcFifo.Count > 0)
                {
                    src      = _srcFifo.Peek();
                    src.Mask = SrcWordMask(src.Index);
                    e        = GetEdgeStrategy(dest.Mask, src.Mask);
                }
                else if (_leftOver && (_extraSrcWord || _xOffset > 0))
                {
                    // At the end of a line (either direction) we are peeking forward
                    // but have run out of source words.  In this case we copy the half-
                    // pipeline register (in essence, not popping the second edge word)
                    // to provide enough bits to complete the line.
                    src = _halfPipe;
                }
                else
                {
#if DEBUG
                    Console.WriteLine("Source FIFO empty at {0} word!", dest.Mask);       // continuing will probably fail...
#else
                    throw new InvalidOperationException("Source FIFO empty and Result expected");
#endif
                }
                break;

            // Both edges in one word
            case CombinerFlags.Both:
                _leftOver = true;           // But... but... it's false too!  Ow, my head.

                try
                {
                    src      = _srcFifo.Peek();
                    src.Mask = SrcWordMask(src.Index);
                    e        = GetEdgeStrategy(dest.Mask, src.Mask);
                }
                catch (InvalidOperationException)
                {
#if DEBUG
                    Console.WriteLine("Source FIFO empty at Both edges word!");        // continuing will probably fail..
#else
                    throw new InvalidOperationException("Source FIFO empty and Result expected");
#endif
                }
                break;

            // Should never happen if our RDS00 ROM table is correct!
            case CombinerFlags.Invalid:
                throw new InvalidOperationException("RasterOp Destination result word has Invalid mask");
            }

            // Pop the current word?
            if (e == EdgeStrategy.PopPeek || e == EdgeStrategy.PopNoPeek)
            {
                _srcFifo.Dequeue();
                // Mask was already set
            }

            // Peek ahead to the next?
            if (e == EdgeStrategy.PopPeek || e == EdgeStrategy.NoPopPeek)
            {
                src      = _srcFifo.Dequeue();
                src.Mask = SrcWordMask(src.Index);
            }

#if TRACING_ENABLED
            if (Trace.TraceOn)
            {
                Trace.Log(LogType.RasterOp, "RasterOp: Next source word: {0}", src);
            }
#endif

            #endregion

            #region Align Bits

            // The destination word is in the update region and our source word is aligned.
            // If bit alignment is needed, feed the saved word from the half pipe to the
            // shifter with the current word.  Note that the MSB of the combined shifter
            // inputs is always the leftmost pixel in the update region (so, dependent upon
            // the direction of transfer).
            if (_xOffset != 0)
            {
                if (_direction == Direction.LeftToRight)
                {
#if TRACING_ENABLED
                    if (Trace.TraceOn)
                    {
                        Trace.Log(LogType.RasterOp, "RasterOp: Result xtra (hi): {0:x4}", _halfPipe);
                    }
#endif
                    _ropShifter.Shift(src.Data, _halfPipe.Data);
                }
                else
                {
#if TRACING_ENABLED
                    if (Trace.TraceOn)
                    {
                        Trace.Log(LogType.RasterOp, "RasterOp: Result xtra (lo): {0:x4}", _halfPipe);
                    }
#endif
                    _ropShifter.Shift(_halfPipe.Data, src.Data);
                }

                // Save the current source word
                _halfPipe = src;

                // Grab the aligned source word from the shifter
                aligned = _ropShifter.ShifterOutput;
            }
            else
            {
                // Already in alignment
                aligned = src.Data;
            }

#if TRACING_ENABLED
            if (Trace.TraceOn)
            {
                Trace.Log(LogType.RasterOp, "RasterOp: Result aligned:  {0:x4}", aligned);
            }
#endif
            #endregion

            #region Combine 'em

            // Finally! Combine source & dest words using the appropriate mask
            switch (dest.Mask)
            {
            case CombinerFlags.LeftEdge:
                combined = Combine(dest.Data, aligned, _leftEdgeMask);
                break;

            case CombinerFlags.RightEdge:
                combined = Combine(dest.Data, aligned, _rightEdgeMask);
                break;

            case CombinerFlags.Both:
                combined = Combine(dest.Data, aligned, _bothEdgesMask);
                break;

            case CombinerFlags.FullWord:
                combined = Combine(dest.Data, aligned, 0xffff);
                break;

            default:
                combined = dest.Data;       // This can't actually happen (silence a warning)
                break;
            }

#if TRACING_ENABLED
            if (Trace.TraceOn)
            {
                Trace.Log(LogType.RasterOp, "RasterOp: Result combined: {0:x4} (func={1})", combined, _function);
            }
#endif

            #endregion


            // For debugging, we return the ROpWord, updated with the combined result.
            // At some point when this is fully debugged, the dest FIFO could be a
            // simple queue of ushorts, which could improve efficiency.
            dest.Data = combined;
            return(dest);
        }