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 ); } }
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 ); } }