Ejemplo n.º 1
0
        private string DisassembleInstruction(CmdInfo info)
        {
            switch (info.ID)
            {
            case CmdID.G_NOOP: return($"gsDPNoOpTag(0x{(uint)info.Args["tag"]:X})");

            case CmdID.G_VTX: return($"gsSPVertex({DisAddress(info.Args["vaddr"])}, {info.Args["numv"]}, {info.Args["vbidx"]})");

            case CmdID.G_MODIFYVTX: return($"gsSPModifyVertex({info.Args["where"]}, {info.Args["vbidx"]}, {info.Args["val"]})");

            case CmdID.G_CULLDL: return($"gsSPCullDisplayList({info.Args["vfirst"]}, {info.Args["vlast"]})");

            case CmdID.G_BRANCH_Z: return($"gsSPBranchLessZraw({DisAddress(_wordHi)}, {info.Args["vbidx"]}, 0x{info.Args["zval"]:X})");

            case CmdID.G_TRI1: return($"gsSP1Triangle({info.Args["v0"]}, {info.Args["v1"]}, {info.Args["v2"]}, 0)");

            case CmdID.G_TRI2: return($"gsSP2Triangles({info.Args["v00"]}, {info.Args["v01"]}, {info.Args["v02"]}, 0, {info.Args["v10"]}, {info.Args["v11"]}, {info.Args["v12"]}, 0)");

            case CmdID.G_QUAD: return($"gsSPQuadrangle({info.Args["v0"]}, {info.Args["v1"]}, {info.Args["v2"]}, {info.Args["v3"]}, 0)");

            case CmdID.G_DMA_IO: return($"gsSPDma_io(0x{info.Args["flag"]:X}, 0x{info.Args["dmem"]:X}, 0x{ info.Args["dram"]:X}, 0x{info.Args["size"]:X})");

            case CmdID.G_TEXTURE: return($"gsSPTexture(0x{info.Args["scaleS"]:X}, 0x{info.Args["scaleT"]:X}, {info.Args["level"]}, {(G_TX_TILE)info.Args["tile"]}, {info.Args["on"]})");

            case CmdID.G_POPMTX: return($"gsSPPopMatrixN(G_MTX_MODELVIEW, {info.Args["num"]})");

            case CmdID.G_GEOMETRYMODE:
            {
                int clearbits = (int)info.Args["clearbits"];
                int setbits   = (int)info.Args["setbits"];

                if (clearbits == 0)
                {
                    var flag = new BitFlag <G_GEO_MODE>((G_GEO_MODE)setbits);
                    return($"gsSPLoadGeometryMode({flag})");
                }
                else if (setbits == 0)
                {
                    var flag = new BitFlag <G_GEO_MODE>((G_GEO_MODE) ~clearbits);
                    return($"gsSPClearGeometryMode({flag})");
                }
                else if (clearbits == 0xFFFFFF)
                {
                    var flag = new BitFlag <G_GEO_MODE>((G_GEO_MODE)setbits);
                    return($"gsSPSetGeometryMode({flag})");
                }
                else
                {
                    var clearFlag = new BitFlag <G_GEO_MODE>((G_GEO_MODE) ~clearbits);
                    var setFlag   = new BitFlag <G_GEO_MODE>((G_GEO_MODE)setbits);
                    return($"gsSPGeometryMode({clearFlag}, {setFlag})");
                }
            }

            case CmdID.G_MTX: return($"gsSPMatrix({DisAddress(info.Args["mtxaddr"])}, {DisMtxParams((int)info.Args["param"])})");

            case CmdID.G_MOVEWORD: break;

            case CmdID.G_MOVEMEM: break;

            case CmdID.G_LOAD_UCODE: return($"gsSPLoadUcodeEx({DisAddress(info.Args["tstart"])}, {DisAddress(_wordHi)}, 0x{info.Args["dsize"]:X})");

            case CmdID.G_DL:
            {
                var branch = info.GetArg <bool>("branch");
                return(branch
                            ? $"gsSPBranchList({DisAddress(info.Args["dl"])})"
                            : $"gsSPDisplayList({DisAddress(info.Args["dl"])})");
            }

            case CmdID.G_ENDDL: return($"gsSPEndDisplayList()");

            case CmdID.G_SPNOOP: return($"gsSPNoOp()");

            case CmdID.G_RDPHALF_1:
            {
                _wordHi = (uint)info.Args["word"];
                break;
            }

            case CmdID.G_SETOTHERMODE_L:
            {
                var cmd = info.Convert <GSetOtherMode>();

                var macro = OtherModeMacro.MacrosL.Find(m => m.Match(cmd));
                if (macro != null)
                {
                    var value = macro.values.Find(v => (uint)v.Item2 == cmd.data);
                    return($"gsDP{macro.Name}({value?.Item1??("0x" +cmd.data.ToString("X"))})");
                }

                return($"gsSPSetOtherMode(G_SETOTHERMODE_L, {(G_MDSFT_L)cmd.shift}, {cmd.len}, 0x{cmd.data:X})");
            }

            case CmdID.G_SETOTHERMODE_H:
            {
                var cmd = info.Convert <GSetOtherMode>();

                var macro = OtherModeMacro.MacrosH.Find(m => m.Match(cmd));
                if (macro != null)
                {
                    var value = macro.values.Find(v => (uint)v.Item2 == cmd.data);
                    return($"gsDP{macro.Name}({value?.Item1 ?? ("0x" + cmd.data.ToString("X"))})");
                }
                return($"gsSPSetOtherMode(G_SETOTHERMODE_H, {(G_MDSFT_H)cmd.shift}, {cmd.len}, 0x{cmd.data:X})");
            }

            case CmdID.G_TEXRECT:
            {
                var cmd = info.Convert <GTexRect>();
                return($"gsSPTextureRectangle({cmd.ulx}, {cmd.uly}, {cmd.lrx}, {cmd.lry}, {cmd.tile}, {cmd.uls}, {cmd.ult}, {cmd.dsdx}, {cmd.dtdy})");
            }

            case CmdID.G_TEXRECTFLIP:
            {
                var cmd = info.Convert <GTexRect>();
                return($"gsSPTextureRectangleFlip({cmd.ulx}, {cmd.uly}, {cmd.lrx}, {cmd.lry}, {cmd.tile}, {cmd.uls}, {cmd.ult}, {cmd.dsdx}, {cmd.dtdy})");
            }

            case CmdID.G_RDPLOADSYNC: return("gsDPLoadSync()");

            case CmdID.G_RDPPIPESYNC: return("gsDPPipeSync()");

            case CmdID.G_RDPTILESYNC: return("gsDPTileSync()");

            case CmdID.G_RDPFULLSYNC: return("gsDPFullSync()");

            case CmdID.G_SETKEYGB:
            {
                var cmd = info.Convert <GSetKeyGB>();
                return($"gsDPSetKeyGB({cmd.centerG}, {cmd.scaleG}, {cmd.widthG}, {cmd.centerB}, {cmd.scaleB}, {cmd.widthB})");
            }

            case CmdID.G_SETKEYR:
            {
                var cmd = info.Convert <GSetKeyR>();
                return($"gsDPSetKeyR({cmd.centerR}, {cmd.widthR}, {cmd.scaleR})");
            }

            case CmdID.G_SETCONVERT: return($"gsDPSetConvert({info.Args["k0"]}, {info.Args["k1"]}, {info.Args["k2"]}, {info.Args["k3"]}, {info.Args["k4"]}, {info.Args["k5"]})");

            case CmdID.G_SETSCISSOR:
            {
                var cmd = info.Convert <GSetScissor>();
                if (cmd.lrx.FracPart() == 0 && cmd.lry.FracPart() == 0 && cmd.ulx.FracPart() == 0 && cmd.uly.FracPart() == 0)
                {
                    return($"gsDPSetScissor({cmd.mode}, {cmd.ulx.IntPart()}, {cmd.uly.IntPart()}, {cmd.lrx.IntPart()}, {cmd.uly.IntPart()})");
                }
                else
                {
                    return($"gsDPSetScissorFrac({cmd.mode}, {cmd.ulx}, {cmd.uly}, {cmd.lrx}, {cmd.lry})");
                }
            }

            case CmdID.G_SETPRIMDEPTH: return($"gsDPSetPrimDepth({info.Args["z"]}, {info.Args["dz"]})");

            case CmdID.G_RDPSETOTHERMODE: return($"gsDPSetOtherMode(0x{info.Args["omodeH"]:X}, 0x{info.Args["omodeL"]:X})");

            case CmdID.G_LOADTLUT: return($"gsDPLoadTLUTCmd({info.Args["tile"]}, {info.Args["count"]})");

            case CmdID.G_RDPHALF_2:
            {
                _wordLo = (uint)info.Args["word"];
                break;
            }

            case CmdID.G_SETTILESIZE:
            {
                var cmd = info.Convert <GLoadTile>();
                return($"gsDPSetTileSize({cmd.tile}, {cmd.uls}, {cmd.ult}, {cmd.lrs}, {cmd.lrt})");
            }

            case CmdID.G_LOADBLOCK:
            {
                var cmd = info.Convert <GLoadBlock>();
                return($"gsDPLoadBlock({cmd.tile}, {cmd.uls}, {cmd.ult}, {cmd.texels}, {cmd.dxt})");
            }

            case CmdID.G_LOADTILE:
            {
                var cmd = info.Convert <GLoadTile>();
                return($"gsDPLoadTile({cmd.tile}, {cmd.uls}, {cmd.ult}, {cmd.lrs}, {cmd.lrt})");
            }

            case CmdID.G_SETTILE:
            {
                var cmt = DisTexWrap((int)info.Args["cmT"]);
                var cmS = DisTexWrap((int)info.Args["cmS"]);
                return($"gsDPSetTile({info.Args["fmt"]}, {info.Args["siz"]}, {info.Args["line"]}, 0x{info.Args["tmem"]:X}, {(G_TX_TILE)info.Args["tile"]}, {info.Args["palette"]}, {cmt}, {info.Args["maskT"]}, {info.Args["shiftT"]}, {cmS}, {info.Args["maskS"]}, {info.Args["shiftS"]})");
            }

            case CmdID.G_FILLRECT:
            {
                var cmd = info.Convert <GFillRect>();
                return($"gsDPFillRectangle({cmd.ulx}, {cmd.uly}, {cmd.lrx}, {cmd.lry})");
            }

            case CmdID.G_SETFILLCOLOR: return($"gsDPSetFillColor(0x{info.Args["color"]:X8})");

            case CmdID.G_SETFOGCOLOR: return($"gsDPSetFogColor({info.Args["R"]}, {info.Args["G"]}, {info.Args["B"]}, {info.Args["A"]})");

            case CmdID.G_SETBLENDCOLOR: return($"gsDPBlendColor({info.Args["R"]}, {info.Args["G"]}, {info.Args["B"]}, {info.Args["A"]})");

            case CmdID.G_SETPRIMCOLOR: return($"gsDPSetPrimColor(0x{info.Args["minlevel"]:X2}, 0x{info.Args["lodfrac"]:X2}, {info.Args["R"]}, {info.Args["G"]}, {info.Args["B"]}, {info.Args["A"]})");

            case CmdID.G_SETENVCOLOR: return($"gsDPSetEnvColor({info.Args["R"]}, {info.Args["G"]}, {info.Args["B"]}, {info.Args["A"]})");

            case CmdID.G_SETCOMBINE:
            {
                var cmd = info.Convert <GSetCombine>();

                var mode0 = CCMode.Modes.Find(m => m.Match(cmd, 0));
                var mode1 = CCMode.Modes.Find(m => m.Match(cmd, 1));
                if (mode0 != null && mode1 != null)
                {
                    return($"gsDPSetCombineMode({mode0.Name}, {mode1.Name})");
                }

                return($"gsDPSetCombineLERP({DisCCM(cmd.a0, 1)}, {DisCCM(cmd.b0, 2)}, {DisCCM(cmd.c0, 3)}, {DisCCM(cmd.d0, 4)}, {DisACM(cmd.Aa0, 1)}, {DisACM(cmd.Ab0, 2)}, {DisACM(cmd.Ac0, 3)}, {DisACM(cmd.Ad0, 4)}, {DisCCM(cmd.a1, 1)}, {DisCCM(cmd.b1, 2)}, {DisCCM(cmd.c1, 3)}, {DisCCM(cmd.d1, 4)}, {DisACM(cmd.Aa1, 1)}, {DisACM(cmd.Ab1, 2)}, {DisACM(cmd.Ac1, 3)}, {DisACM(cmd.Ad1, 4)})");
            }

            case CmdID.G_SETTIMG: return($"gsDPSetTextureImage({info.Args["fmt"]}, {info.Args["siz"]}, {info.Args["width"]}, {DisAddress(info.Args["imgaddr"])})");

            case CmdID.G_SETZIMG: return($"gsDPSetDepthImage({DisAddress(info.Args["imgaddr"])})");

            case CmdID.G_SETCIMG: return($"gsDPSetColorImage({info.Args["fmt"]}, {info.Args["siz"]}, {info.Args["width"]}, {DisAddress(info.Args["imgaddr"])})");

            default:
                break;
            }

            return($"Unsupported Instruction {info.ID}");
        }