Beispiel #1
0
        private void ProcessInstruction()
        {
            GpuDisplayListRunner.Pc = InstructionAddressCurrent;
            var Instruction = ReadInstructionAndMoveNext();

            GpuDisplayListRunner.OpCode   = Instruction.OpCode;
            GpuDisplayListRunner.Params24 = Instruction.Params;

            InstructionSwitch(GpuDisplayListRunner, Instruction.OpCode, Instruction.Params);

            if (Debug)
            {
                var WritePC = Memory.GetPCWriteAddress(GpuDisplayListRunner.Pc);

                Console.Error.WriteLine(
                    "CODE(0x{0:X}-0x{1:X}) : PC(0x{2:X}) : {3} : 0x{4:X} : Done:{5}",
                    InstructionAddressCurrent,
                    InstructionAddressStall,
                    WritePC,
                    Instruction.OpCode,
                    Instruction.Params,
                    Done
                    );
            }
        }
Beispiel #2
0
        private void ProcessInstruction()
        {
            var Instruction = ReadInstructionAndMoveNext();
            var Params24    = Instruction.Params;

            //Console.WriteLine($"ProcessInstruction: Pc={Pc}, Instruction={Instruction}");

            //InstructionSwitch(GpuDisplayListRunner, Instruction.OpCode, Instruction.Params);
            GpuStateStructPointer.data[Instruction.OpCode] = Instruction.Params;
            switch (Instruction.OpCode)
            {
            // Address
            case GpuOpCodes.ORIGIN_ADDR:
                break;

            case GpuOpCodes.OFFSET_ADDR:
                GpuStateData[GpuOpCodes.OFFSET_ADDR] = Params24 << 8;
                break;

            // Flow
            case GpuOpCodes.JUMP:
            {
                JumpRelativeOffset((uint)(Params24 & ~3));
                break;
            }

            case GpuOpCodes.CALL:
            {
                CallRelativeOffset((uint)(Params24 & ~3));
                break;
            }

            case GpuOpCodes.RET:
            {
                Ret();
                break;
            }

            // Finishing
            case GpuOpCodes.END:
            {
                Done = true;
                GpuProcessor.GpuImpl.End(GpuStateStructPointer);
                break;
            }

            case GpuOpCodes.FINISH:
            {
                GpuProcessor.GpuImpl.Finish(GpuStateStructPointer);
                DoFinish(InstructionAddressCurrent, Params24, ExecuteNow: true);
                break;
            }

            // Texture
            case GpuOpCodes.TFLUSH:
                GpuProcessor.GpuImpl.TextureFlush(GpuStateStructPointer);
                break;

            case GpuOpCodes.TSYNC:
                GpuProcessor.GpuImpl.TextureSync(GpuStateStructPointer);
                break;

            // Kicking
            case GpuOpCodes.SPLINE:
                // @TODO
                //auto sp_ucount = command.extract!(uint,  0, 8);
                //auto sp_vcount = command.extract!(uint,  8, 8);
                //auto sp_utype  = command.extract!(uint, 16, 2);
                //auto sp_vtype  = command.extract!(uint, 18, 2);
                //gpu.logWarning("OP_SPLINE(%d, %d, %d, %d)", sp_ucount, sp_vcount, sp_utype, sp_vtype);
                break;

            case GpuOpCodes.TRXKICK:
            {
                var transfer = GpuStateStructPointer.TextureTransferState;
                transfer.TexelSize =
                    (TextureTransferStateStruct.TexelSizeEnum)Params24.Extract(0, 1);
                GpuProcessor.GpuImpl.Transfer(GpuStateStructPointer);
                break;
            }

            case GpuOpCodes.PPRIM:
            {
                //gpu.state.patch.type = command.extract!(PatchPrimitiveType, 0);
                break;
            }

            case GpuOpCodes.PRIM:
            {
                var primitiveType = (GuPrimitiveType)Params24.Extract(16, 3);
                var vertexCount   = (ushort)Params24.Extract(0, 16);

#if PRIM_BATCH
                var nextInstruction = *(GpuInstruction *)Memory.PspAddressToPointerUnsafe(Pc + 4);

                if (_primCount == 0)
                {
                    GpuProcessor.GpuImpl.BeforeDraw(GpuStateStructPointer);
                    GpuProcessor.GpuImpl.PrimStart(GlobalGpuState, GpuStateStructPointer,
                                                   primitiveType);
                }

                if (vertexCount > 0)
                {
                    GpuProcessor.GpuImpl.Prim(vertexCount);
                }

                if (nextInstruction.OpCode == GpuOpCodes.PRIM &&
                    (GuPrimitiveType)nextInstruction.Params.Extract(16, 3) == primitiveType)
                {
                    //Console.WriteLine();
                    _primCount++;
                }
                else
                {
                    //Console.WriteLine("{0:X8}", PC);

                    _primCount = 0;
                    GpuProcessor.GpuImpl.PrimEnd();
                }
#else
                GpuDisplayList.GpuProcessor.GpuImpl.BeforeDraw(GpuDisplayList.GpuStateStructPointer);
                GpuDisplayList.GpuProcessor.GpuImpl.PrimStart(GlobalGpuState, GpuDisplayList.GpuStateStructPointer);
                GpuDisplayList.GpuProcessor.GpuImpl.Prim(GlobalGpuState, GpuDisplayList.GpuStateStructPointer, primitiveType, vertexCount);
                GpuDisplayList.GpuProcessor.GpuImpl.PrimEnd(GlobalGpuState, GpuDisplayList.GpuStateStructPointer);
#endif
            }
            break;

            case GpuOpCodes.BEZIER:
            {
                var uCount = (byte)Params24.Extract(0, 8);
                var vCount = (byte)Params24.Extract(8, 8);
                DrawBezier(uCount, vCount);
                break;
            }

            case GpuOpCodes.ZBW:
            {
                GpuProcessor.MarkDepthBufferLoad();     // @TODO: Is this required?
                break;
            }

            case GpuOpCodes.SIGNAL:
            {
                var signal    = Params24.Extract(0, 16);
                var behaviour = (SignalBehavior)Params24.Extract(16,8);

                Console.Out.WriteLineColored(ConsoleColor.Green,"OP_SIGNAL: {0}, {1}",signal,behaviour);

                switch (behaviour)
                {
                case SignalBehavior.PSP_GE_SIGNAL_NONE:
                    break;

                case SignalBehavior.PSP_GE_SIGNAL_HANDLER_CONTINUE:
                case SignalBehavior.PSP_GE_SIGNAL_HANDLER_PAUSE:
                case SignalBehavior.PSP_GE_SIGNAL_HANDLER_SUSPEND:
                    var next = ReadInstructionAndMoveNext();
                    if (next.OpCode != GpuOpCodes.END)
                    {
                        throw new NotImplementedException("Error! Next Signal not an END! : " + next.OpCode);
                    }
                    break;

                default:
                    throw new NotImplementedException($"Not implemented {behaviour}");
                }

                DoSignal(Pc,signal,behaviour,ExecuteNow: true);

                break;
            }

            // Matrices
            case GpuOpCodes.TMS:
            {
                GpuStateData[GpuOpCodes.TMS] = 0;
                break;
            }

            case GpuOpCodes.TMATRIX:
            {
                var pos = GpuStateData[GpuOpCodes.TMS]++;
                GpuStateData[GpuOpCodes.TMATRIX_BASE + (ushort)pos] = Params24 << 8;
                break;
            }

            case GpuOpCodes.VMS:
            {
                GpuStateData[GpuOpCodes.VMS] = 0;
                break;
            }

            case GpuOpCodes.VIEW:
            {
                var pos = GpuStateData[GpuOpCodes.VMS]++;
                GpuStateData[GpuOpCodes.VIEW_MATRIX_BASE + (ushort)pos] = Params24 << 8;
                break;
            }

            case GpuOpCodes.WMS:
            {
                GpuStateData[GpuOpCodes.WMS] = 0;
                break;
            }

            case GpuOpCodes.WORLD:
            {
                var pos = GpuStateData[GpuOpCodes.WMS]++;
                GpuStateData[GpuOpCodes.WORLD_MATRIX_BASE + (ushort)pos] = Params24 << 8;
                break;
            }

            case GpuOpCodes.PMS:
            {
                GpuStateData[GpuOpCodes.PMS] = 0;
                break;
            }

            case GpuOpCodes.PROJ:
            {
                var pos = GpuStateData[GpuOpCodes.PMS]++;
                GpuStateData[GpuOpCodes.PROJ_MATRIX_BASE + (ushort)pos] = Params24 << 8;
                break;
            }

            case GpuOpCodes.BOFS:
            {
                GpuStateData[GpuOpCodes.BOFS] = Params24;
                break;
            }

            case GpuOpCodes.BONE:
            {
                var pos = GpuStateData[GpuOpCodes.BOFS]++;
                GpuStateData[GpuOpCodes.BONE_MATRIX_BASE + (ushort)pos] = Params24 << 8;
                break;
            }
            }

            if (Debug)
            {
                var WritePC = Memory.GetPCWriteAddress(Pc);

                Console.Error.WriteLine(
                    "CODE(0x{0:X}-0x{1:X}) : PC(0x{2:X}) : {3} : 0x{4:X} : Done:{5}",
                    InstructionAddressCurrent,
                    InstructionAddressStall,
                    WritePC,
                    Instruction.OpCode,
                    Instruction.Params,
                    Done
                    );
            }
        }