Exemplo n.º 1
0
 /// <summary>
 /// Sets the shadow ram control value of all sub-channels.
 /// </summary>
 /// <param name="control">New shadow ram control value</param>
 public void SetShadowRamControl(ShadowRamControl control)
 {
     for (int i = 0; i < _subChannels.Length; i++)
     {
         _subChannels[i].ShadowRamControl = control;
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Calls a GPU method, using this state.
        /// </summary>
        /// <param name="meth">The GPU method to be called</param>
        public void CallMethod(MethodParams meth)
        {
            int value = meth.Argument;

            // Methods < 0x80 shouldn't be affected by shadow RAM at all.
            if (meth.Method >= 0x80)
            {
                ShadowRamControl shadowCtrl = ShadowRamControl;

                // TODO: Figure out what TrackWithFilter does, compared to Track.
                if (shadowCtrl == ShadowRamControl.Track ||
                    shadowCtrl == ShadowRamControl.TrackWithFilter)
                {
                    _shadow[meth.Method] = value;
                }
                else if (shadowCtrl == ShadowRamControl.Replay)
                {
                    value = _shadow[meth.Method];
                }
            }

            Register register = _registers[meth.Method];

            if (_memory[meth.Method] != value)
            {
                _registers[(int)register.BaseOffset].Modified = true;
            }

            _memory[meth.Method] = value;

            register.Callback?.Invoke(this, value);
        }
Exemplo n.º 3
0
            /// <summary>
            /// Starts executing the macro program code.
            /// </summary>
            /// <param name="mme">Program code</param>
            /// <param name="state">Current GPU state</param>
            public void Execute(int[] mme, ShadowRamControl shadowCtrl, GpuState state, GpuState shadowState)
            {
                if (_executionPending)
                {
                    _executionPending = false;

                    _interpreter?.Execute(mme, Position, _argument, shadowCtrl, state, shadowState);
                }
            }
Exemplo n.º 4
0
        /// <summary>
        /// Executes a macro program until it exits.
        /// </summary>
        /// <param name="mme">Code of the program to execute</param>
        /// <param name="position">Start position to execute</param>
        /// <param name="param">Optional argument passed to the program, 0 if not used</param>
        /// <param name="shadowCtrl">Shadow RAM control register value</param>
        /// <param name="state">Current GPU state</param>
        /// <param name="shadowState">Shadow GPU state</param>
        public void Execute(int[] mme, int position, int param, ShadowRamControl shadowCtrl, GpuState state, GpuState shadowState)
        {
            Reset();

            _gprs[1] = param;

            _pc = position;

            _shadowCtrl = shadowCtrl;

            FetchOpCode(mme);

            while (Step(mme, state, shadowState));

            // Due to the delay slot, we still need to execute
            // one more instruction before we actually exit.
            Step(mme, state, shadowState);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Change the shadow RAM setting
 /// </summary>
 /// <param name="shadowCtrl">The new Shadow RAM setting</param>
 public void SetMmeShadowRamControl(ShadowRamControl shadowCtrl)
 {
     _shadowCtrl = shadowCtrl;
 }
Exemplo n.º 6
0
 /// <summary>
 /// Change the shadow RAM setting
 /// </summary>
 /// <param name="argument">Method call argument</param>
 public void SetMmeShadowRamControl(int argument)
 {
     ShadowCtrl = (ShadowRamControl)argument;
 }
Exemplo n.º 7
0
        /// <summary>
        /// Calls a GPU method.
        /// </summary>
        /// <param name="meth">GPU method call parameters</param>
        public void CallMethod(MethodParams meth)
        {
            if ((NvGpuFifoMeth)meth.Method == NvGpuFifoMeth.BindChannel)
            {
                _subChannels[meth.SubChannel].Class = (ClassId)meth.Argument;
            }
            else if (meth.Method < 0x60)
            {
                switch ((NvGpuFifoMeth)meth.Method)
                {
                case NvGpuFifoMeth.WaitForIdle:
                {
                    _context.Methods.PerformDeferredDraws();

                    _context.Renderer.Pipeline.Barrier();

                    break;
                }

                case NvGpuFifoMeth.SetMacroUploadAddress:
                {
                    _currMacroPosition = meth.Argument;

                    break;
                }

                case NvGpuFifoMeth.SendMacroCodeData:
                {
                    _mme[_currMacroPosition++] = meth.Argument;

                    break;
                }

                case NvGpuFifoMeth.SetMacroBindingIndex:
                {
                    _currMacroBindIndex = meth.Argument;

                    break;
                }

                case NvGpuFifoMeth.BindMacro:
                {
                    int position = meth.Argument;

                    _macros[_currMacroBindIndex++] = new CachedMacro(position);

                    break;
                }

                case NvGpuFifoMeth.SetMmeShadowRamControl:
                {
                    _shadowCtrl = (ShadowRamControl)meth.Argument;

                    break;
                }
                }
            }
            else if (meth.Method < 0xe00)
            {
                SubChannel sc = _subChannels[meth.SubChannel];

                sc.ShadowState.Write(meth.Method, meth.Argument);

                sc.State.CallMethod(meth);
            }
            else
            {
                int macroIndex = (meth.Method >> 1) & MacroIndexMask;

                if ((meth.Method & 1) != 0)
                {
                    _macros[macroIndex].PushArgument(meth.Argument);
                }
                else
                {
                    _macros[macroIndex].StartExecution(meth.Argument);
                }

                if (meth.IsLastCall)
                {
                    SubChannel sc = _subChannels[meth.SubChannel];

                    _macros[macroIndex].Execute(_mme, _shadowCtrl, sc.State, sc.ShadowState);

                    _context.Methods.PerformDeferredDraws();
                }
            }
        }