2020-10-03 15:22:44 +00:00
|
|
|
#include "global.h"
|
2020-06-05 17:18:39 +00:00
|
|
|
|
|
|
|
#define F3DZEX_CONST(name) \
|
|
|
|
{ name, #name }
|
|
|
|
#define F3DZEX_FLAG(set, unset) \
|
|
|
|
{ set, #set, #unset }
|
|
|
|
#define F3DZEX_RENDERMODE(name, mask) \
|
|
|
|
{ #name, name, mask }
|
|
|
|
#define F3DZEX_SETRENDERMACRO(name, shift, len, value0, value1, value2, value3) \
|
|
|
|
{ \
|
|
|
|
name, shift, len, { \
|
|
|
|
{ #value0, value0 }, { #value1, value1 }, { #value2, value2 }, { #value3, value3 }, \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DISAS_LOG \
|
|
|
|
if (this->enableLog) \
|
|
|
|
osSyncPrintf
|
|
|
|
|
|
|
|
u32 UCodeDisas_TranslateAddr(UCodeDisas* this, u32 addr) {
|
|
|
|
u32 physical = this->segments[SEGMENT_NUMBER(addr)] + SEGMENT_OFFSET(addr);
|
|
|
|
return PHYSICAL_TO_VIRTUAL(physical);
|
|
|
|
}
|
|
|
|
|
|
|
|
F3dzexConst sUCodeDisasGeometryModes[] = {
|
|
|
|
F3DZEX_CONST(G_ZBUFFER), F3DZEX_CONST(G_TEXTURE_ENABLE),
|
|
|
|
F3DZEX_CONST(G_SHADE), F3DZEX_CONST(G_SHADING_SMOOTH),
|
|
|
|
F3DZEX_CONST(G_CULL_FRONT), F3DZEX_CONST(G_CULL_BACK),
|
|
|
|
F3DZEX_CONST(G_FOG), F3DZEX_CONST(G_LIGHTING),
|
|
|
|
F3DZEX_CONST(G_TEXTURE_GEN), F3DZEX_CONST(G_TEXTURE_GEN_LINEAR),
|
|
|
|
F3DZEX_CONST(G_LOD),
|
|
|
|
};
|
|
|
|
|
|
|
|
F3dzexFlag sUCodeDisasMtxFlags[] = {
|
|
|
|
F3DZEX_FLAG(G_MTX_PROJECTION, G_MTX_MODELVIEW),
|
|
|
|
F3DZEX_FLAG(G_MTX_LOAD, G_MTX_MUL),
|
|
|
|
F3DZEX_FLAG(G_MTX_PUSH, G_MTX_NOPUSH),
|
|
|
|
};
|
|
|
|
|
|
|
|
const char* UCodeDisas_ParseCombineColor(u32 value, u32 idx) {
|
|
|
|
const char* ret = "?";
|
|
|
|
|
|
|
|
switch (value) {
|
|
|
|
case G_CCMUX_COMBINED:
|
|
|
|
ret = "COMBINED";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_TEXEL0:
|
|
|
|
ret = "TEXEL0";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_TEXEL1:
|
|
|
|
ret = "TEXEL1";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_PRIMITIVE:
|
|
|
|
ret = "PRIMITIVE";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_SHADE:
|
|
|
|
ret = "SHADE";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_ENVIRONMENT:
|
|
|
|
ret = "ENVIRONMENT";
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
ret = (idx == 2) ? "CENTER" : (idx == 3) ? "SCALE" : "1";
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
ret = (idx == 1) ? "NOISE" : (idx == 2) ? "K4" : (idx == 3) ? "COMBINED_ALPHA" : "0";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (idx == 3) {
|
|
|
|
switch (value) {
|
|
|
|
case G_CCMUX_TEXEL0_ALPHA:
|
|
|
|
ret = "TEXEL0_ALPHA";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_TEXEL1_ALPHA:
|
|
|
|
ret = "TEXEL1_ALPHA";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_PRIMITIVE_ALPHA:
|
|
|
|
ret = "PRIMITIVE_ALPHA";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_SHADE_ALPHA:
|
|
|
|
ret = "SHADE_ALPHA";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_ENV_ALPHA:
|
|
|
|
ret = "ENV_ALPHA";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_LOD_FRACTION:
|
|
|
|
ret = "LOD_FRACTION";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_PRIM_LOD_FRAC:
|
|
|
|
ret = "PRIM_LOD_FRAC";
|
|
|
|
break;
|
|
|
|
case G_CCMUX_K5:
|
|
|
|
ret = "K5";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = "0";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = "0";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* UCodeDisas_ParseCombineAlpha(u32 value, u32 idx) {
|
|
|
|
const char* ret = "?";
|
|
|
|
switch (value) {
|
|
|
|
case 0:
|
|
|
|
ret = (idx == 3) ? "LOD_FRACTION" : "COMBINED";
|
|
|
|
break;
|
|
|
|
case G_ACMUX_TEXEL0:
|
|
|
|
ret = "TEXEL0";
|
|
|
|
break;
|
|
|
|
case G_ACMUX_TEXEL1:
|
|
|
|
ret = "TEXEL1";
|
|
|
|
break;
|
|
|
|
case G_ACMUX_PRIMITIVE:
|
|
|
|
ret = "PRIMITIVE";
|
|
|
|
break;
|
|
|
|
case G_ACMUX_SHADE:
|
|
|
|
ret = "SHADE";
|
|
|
|
break;
|
|
|
|
case G_ACMUX_ENVIRONMENT:
|
|
|
|
ret = "ENVIRONMENT";
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
ret = (idx == 3) ? "PRIM_LOD_FRAC" : "1";
|
|
|
|
break;
|
|
|
|
case G_ACMUX_0:
|
|
|
|
ret = "0";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_Init(UCodeDisas* this) {
|
|
|
|
u32 i;
|
|
|
|
bzero(this, sizeof(UCodeDisas));
|
|
|
|
for (i = 0; i < NUM_SEGMENTS; i++) {
|
|
|
|
this->segments[i] = gSegments[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_Destroy(UCodeDisas* this) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_SetCurUCodeImpl(UCodeDisas* this, void* ptr) {
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < this->ucodeInfoCount; i++) {
|
|
|
|
if (ptr == this->ucodeInfo[i].ptr) {
|
|
|
|
this->ucodeType = this->ucodeInfo[i].type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i >= this->ucodeInfoCount) {
|
2021-09-04 13:33:19 +00:00
|
|
|
DISAS_LOG("マイクロコードが一致しなかった\n"); // "Microcode did not match"
|
2020-06-05 17:18:39 +00:00
|
|
|
this->ucodeType = UCODE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_ParseGeometryMode(UCodeDisas* this, u32 mode) {
|
|
|
|
u32 first = true;
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sUCodeDisasGeometryModes); i++) {
|
2020-08-23 21:50:30 +00:00
|
|
|
if ((sUCodeDisasGeometryModes[i].value & mode) == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
2020-06-05 17:18:39 +00:00
|
|
|
|
2020-08-23 21:50:30 +00:00
|
|
|
if (first) {
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("|");
|
2020-06-05 17:18:39 +00:00
|
|
|
}
|
2020-08-23 21:50:30 +00:00
|
|
|
first = false;
|
|
|
|
|
|
|
|
DISAS_LOG("%s", sUCodeDisasGeometryModes[i].name);
|
2020-06-05 17:18:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_ParseRenderMode(UCodeDisas* this, u32 mode) {
|
|
|
|
static F3dzexRenderMode sUCodeDisasRenderModeFlags[] = {
|
|
|
|
F3DZEX_RENDERMODE(AA_EN, 0x8),
|
|
|
|
F3DZEX_RENDERMODE(Z_CMP, 0x10),
|
|
|
|
F3DZEX_RENDERMODE(Z_UPD, 0x20),
|
|
|
|
F3DZEX_RENDERMODE(IM_RD, 0x40),
|
|
|
|
F3DZEX_RENDERMODE(CLR_ON_CVG, 0x80),
|
|
|
|
F3DZEX_RENDERMODE(CVG_DST_CLAMP, 0x300),
|
|
|
|
F3DZEX_RENDERMODE(CVG_DST_WRAP, 0x300),
|
|
|
|
F3DZEX_RENDERMODE(CVG_DST_FULL, 0x300),
|
|
|
|
F3DZEX_RENDERMODE(CVG_DST_SAVE, 0x300),
|
|
|
|
F3DZEX_RENDERMODE(ZMODE_OPA, 0xC00),
|
|
|
|
F3DZEX_RENDERMODE(ZMODE_INTER, 0xC00),
|
|
|
|
F3DZEX_RENDERMODE(ZMODE_XLU, 0xC00),
|
|
|
|
F3DZEX_RENDERMODE(ZMODE_DEC, 0xC00),
|
|
|
|
F3DZEX_RENDERMODE(CVG_X_ALPHA, 0x1000),
|
|
|
|
F3DZEX_RENDERMODE(ALPHA_CVG_SEL, 0x2000),
|
|
|
|
F3DZEX_RENDERMODE(FORCE_BL, 0x4000),
|
|
|
|
};
|
|
|
|
static const char* D_8012DDDC[4][4] = {
|
|
|
|
{ "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG" },
|
|
|
|
{ "G_BL_A_IN", "G_BL_A_FOG", "G_BL_A_SHADE", "G_BL_0" },
|
|
|
|
{ "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG" },
|
|
|
|
{ "G_BL_1MA", "G_BL_A_MEM", "G_BL_1", "G_BL_0" },
|
|
|
|
};
|
|
|
|
|
2020-08-23 21:50:30 +00:00
|
|
|
s32 i;
|
|
|
|
s32 a;
|
|
|
|
s32 b;
|
|
|
|
|
2020-06-05 17:18:39 +00:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sUCodeDisasRenderModeFlags); i++) {
|
2020-08-23 21:50:30 +00:00
|
|
|
if ((mode & sUCodeDisasRenderModeFlags[i].mask) != sUCodeDisasRenderModeFlags[i].value) {
|
|
|
|
continue;
|
2020-06-05 17:18:39 +00:00
|
|
|
}
|
2020-08-23 21:50:30 +00:00
|
|
|
|
|
|
|
DISAS_LOG("%s|", sUCodeDisasRenderModeFlags[i].name);
|
2020-06-05 17:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
a = (mode >> 18) & 0x3333;
|
|
|
|
b = (mode >> 16) & 0x3333;
|
|
|
|
|
|
|
|
// clang-format off
|
2020-08-23 21:50:30 +00:00
|
|
|
if (this->enableLog == 0) {} else { osSyncPrintf("\nGBL_c1(%s, %s, %s, %s)|",
|
|
|
|
D_8012DDDC[0][a >> 12 & 3], D_8012DDDC[1][a >> 8 & 3], D_8012DDDC[2][a >> 4 & 3], D_8012DDDC[3][a >> 0 & 3]); }
|
2020-06-05 17:18:39 +00:00
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
if (this->enableLog) {
|
|
|
|
osSyncPrintf("\nGBL_c2(%s, %s, %s, %s)", D_8012DDDC[0][b >> 12 & 3], D_8012DDDC[1][b >> 8 & 3],
|
|
|
|
D_8012DDDC[2][b >> 4 & 3], D_8012DDDC[3][b >> 0 & 3]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_PrintVertices(UCodeDisas* this, Vtx* vtx, s32 count, s32 start) {
|
|
|
|
s32 i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
if (this->geometryMode & G_LIGHTING) {
|
|
|
|
DISAS_LOG("\n{{%6d, %6d, %6d, %d, %6d, %6d, %3d, %3d, %3d, %3d}}, /* vc%d */", vtx->n.ob[0], vtx->n.ob[1],
|
|
|
|
vtx->n.ob[2], vtx->n.flag, vtx->n.tc[0], vtx->n.tc[1], vtx->n.n[0], vtx->n.n[1], vtx->n.n[2],
|
|
|
|
vtx->n.a, start + i);
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("\n{{%6d, %6d, %6d, %d, %6d, %6d, %3d, %3d, %3d, %3d}}, /* vn%d */", vtx->v.ob[0], vtx->v.ob[1],
|
|
|
|
vtx->v.ob[2], vtx->v.flag, vtx->v.tc[0], vtx->v.tc[1], vtx->v.cn[0], vtx->v.cn[1], vtx->v.cn[2],
|
|
|
|
vtx->v.cn[3], start + i);
|
|
|
|
}
|
|
|
|
vtx++;
|
|
|
|
|
|
|
|
if (1) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-31 20:39:29 +00:00
|
|
|
// Todo: clean this up
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
s8 cmd;
|
|
|
|
u8 v0;
|
|
|
|
u8 v1;
|
|
|
|
u8 wd;
|
|
|
|
u32 pad;
|
|
|
|
} Gline3DFix;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int cmd : 8;
|
|
|
|
u8 pad;
|
|
|
|
u8 prim_min_level;
|
|
|
|
u8 prim_level;
|
|
|
|
u8 r;
|
|
|
|
u8 g;
|
|
|
|
u8 b;
|
|
|
|
u8 a;
|
|
|
|
} GsetcolorMod;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
u8 cmd;
|
|
|
|
char pad[3];
|
|
|
|
u16 z;
|
|
|
|
u16 d;
|
|
|
|
} Gsetprimdepth;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
s32 cmd : 8;
|
|
|
|
u32 type : 8;
|
|
|
|
u32 len : 16;
|
|
|
|
union {
|
|
|
|
u32 u32;
|
|
|
|
f32 f32;
|
|
|
|
} value;
|
|
|
|
} Gnoop;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
u8 cmd;
|
|
|
|
u8 pad[2];
|
|
|
|
u8 params;
|
|
|
|
u32 addr;
|
|
|
|
} Gmatrix;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
u8 cmd;
|
|
|
|
u32 a : 4;
|
|
|
|
u32 c : 5;
|
|
|
|
u32 z : 3;
|
|
|
|
u32 x : 3;
|
|
|
|
u32 e : 4;
|
|
|
|
u32 g : 5;
|
|
|
|
u32 b : 4;
|
|
|
|
u32 f : 4;
|
|
|
|
u32 v : 3;
|
|
|
|
u32 t : 3;
|
|
|
|
u32 d : 3;
|
|
|
|
u32 y : 3;
|
|
|
|
u32 w : 3;
|
|
|
|
u32 h : 3;
|
|
|
|
u32 u : 3;
|
|
|
|
u32 s : 3;
|
|
|
|
} GsetcombineMod;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
u32 cmd : 8;
|
|
|
|
u32 pad0 : 8;
|
|
|
|
u32 sft : 8;
|
|
|
|
u32 len : 8;
|
|
|
|
u32 data : 32;
|
|
|
|
} GsetothermodeMod;
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
Gwords words;
|
|
|
|
Gnoop noop;
|
|
|
|
Gmatrix matrix;
|
|
|
|
Gdma dma;
|
|
|
|
Gtri tri;
|
|
|
|
Gline3D line;
|
|
|
|
Gpopmtx popmtx;
|
|
|
|
Gsegment segment;
|
|
|
|
GsetothermodeH setothermodeH;
|
|
|
|
GsetothermodeL setothermodeL;
|
|
|
|
GsetothermodeMod setothermode;
|
|
|
|
Gtexture texture;
|
|
|
|
Gperspnorm perspnorm;
|
|
|
|
Gsetimg setimg;
|
|
|
|
GsetcombineMod setcombine;
|
|
|
|
GsetcolorMod setcolor; // mod
|
|
|
|
Gfillrect fillrect; /* use for setscissor also */
|
|
|
|
Gsettile settile;
|
|
|
|
Gloadtile loadtile; /* use for loadblock also, th is dxt */
|
|
|
|
Gsettilesize settilesize;
|
|
|
|
Gloadtlut loadtlut;
|
|
|
|
Gsetprimdepth setprimdepth;
|
|
|
|
long long int force_structure_alignment;
|
|
|
|
} GfxMod;
|
|
|
|
|
|
|
|
#ifdef NON_EQUIVALENT
|
|
|
|
void UCodeDisas_Disassemble(UCodeDisas* this, u32 ptr) {
|
|
|
|
GfxMod* gfx; // 0x394 -> s5
|
|
|
|
u32 exit; // 0x378 -> 0x308
|
|
|
|
u32 addr;
|
|
|
|
s32 i0;
|
|
|
|
u32 rdpHalf; // 0x384 -> 0x2FC
|
|
|
|
u16 linkDlLow;
|
|
|
|
u8 sid;
|
|
|
|
GfxMod curGfx; // 0x370 -> 0x2F0 (pointer to it in s8)
|
|
|
|
u8 cmd; // s1
|
|
|
|
|
|
|
|
gfx = ptr;
|
|
|
|
exit = false;
|
|
|
|
|
|
|
|
while (!exit) {
|
|
|
|
this->dlCnt++;
|
|
|
|
|
|
|
|
gfx = UCodeDisas_TranslateAddr(this, gfx);
|
|
|
|
DISAS_LOG("%08x:", gfx);
|
|
|
|
|
|
|
|
curGfx = *gfx;
|
|
|
|
cmd = curGfx.dma.cmd;
|
|
|
|
addr = UCodeDisas_TranslateAddr(this, curGfx.dma.addr);
|
|
|
|
|
|
|
|
DISAS_LOG("%08x-%08x:", curGfx.words.w0, curGfx.words.w1);
|
|
|
|
|
|
|
|
for (i0 = 0; i0 < this->dlDepth; i0++) {
|
|
|
|
DISAS_LOG(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 848
|
|
|
|
switch (cmd) {
|
|
|
|
case G_SPNOOP: {
|
|
|
|
// 850
|
|
|
|
DISAS_LOG("gsSPNoOp(),");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_DL: {
|
|
|
|
// 878
|
|
|
|
Gdma dma = gfx->dma;
|
|
|
|
switch (dma.par) // minor reordering (branch instruction)
|
|
|
|
{
|
|
|
|
case 0: {
|
|
|
|
// 8B0
|
|
|
|
DISAS_LOG("gsSPDisplayList(0x%08x),", dma.addr);
|
|
|
|
this->dlStack[this->dlDepth++] = gfx + 1;
|
|
|
|
gfx = (GfxMod*)addr - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: {
|
|
|
|
// 900
|
|
|
|
DISAS_LOG("gsSPBranchList(0x%08x),", dma.addr);
|
|
|
|
gfx = (GfxMod*)addr - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPHALF_1: {
|
|
|
|
// 928
|
|
|
|
DISAS_LOG("RDPHALF_1(0x%08x),", curGfx.dma.addr);
|
|
|
|
rdpHalf = curGfx.dma.addr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TEXRECT: // small reordering
|
|
|
|
{
|
|
|
|
// 94C
|
|
|
|
Gtexrect rect = *(Gtexrect*)gfx;
|
|
|
|
DISAS_LOG("gsSPTextureRectangle(%d,%d,%d,%d,%d,%d,%d,%d,%d),", rect.xh, rect.yh, rect.xl, rect.yl,
|
|
|
|
rect.tile, gfx[1].words.w1 >> 16, gfx[1].words.w1 & 0xFFFF, gfx[2].words.w1 >> 16,
|
|
|
|
gfx[2].words.w1 & 0xFFFF);
|
|
|
|
|
|
|
|
gfx += 3 - 1;
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_LOAD_UCODE: // len loaded from sp+2F2 instead of s8+2
|
|
|
|
{
|
|
|
|
// A08
|
|
|
|
u16 len = curGfx.dma.len;
|
|
|
|
if (len == 0x7FF) {
|
|
|
|
// A1C
|
|
|
|
DISAS_LOG("gsSPLoadUcode(0x%08x, 0x%08x),", curGfx.dma.addr, rdpHalf);
|
|
|
|
} else {
|
|
|
|
// A3C
|
|
|
|
DISAS_LOG("gsSPLoadUcodeEx(0x%08x, 0x%08x, 0x%05x),", curGfx.dma.addr, rdpHalf, len + 1);
|
|
|
|
}
|
|
|
|
// A5C
|
|
|
|
UCodeDisas_SetCurUCodeImpl(this, (void*)UCodeDisas_TranslateAddr(this, curGfx.dma.addr));
|
|
|
|
this->loaducodeCnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_ENDDL: {
|
|
|
|
// A84
|
|
|
|
DISAS_LOG("gsSPEndDisplayList(),");
|
|
|
|
if (this->dlDepth <= 0) {
|
|
|
|
// AA0
|
|
|
|
exit = true;
|
|
|
|
} else {
|
|
|
|
// AB0
|
|
|
|
GfxMod* ret = (GfxMod*)this->dlStack[--this->dlDepth];
|
|
|
|
gfx = ret - 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETTILE: // reordering
|
|
|
|
{
|
|
|
|
// AD4
|
|
|
|
Gsettile settile = gfx->settile;
|
|
|
|
DISAS_LOG("gsDPSetTile(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d),", settile.fmt, settile.siz, settile.line,
|
|
|
|
settile.tmem, settile.tile, settile.palette, (settile.ct << 2) + (settile.mt), settile.maskt,
|
|
|
|
settile.shiftt, (settile.cs << 2) + (settile.ms), settile.masks, settile.shifts);
|
|
|
|
|
|
|
|
if (this->tileSyncRequired) {
|
|
|
|
// BB8
|
|
|
|
DISAS_LOG("### TileSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_LOADTILE: // minor reordering (branch instruction)
|
|
|
|
{
|
|
|
|
// BE0
|
|
|
|
Gloadtile loadtile = gfx->loadtile;
|
|
|
|
DISAS_LOG("gsDPLoadTile(%d,%d,%d,%d,%d),", loadtile.tile, loadtile.sh, loadtile.th, loadtile.sl,
|
|
|
|
loadtile.tl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// starting here, replacing gfx with curGfx breaks everything for some reason
|
|
|
|
case G_LOADBLOCK: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
// C4C
|
|
|
|
Gloadtile loadtile = curGfx.loadtile;
|
|
|
|
DISAS_LOG("gsDPLoadBlock(%d,%d,%d,%d,%d),", loadtile.tile, loadtile.sh, loadtile.th, loadtile.sl,
|
|
|
|
loadtile.tl);
|
|
|
|
if (this->loadSyncRequired) {
|
|
|
|
// CB8
|
|
|
|
DISAS_LOG("### LoadSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
// CDC
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETTILESIZE: // gfx instead of curGfx(?) + minor reordering (branch instruction)
|
|
|
|
{
|
|
|
|
// CE8
|
|
|
|
Gloadtile loadtile = curGfx.loadtile;
|
|
|
|
DISAS_LOG("gsDPSetTileSize(%d,%d,%d,%d,%d),", loadtile.tile, loadtile.sh, loadtile.th, loadtile.sl,
|
|
|
|
loadtile.tl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_LOADTLUT: // gfx instead of curGfx(?) + minor reordering (branch instruction)
|
|
|
|
{
|
|
|
|
// D54
|
|
|
|
Gloadtlut loadtlut = curGfx.loadtlut;
|
|
|
|
DISAS_LOG("gsDPLoadTLUTCmd(%d,%d),", loadtlut.tile, loadtlut.sh >> 2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETCOMBINE: // gfx instead of curGfx(?) + minor reordering (branch instruction)
|
|
|
|
{
|
|
|
|
// DA8
|
|
|
|
GsetcombineMod setcombine = curGfx.setcombine;
|
|
|
|
DISAS_LOG("gsDPSetCombineLERP(%s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s),",
|
|
|
|
UCodeDisas_ParseCombineColor(setcombine.a, 1), UCodeDisas_ParseCombineColor(setcombine.b, 2),
|
|
|
|
UCodeDisas_ParseCombineColor(setcombine.c, 3), UCodeDisas_ParseCombineColor(setcombine.d, 4),
|
|
|
|
|
|
|
|
UCodeDisas_ParseCombineAlpha(setcombine.z, 1), UCodeDisas_ParseCombineAlpha(setcombine.y, 2),
|
|
|
|
UCodeDisas_ParseCombineAlpha(setcombine.x, 3), UCodeDisas_ParseCombineAlpha(setcombine.w, 4),
|
|
|
|
|
|
|
|
UCodeDisas_ParseCombineColor(setcombine.e, 1), UCodeDisas_ParseCombineColor(setcombine.f, 2),
|
|
|
|
UCodeDisas_ParseCombineColor(setcombine.g, 3), UCodeDisas_ParseCombineColor(setcombine.h, 4),
|
|
|
|
|
|
|
|
UCodeDisas_ParseCombineAlpha(setcombine.v, 1), UCodeDisas_ParseCombineAlpha(setcombine.u, 2),
|
|
|
|
UCodeDisas_ParseCombineAlpha(setcombine.t, 3), UCodeDisas_ParseCombineAlpha(setcombine.s, 4));
|
|
|
|
|
|
|
|
// F98
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
// FA8
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETOTHERMODE_H: // small reordering
|
|
|
|
{
|
|
|
|
// FD0
|
|
|
|
static F3dzexSetModeMacro sUCodeDisasModeHMacros[] = {
|
|
|
|
F3DZEX_SETRENDERMACRO("SetAlphaDither", G_MDSFT_ALPHADITHER, 2, G_AD_PATTERN, G_AD_NOTPATTERN,
|
|
|
|
G_AD_NOISE, G_AD_DISABLE),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetColorDither", G_MDSFT_RGBDITHER, 2, G_CD_MAGICSQ, G_CD_BAYER, G_CD_NOISE,
|
|
|
|
-1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetCombineKey", G_MDSFT_COMBKEY, 1, G_CK_NONE, G_CK_KEY, -1, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureConvert", G_MDSFT_TEXTCONV, 3, G_TC_CONV, G_TC_FILTCONV, G_TC_FILT,
|
|
|
|
-1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureFilter", G_MDSFT_TEXTFILT, 2, G_TF_POINT, G_TF_AVERAGE,
|
|
|
|
G_TF_BILERP, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureLUT", G_MDSFT_TEXTLUT, 2, G_TT_NONE, G_TT_RGBA16, G_TT_IA16, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureLOD", G_MDSFT_TEXTLOD, 1, G_TL_TILE, G_TL_LOD, -1, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureDetail", G_MDSFT_TEXTDETAIL, 2, G_TD_CLAMP, G_TD_SHARPEN,
|
|
|
|
G_TD_DETAIL, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTexturePersp", G_MDSFT_TEXTPERSP, 1, G_TP_PERSP, G_TP_NONE, -1, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetCycleType", G_MDSFT_CYCLETYPE, 2, G_CYC_1CYCLE, G_CYC_2CYCLE, G_CYC_COPY,
|
|
|
|
G_CYC_FILL),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetColorDither", G_MDSFT_COLORDITHER, 2, G_CD_MAGICSQ, G_CD_BAYER,
|
|
|
|
G_CD_NOISE, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("PipelineMode", G_MDSFT_PIPELINE, 1, G_PM_1PRIMITIVE, G_PM_NPRIMITIVE, -1,
|
|
|
|
-1),
|
|
|
|
};
|
|
|
|
|
|
|
|
u32 len = curGfx.setothermode.len + 1;
|
|
|
|
u32 sft = (-curGfx.setothermode.sft - len) + 32;
|
|
|
|
u32 i1;
|
|
|
|
u32 i2;
|
|
|
|
|
|
|
|
for (i1 = 0; i1 < ARRAY_COUNTU(sUCodeDisasModeHMacros); i1++) {
|
|
|
|
// 1004
|
|
|
|
if (sft == sUCodeDisasModeHMacros[i1].shift) {
|
|
|
|
for (i2 = 0; i2 < 4; i2++) {
|
|
|
|
// 102C ?
|
|
|
|
if (curGfx.setothermode.data == sUCodeDisasModeHMacros[i1].values[i2].value) {
|
|
|
|
// 1038
|
|
|
|
DISAS_LOG("gsDP%s(%s),", sUCodeDisasModeHMacros[i1].name,
|
|
|
|
sUCodeDisasModeHMacros[i1].values[i2].name);
|
|
|
|
goto block_1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 1078
|
|
|
|
DISAS_LOG("gsSPSetOtherModeH(%d, %d, 0x%08x),", sft, len, curGfx.setothermode.data);
|
|
|
|
block_1:
|
|
|
|
// 1098
|
|
|
|
this->modeH &= (((1 - (1 << len)) << sft) - 1);
|
|
|
|
this->modeH |= curGfx.setothermode.data;
|
|
|
|
|
|
|
|
// 10C0
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETOTHERMODE_L: // small reordering + (i1 != 2) instead of (i1 < 2)
|
|
|
|
{
|
|
|
|
// 10F0
|
|
|
|
static F3dzexSetModeMacro sUCodeDisasModeLMacros[] = {
|
|
|
|
F3DZEX_SETRENDERMACRO("gsDPSetAlphaCompare", G_MDSFT_ALPHACOMPARE, 2, G_AC_NONE, G_AC_THRESHOLD,
|
|
|
|
G_AC_DITHER, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("gsDPSetDepthSource", G_MDSFT_ZSRCSEL, 1, G_ZS_PIXEL, G_ZS_PRIM, -1, -1),
|
|
|
|
};
|
|
|
|
|
|
|
|
u32 len = curGfx.setothermode.len + 1;
|
|
|
|
u32 sft = (-curGfx.setothermode.sft - len) + 32;
|
|
|
|
u32 i1;
|
|
|
|
u32 i2;
|
|
|
|
|
|
|
|
// 1114
|
|
|
|
if (sft == G_MDSFT_RENDERMODE) {
|
|
|
|
// 111C
|
|
|
|
DISAS_LOG("\ngsDPSetRenderBlender(");
|
|
|
|
UCodeDisas_ParseRenderMode(this, curGfx.setothermode.data);
|
|
|
|
DISAS_LOG("\n),");
|
|
|
|
} else {
|
|
|
|
// 1154
|
|
|
|
// checks (i1 != 2) instead of (i1 < 2) for some reason (this does not happen above)
|
|
|
|
for (i1 = 0; i1 < ARRAY_COUNTU(sUCodeDisasModeLMacros); i1++) {
|
|
|
|
if (sft == sUCodeDisasModeLMacros[i1].shift) {
|
|
|
|
for (i2 = 0; i2 < 4; i2++) {
|
|
|
|
if (curGfx.setothermode.data == sUCodeDisasModeLMacros[i1].values[i2].value) {
|
|
|
|
// 1198
|
|
|
|
DISAS_LOG("gsDP%s(%s),", sUCodeDisasModeLMacros[i1].name,
|
|
|
|
sUCodeDisasModeLMacros[i1].values[i2].name);
|
|
|
|
goto block_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 11D8
|
|
|
|
DISAS_LOG("gsSPSetOtherModeL(%d, %d, 0x%08x),", sft, len, curGfx.setothermode.data);
|
|
|
|
}
|
|
|
|
block_2:
|
|
|
|
// 11F4
|
|
|
|
this->modeL &= (((1 - (1 << len)) << sft) - 1);
|
|
|
|
this->modeL |= curGfx.setothermode.data;
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPSETOTHERMODE: {
|
|
|
|
// 1250
|
|
|
|
DISAS_LOG("gsDPSetOtherMode(0x%08x, 0x%08x),", curGfx.words.w0 & 0xFFFFFF, curGfx.words.w1);
|
|
|
|
this->modeH = curGfx.words.w0 & 0xFFF;
|
|
|
|
this->modeL = curGfx.words.w1;
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETSCISSOR: // gfx instead of curGfx(?) + reordering
|
|
|
|
{
|
|
|
|
// 12C0
|
|
|
|
Gfillrect setscissor = curGfx.fillrect;
|
|
|
|
const char* modeStr;
|
|
|
|
|
|
|
|
modeStr = (setscissor.pad == G_SC_NON_INTERLACE)
|
|
|
|
? "G_SC_NON_INTERLACE"
|
|
|
|
: (setscissor.pad == G_SC_ODD_INTERLACE)
|
|
|
|
? "G_SC_ODD_INTERLACE"
|
|
|
|
: (setscissor.pad == G_SC_EVEN_INTERLACE) ? "G_SC_EVEN_INTERLACE" : "???";
|
|
|
|
if ((setscissor.x0frac | setscissor.y0frac | setscissor.x1frac | setscissor.y1frac)) {
|
|
|
|
// 1368
|
|
|
|
// reordering here
|
|
|
|
DISAS_LOG("gsDPSetScissorFrac(%s, %d, %d, %d, %d),", modeStr,
|
|
|
|
(setscissor.x0 << 2) + setscissor.x0frac, (setscissor.y0 << 2) + setscissor.y0frac,
|
|
|
|
(setscissor.x1 << 2) + setscissor.x1frac, (setscissor.y1 << 2) + setscissor.y1frac);
|
|
|
|
} else {
|
|
|
|
// 13E8
|
|
|
|
DISAS_LOG("gsDPSetScissor(%s, %d, %d, %d, %d),", modeStr, setscissor.x0, setscissor.y0,
|
|
|
|
setscissor.x1, setscissor.y1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_FILLRECT: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
// 1438
|
|
|
|
Gfillrect fillrect = curGfx.fillrect;
|
|
|
|
|
|
|
|
DISAS_LOG("gsDPFillRectangle(%d, %d, %d, %d),", fillrect.x0, fillrect.y0, fillrect.x1, fillrect.y1);
|
|
|
|
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETCIMG: // reordering
|
|
|
|
{
|
|
|
|
// 14a4
|
|
|
|
u8 fmt = (curGfx.words.w0 & 0xE00000) >> 0x15;
|
|
|
|
u8 siz = (curGfx.words.w0 & 0x180000) >> 0x13;
|
|
|
|
|
|
|
|
DISAS_LOG("gsDPSetColorImage(G_IM_FMT_%s, G_IM_SIZ_%s, %d, 0x%08x(0x%08x) ),",
|
|
|
|
(fmt == G_IM_FMT_RGBA)
|
|
|
|
? "RGBA"
|
|
|
|
: (fmt == G_IM_FMT_YUV) ? "YUV"
|
|
|
|
: (fmt == G_IM_FMT_CI) ? "CI" : (fmt == G_IM_FMT_IA) ? "IA" : "I",
|
|
|
|
(siz == G_IM_SIZ_4b) ? "4b"
|
|
|
|
: (siz == G_IM_SIZ_8b) ? "8b" : (siz == G_IM_SIZ_16b) ? "16b" : "32b",
|
|
|
|
curGfx.setimg.wd + 1, curGfx.setimg.dram, addr);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETZIMG: {
|
|
|
|
// 15E0
|
|
|
|
DISAS_LOG("gsDPSetDepthImage(0x%08x(0x%08x)),", curGfx.words.w1, addr);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETTIMG: // reordering
|
|
|
|
{
|
|
|
|
// 1630
|
|
|
|
u8 fmt = (curGfx.words.w0 & 0xE00000) >> 0x15;
|
|
|
|
u8 siz = (curGfx.words.w0 & 0x180000) >> 0x13;
|
|
|
|
|
|
|
|
DISAS_LOG("gsDPSetTextureImage(G_IM_FMT_%s, G_IM_SIZ_%s, %d, 0x%08x(0x%08x)),",
|
|
|
|
(fmt == G_IM_FMT_RGBA)
|
|
|
|
? "RGBA"
|
|
|
|
: (fmt == G_IM_FMT_YUV) ? "YUV"
|
|
|
|
: (fmt == G_IM_FMT_CI) ? "CI" : (fmt == G_IM_FMT_IA) ? "IA" : "I",
|
|
|
|
(siz == G_IM_SIZ_4b) ? "4b"
|
|
|
|
: (siz == G_IM_SIZ_8b) ? "8b" : (siz == G_IM_SIZ_16b) ? "16b" : "32b",
|
|
|
|
curGfx.setimg.wd + 1, curGfx.setimg.dram, addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETENVCOLOR: // minor reordering
|
|
|
|
{
|
|
|
|
// 1740
|
|
|
|
DISAS_LOG("gsDPSetEnvColor(%d, %d, %d, %d),", curGfx.setcolor.r, curGfx.setcolor.g, curGfx.setcolor.b,
|
|
|
|
curGfx.setcolor.a);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETBLENDCOLOR: // minor reordering
|
|
|
|
{
|
|
|
|
// 17A0
|
|
|
|
DISAS_LOG("gsDPSetBlendColor(%d, %d, %d, %d),", curGfx.setcolor.r, curGfx.setcolor.g, curGfx.setcolor.b,
|
|
|
|
curGfx.setcolor.a);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETFOGCOLOR: // minor reordering
|
|
|
|
{
|
|
|
|
// 1800
|
|
|
|
DISAS_LOG("gsDPSetFogColor(%d, %d, %d, %d),", curGfx.setcolor.r, curGfx.setcolor.g, curGfx.setcolor.b,
|
|
|
|
curGfx.setcolor.a);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETFILLCOLOR: {
|
|
|
|
// 1860
|
|
|
|
DISAS_LOG("gsDPSetFillColor(0x%08x),", curGfx.words.w1);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETPRIMDEPTH: {
|
|
|
|
// 18AC
|
|
|
|
DISAS_LOG("gsDPSetPrimDepth(%d, %d),", curGfx.setprimdepth.z, curGfx.setprimdepth.d);
|
|
|
|
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SETPRIMCOLOR: // reordering
|
|
|
|
{
|
|
|
|
// 18FC
|
|
|
|
DISAS_LOG("gsDPSetPrimColor(%d, %d, %d, %d, %d, %d),", curGfx.setcolor.prim_min_level,
|
|
|
|
curGfx.setcolor.prim_level, curGfx.setcolor.r, curGfx.setcolor.g, curGfx.setcolor.b,
|
|
|
|
curGfx.setcolor.a);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPFULLSYNC: {
|
|
|
|
// 1940
|
|
|
|
DISAS_LOG("gsDPFullSync(),");
|
|
|
|
if (this->pipeSyncRequired) {
|
|
|
|
DISAS_LOG("### PipeSyncが必要です。\n");
|
|
|
|
this->syncErr++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPTILESYNC: {
|
|
|
|
// 1988
|
|
|
|
DISAS_LOG("gsDPTileSync(),");
|
|
|
|
this->tileSyncRequired = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPPIPESYNC: {
|
|
|
|
// 19A8
|
|
|
|
DISAS_LOG("gsDPPipeSync(),");
|
|
|
|
this->pipeSyncRequired = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPLOADSYNC: {
|
|
|
|
// 19C8
|
|
|
|
DISAS_LOG("gsDPLoadSync(),");
|
|
|
|
this->loadSyncRequired = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_NOOP: {
|
|
|
|
// 19E8
|
|
|
|
switch (curGfx.noop.type) {
|
|
|
|
case 0: // curGfx.noop.value.u32 should be reused
|
|
|
|
{
|
|
|
|
// 1A10
|
|
|
|
if (curGfx.noop.value.u32 == 0) {
|
|
|
|
DISAS_LOG("gsDPNoOp(),");
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsDPNoOpTag(%08x),", curGfx.noop.value.u32);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: {
|
|
|
|
// 1A4C
|
|
|
|
DISAS_LOG("count_gsDPNoOpHere([%s:%d]),", curGfx.noop.value.u32, curGfx.dma.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 7: {
|
|
|
|
// 1A6C
|
|
|
|
DISAS_LOG("count_gsDPNoOpOpenDisp([%s:%d]),", curGfx.noop.value.u32, curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 8: {
|
|
|
|
// 1A8C
|
|
|
|
DISAS_LOG("count_gsDPNoOpCloseDisp([%s:%d]),", curGfx.noop.value.u32, curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: // minor reordering
|
|
|
|
{
|
|
|
|
// 1AAC
|
|
|
|
DISAS_LOG("count_gsDPNoOpString(%c%s%c, %d),", '"', curGfx.noop.value.u32, '"',
|
|
|
|
curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 3: {
|
|
|
|
// 1AD8
|
|
|
|
DISAS_LOG("count_gsDPNoOpWord(0x%08x, %d),", curGfx.noop.value.u32, curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 4: {
|
|
|
|
// 1AFC
|
|
|
|
DISAS_LOG("count_gsDPNoOpFloat(%8.3f, %d),", curGfx.noop.value.f32, curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 5: // missing a move
|
|
|
|
{
|
|
|
|
// 1B30
|
|
|
|
if (curGfx.noop.len == 0) {
|
|
|
|
DISAS_LOG("count_gsDPNoOpQuiet(),");
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("count_gsDPNoOpVerbose(),");
|
|
|
|
}
|
|
|
|
this->enableLog = curGfx.noop.len;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 6: {
|
|
|
|
// 1B74
|
|
|
|
/*! @bug arguments are not printed */
|
|
|
|
DISAS_LOG("count_gsDPNoOpCallBack(%08x,%d),");
|
|
|
|
((void (*)(UCodeDisas*, u32))curGfx.noop.value.u32)(this, curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: // curGfx.noop.type seems reused
|
|
|
|
{
|
|
|
|
// 1BA0
|
|
|
|
DISAS_LOG("gsDPNoOpTag3(%02x, %08x, %04x),", curGfx.noop.type, curGfx.noop.value.u32,
|
|
|
|
curGfx.noop.len);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
// 1BBC
|
|
|
|
// there's a problem here
|
|
|
|
switch (this->ucodeType) {
|
|
|
|
case UCODE_F3DZEX:
|
|
|
|
case UCODE_UNK: {
|
|
|
|
// 1BE8
|
|
|
|
switch (curGfx.dma.cmd) // which one to choose here?
|
|
|
|
{
|
|
|
|
case G_MTX: // gfx instead of curGfx(?) + lbu -> lb + reordering
|
|
|
|
{
|
|
|
|
// 1C3C
|
|
|
|
Gmatrix gmtx = curGfx.matrix;
|
|
|
|
MtxF mtx;
|
|
|
|
MatrixInternal* mtxp = (MatrixInternal*)addr;
|
|
|
|
s32 i1;
|
|
|
|
u32 params;
|
|
|
|
DISAS_LOG("gsSPMatrix(0x%08x(%08x), 0", gmtx.addr, addr);
|
|
|
|
|
|
|
|
params = (gmtx.params ^ G_MTX_PUSH);
|
|
|
|
|
|
|
|
for (i1 = 0; i1 < ARRAY_COUNT(sUCodeDisasMtxFlags); i1++) {
|
|
|
|
DISAS_LOG("|%s", (sUCodeDisasMtxFlags[i1].value & params)
|
|
|
|
? sUCodeDisasMtxFlags[i1].setName
|
|
|
|
: sUCodeDisasMtxFlags[i1].unsetName);
|
|
|
|
}
|
|
|
|
DISAS_LOG("),", gmtx.addr); /*! @bug gmtx.addr shouldn't be here*/
|
|
|
|
|
|
|
|
if (this->enableLog >= 2) {
|
|
|
|
MtxConv_L2F(&mtx, mtxp);
|
|
|
|
DISAS_LOG("\n");
|
|
|
|
/*! @bug %.04x.%04x is a typo, should be %04x.%04x */
|
|
|
|
DISAS_LOG(
|
|
|
|
"/ %04x.%04x %04x.%04x %04x.%04x %.04x.%04x \\/ %12.6f %12.6f %12.6f %12.6f "
|
|
|
|
"\\\n"
|
|
|
|
"| %04x.%04x %04x.%04x %04x.%04x %.04x.%04x || %12.6f %12.6f %12.6f %12.6f |\n"
|
|
|
|
"| %04x.%04x %04x.%04x %04x.%04x %.04x.%04x || %12.6f %12.6f %12.6f %12.6f |\n"
|
|
|
|
"\\ %04x.%04x %04x.%04x %04x.%04x %.04x.%04x /\\ %12.6f %12.6f %12.6f %12.6f "
|
|
|
|
"/\n",
|
|
|
|
mtxp->intPart[0][0], mtxp->fracPart[0][0], mtxp->intPart[1][0],
|
|
|
|
mtxp->fracPart[1][0], mtxp->intPart[2][0], mtxp->fracPart[2][0],
|
|
|
|
mtxp->intPart[3][0], mtxp->fracPart[3][0], mtx.mf[0][0], mtx.mf[1][0],
|
|
|
|
mtx.mf[2][0], mtx.mf[3][0],
|
|
|
|
|
|
|
|
mtxp->intPart[0][1], mtxp->fracPart[0][1], mtxp->intPart[1][1],
|
|
|
|
mtxp->fracPart[1][1], mtxp->intPart[2][1], mtxp->fracPart[2][1],
|
|
|
|
mtxp->intPart[3][1], mtxp->fracPart[3][1], mtx.mf[0][1], mtx.mf[1][1],
|
|
|
|
mtx.mf[2][1], mtx.mf[3][1],
|
|
|
|
|
|
|
|
mtxp->intPart[0][2], mtxp->fracPart[0][2], mtxp->intPart[1][2],
|
|
|
|
mtxp->fracPart[1][2], mtxp->intPart[2][2], mtxp->fracPart[2][2],
|
|
|
|
mtxp->intPart[3][2], mtxp->fracPart[3][2], mtx.mf[0][2], mtx.mf[1][2],
|
|
|
|
mtx.mf[2][2], mtx.mf[3][2],
|
|
|
|
|
|
|
|
mtxp->intPart[0][3], mtxp->fracPart[0][3], mtxp->intPart[1][3],
|
|
|
|
mtxp->fracPart[1][3], mtxp->intPart[2][3], mtxp->fracPart[2][3],
|
|
|
|
mtxp->intPart[3][3], mtxp->fracPart[3][3], mtx.mf[0][3], mtx.mf[1][3],
|
|
|
|
mtx.mf[2][3], mtx.mf[3][3]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_VTX: {
|
|
|
|
// 1EF4
|
|
|
|
// this is not correct
|
|
|
|
s32 numv = (curGfx.words.w0 >> 12) & 0xFF;
|
|
|
|
s32 vbidx = ((curGfx.words.w0 & 0xFF) >> 1) - numv;
|
|
|
|
DISAS_LOG("gsSPVertex(0x%08x(0x%08x), %d, %d),", curGfx.words.w1, addr, numv, vbidx);
|
|
|
|
|
|
|
|
this->vtxCnt += numv;
|
|
|
|
this->spvtxCnt++;
|
|
|
|
|
|
|
|
if (this->enableLog >= 2) {
|
|
|
|
UCodeDisas_PrintVertices(this, addr, numv, vbidx);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MODIFYVTX: // additional move
|
|
|
|
{
|
|
|
|
// 1F74
|
|
|
|
u16 where = curGfx.dma.len;
|
|
|
|
DISAS_LOG("gsSPModifyVertex(%d, %s, %08x),", curGfx.dma.par,
|
|
|
|
(where == G_MWO_POINT_RGBA)
|
|
|
|
? "G_MWO_POINT_RGBA"
|
|
|
|
: (where == G_MWO_POINT_ST)
|
|
|
|
? "G_MWO_POINT_ST"
|
|
|
|
: (where == G_MWO_POINT_XYSCREEN)
|
|
|
|
? "G_MWO_POINT_XYSCREEN"
|
|
|
|
: (where == G_MWO_POINT_ZSCREEN) ? "G_MWO_POINT_ZSCREEN"
|
|
|
|
: "G_MWO_POINT_????",
|
|
|
|
curGfx.dma.addr);
|
|
|
|
this->vtxCnt += curGfx.dma.par;
|
|
|
|
this->spvtxCnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TRI1: // a Gtri1 struct should probably be used here + code missing
|
|
|
|
{
|
|
|
|
// 2024
|
|
|
|
Gwords words2 = curGfx.words;
|
|
|
|
DISAS_LOG("gsSP1Triangle(%d, %d, %d),", ((words2.w0 >> 16) & 0xFF) / 2,
|
|
|
|
((words2.w0 >> 8) & 0xFF) / 2, ((words2.w0 >> 0) & 0xFF) / 2);
|
|
|
|
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
this->tri1Cnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_LINE3D: // curGfx should be used here(?)
|
|
|
|
{
|
|
|
|
// 20BC
|
|
|
|
Gline3DFix* line = (Gline3DFix*)&curGfx;
|
|
|
|
if (line->wd == 0) {
|
|
|
|
DISAS_LOG("gsSPLine3D(%d, %d),", line->v0, line->v1);
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsSPLineW3D(%d, %d, %d),", line->v0, line->v1, line->wd);
|
|
|
|
}
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
this->lineCnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TRI2: // gfx instead of curGfx(?) + a Gtri2 struct should probably be used here +
|
|
|
|
// code missing
|
|
|
|
{
|
|
|
|
Gwords words2 = curGfx.words;
|
|
|
|
DISAS_LOG("gsSP2Triangles(%d, %d, %d, 0, %d, %d, %d, 0),",
|
|
|
|
((words2.w0 >> 16) & 0xFF) / 2, ((words2.w0 >> 8) & 0xFF) / 2,
|
|
|
|
((words2.w0 >> 0) & 0xFF) / 2, ((words2.w1 >> 16) & 0xFF) / 2,
|
|
|
|
((words2.w1 >> 8) & 0xFF) / 2, ((words2.w1 >> 0) & 0xFF) / 2);
|
|
|
|
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
this->tri2Cnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_QUAD: // gfx instead of curGfx(?) + a Gquad struct should probably be used here +
|
|
|
|
// code missing
|
|
|
|
{
|
|
|
|
Gwords words2 = curGfx.words;
|
|
|
|
DISAS_LOG("gsSP1Quadrangle(%d, %d, %d, %d, 0),", ((words2.w0 >> 16) & 0xFF) / 2,
|
|
|
|
((words2.w0 >> 8) & 0xFF) / 2, ((words2.w0 >> 0) & 0xFF) / 2,
|
|
|
|
((words2.w1 >> 0) & 0xFF) / 2);
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
this->quadCnt++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_CULLDL: // code missing
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPCullDisplayList(%d, %d),", (curGfx.words.w0 & 0xFFFF) / 2,
|
|
|
|
(curGfx.words.w1 & 0xFFFF) / 2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_BRANCH_Z: {
|
|
|
|
GfxMod* dst = UCodeDisas_TranslateAddr(this, rdpHalf);
|
|
|
|
DISAS_LOG("gsSPBranchLessZraw(0x%08x(0x%08x), %d, 0x%08x),", rdpHalf, dst,
|
|
|
|
(curGfx.words.w0 & 0xFFF) / 2, curGfx.words.w1);
|
|
|
|
gfx = dst - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TEXTURE: // gfx instead of curGfx(?) + reordering + arithmetic issue?
|
|
|
|
{
|
|
|
|
Gtexture texture = curGfx.texture;
|
|
|
|
if (texture.lodscale == 0) {
|
|
|
|
DISAS_LOG("gsSPTexture(%d, %d, %d, %d, %s),", texture.s, texture.t,
|
|
|
|
texture.tile >> 3, texture.tile & 7, texture.on ? "G_ON" : "G_OFF");
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsSPTextureL(%d, %d, %d, %d, %d, %s),", texture.s, texture.t,
|
|
|
|
texture.tile >> 3, texture.lodscale, texture.tile & 7,
|
|
|
|
texture.on ? "G_ON" : "G_OFF");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_POPMTX: // gfx instead of curGfx(?) + reordering
|
|
|
|
{
|
|
|
|
Gwords words2 = curGfx.words;
|
|
|
|
s32 num = words2.w1 / 64;
|
|
|
|
if (num == 1) {
|
|
|
|
DISAS_LOG("gsSPPopMatrix(G_MTX_MODELVIEW),");
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsSPPopMatrixN(G_MTX_MODELVIEW, %d),", num);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_GEOMETRYMODE: {
|
|
|
|
u32 clearbits = curGfx.words.w0 & 0xFFFFFF;
|
|
|
|
u32 setbits = curGfx.words.w1 & 0xFFFFFF; // ?? setbits should be 32bit
|
|
|
|
|
|
|
|
if (clearbits == 0) {
|
|
|
|
DISAS_LOG("gsSPLoadGeometryMode(");
|
|
|
|
UCodeDisas_ParseGeometryMode(this, setbits);
|
|
|
|
DISAS_LOG("),");
|
|
|
|
} else {
|
|
|
|
if (setbits == 0) {
|
|
|
|
DISAS_LOG("gsSPClearGeometryMode(");
|
|
|
|
UCodeDisas_ParseGeometryMode(this, ~clearbits);
|
|
|
|
DISAS_LOG("),");
|
|
|
|
} else {
|
|
|
|
if (clearbits == 0xFFFFFF) {
|
|
|
|
DISAS_LOG("gsSPSetGeometryMode(");
|
|
|
|
UCodeDisas_ParseGeometryMode(this, setbits);
|
|
|
|
DISAS_LOG("),");
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsSPGeometryMode(");
|
|
|
|
UCodeDisas_ParseGeometryMode(this, ~clearbits);
|
|
|
|
DISAS_LOG(",");
|
|
|
|
UCodeDisas_ParseGeometryMode(this, setbits);
|
|
|
|
DISAS_LOG("),");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this->geometryMode &= clearbits;
|
|
|
|
this->geometryMode |= setbits;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MOVEWORD: // gfx instead of curGfx(?) + missing code + missing copy
|
|
|
|
{
|
|
|
|
Gdma dma = curGfx.dma; // Gsegment ?
|
|
|
|
switch (dma.par) {
|
|
|
|
case G_MW_SEGMENT: {
|
|
|
|
DISAS_LOG("gsSPSegment(%d, 0x%08x),", dma.len, dma.addr / 4);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MW_CLIP: {
|
|
|
|
DISAS_LOG("gsSPClipRatio(FRUSTRATIO_%d), ",
|
|
|
|
(dma.addr != 0) ? dma.addr : -dma.addr);
|
|
|
|
gfx += 4 - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MW_NUMLIGHT: {
|
|
|
|
DISAS_LOG("gsSPNumLights(%d), ", dma.addr / 24);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MW_LIGHTCOL: {
|
|
|
|
DISAS_LOG("gsSPLightColor(%d, %d), ", ((dma.addr & 0xF0) >> 5) + 1, dma.addr);
|
|
|
|
break;
|
|
|
|
gfx += 2 - 1;
|
|
|
|
}
|
|
|
|
case G_MW_FOG: {
|
|
|
|
DISAS_LOG("gsSPFogFactor(%d, %d),", dma.addr >> 16, dma.addr & 0xFFFF);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MW_PERSPNORM: {
|
|
|
|
DISAS_LOG("gsSPPerspNormalize(%d),", dma.addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
DISAS_LOG("gsMoveWd(%d, %d, %d), ", dma.par, dma.len, dma.addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MOVEMEM: // gfx instead of curGfx(?) + code is wrong
|
|
|
|
{
|
|
|
|
Gwords words2 = curGfx.words;
|
|
|
|
s32 offset = (words2.w0 >> 8) & 0xFF;
|
|
|
|
s32 size = (((words2.w0 >> 16) >> 3) + 1) * 8;
|
|
|
|
s32 index = words2.w0 & 0xFF;
|
|
|
|
Vp_t* vp = (Vp_t*)addr;
|
|
|
|
|
|
|
|
switch (index) {
|
|
|
|
case G_MV_VIEWPORT: {
|
|
|
|
DISAS_LOG("gsSPViewport(0x%08x(0x%08x)),", words2.w1, vp);
|
|
|
|
DISAS_LOG("\t# vscale=[%d %d %d %d], ", vp->vscale[0], vp->vscale[1],
|
|
|
|
vp->vscale[2], vp->vscale[3]);
|
|
|
|
DISAS_LOG("vtrans=[%d %d %d %d] ", vp->vtrans[0], vp->vtrans[1], vp->vtrans[2],
|
|
|
|
vp->vtrans[3]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MV_MATRIX: {
|
|
|
|
DISAS_LOG("gsSPForceMatrix(0x%08x),", words2.w1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MV_LIGHT: {
|
|
|
|
switch ((offset * 8)) {
|
|
|
|
case G_MVO_LOOKATX: {
|
|
|
|
DISAS_LOG("gsSPLookAtX(0x%08x),", words2.w1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_MVO_LOOKATY: {
|
|
|
|
DISAS_LOG("gsSPLookAtY(0x%08x),", words2.w1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
DISAS_LOG("gsSPLight(0x%08x,%d),", words2.w1, (offset * 8 - 24) / 24);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
DISAS_LOG("gsMoveMem(0x%08x, %d, %d, %d),", words2.w1, size, index, offset * 8);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
DISAS_LOG("AnyDisplayList(),");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case UCODE_S2DEX: {
|
|
|
|
// 29FC?
|
|
|
|
switch (curGfx.dma.cmd) // which one to choose here?
|
|
|
|
{
|
|
|
|
case G_BG_COPY: // gfx instead of curGfx(?) + missing copy
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPBgRectCopy(0x%08x(0x%08x)),", curGfx.words.w1, addr);
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_BG_1CYC: // gfx instead of curGfx(?) + missing copy
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPBgRect1Cyc(0x%08x(0x%08x)),", curGfx.words.w1, addr);
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_SPRITE: // gfx instead of curGfx(?) + missing copy
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjSprite(0x%08x(0x%08x)),", curGfx.words.w1, addr);
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_RECTANGLE: // gfx instead of curGfx(?) + missing copy
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjRectangle(0x%08x(0x%08x)),", curGfx.words.w1, addr);
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_RECTANGLE_R: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjRectangleR(0x%08x(0x%08x)),", curGfx.words.w1, addr);
|
|
|
|
this->pipeSyncRequired = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_RDPHALF_0: {
|
|
|
|
DISAS_LOG("RDPHALF_0(0x%02x, 0x%08x, 0x%04x),", curGfx.dma.par, curGfx.dma.addr,
|
|
|
|
curGfx.dma.len);
|
|
|
|
sid = curGfx.dma.par;
|
|
|
|
rdpHalf = curGfx.dma.addr;
|
|
|
|
linkDlLow = curGfx.dma.len;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_MOVEMEM: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
Gdma dma = curGfx.dma;
|
|
|
|
if (dma.par == 23) {
|
|
|
|
DISAS_LOG("gsSPObjMatrix(0x%08x(0x%08x)),", dma.addr, addr);
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsSPObjSubMatrix(0x%08x(0x%08x)),", dma.addr, addr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_LOADTXTR: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjLoadTxtr(0x%08x(0x%08x)),", curGfx.dma.addr, addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_LDTX_SPRITE: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjLoadTxSprite(0x%08x(0x%08x)),", curGfx.dma.addr, addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_LDTX_RECT: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjLoadTxRect(0x%08x(0x%08x)),", curGfx.dma.addr, addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_LDTX_RECT_R: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjLoadTxRectR(0x%08x(0x%08x)),", curGfx.dma.addr, addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_SELECT_DL: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
Gdma dma = curGfx.dma;
|
|
|
|
u32 dlAddr = UCodeDisas_TranslateAddr(this, (linkDlLow << 16) | dma.len);
|
|
|
|
if (dma.par == 0) {
|
|
|
|
DISAS_LOG("gsSPSelectDL(0x%08x, %d, 0x%08x, 0x%08x),", dlAddr, sid, rdpHalf,
|
|
|
|
dma.addr);
|
|
|
|
} else {
|
|
|
|
DISAS_LOG("gsSPSelectBranchDL(0x%08x, %d, 0x%08x, 0x%08x),", dlAddr, sid, rdpHalf,
|
|
|
|
dma.addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 0xDB: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
Gdma dma = curGfx.dma;
|
|
|
|
switch (dma.par) {
|
|
|
|
case 6: {
|
|
|
|
u32 segId = dma.len / 2;
|
|
|
|
DISAS_LOG("gsSPSegment(%d, 0x%08x),", segId, dma.addr);
|
|
|
|
this->segments[segId] = dma.addr & 0xFFFFFF;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 8: {
|
|
|
|
DISAS_LOG("gsSPSetStatus(0x%08x, 0x%08x),", dma.len, dma.addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
DISAS_LOG("gsMoveWd(%d, %d, %d), ", dma, dma.len, dma.addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_OBJ_RENDERMODE: // gfx instead of curGfx(?)
|
|
|
|
{
|
|
|
|
DISAS_LOG("gsSPObjRenderMode(0x%08x),", curGfx.dma.addr);
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
DISAS_LOG("AnyDisplayList(),");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DISAS_LOG("\n");
|
|
|
|
|
|
|
|
gfx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2020-06-05 17:18:39 +00:00
|
|
|
void UCodeDisas_Disassemble(UCodeDisas* this, Gfx* gfx0);
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/ucode_disas/UCodeDisas_Disassemble.rodata.s")
|
|
|
|
F3dzexSetModeMacro sUCodeDisasModeHMacros[] = {
|
|
|
|
F3DZEX_SETRENDERMACRO("SetAlphaDither", G_MDSFT_ALPHADITHER, 2, G_AD_PATTERN, G_AD_NOTPATTERN, G_AD_NOISE,
|
|
|
|
G_AD_DISABLE),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetColorDither", G_MDSFT_RGBDITHER, 2, G_CD_MAGICSQ, G_CD_BAYER, G_CD_NOISE, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetCombineKey", G_MDSFT_COMBKEY, 1, G_CK_NONE, G_CK_KEY, -1, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureConvert", G_MDSFT_TEXTCONV, 3, G_TC_CONV, G_TC_FILTCONV, G_TC_FILT, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureFilter", G_MDSFT_TEXTFILT, 2, G_TF_POINT, G_TF_AVERAGE, G_TF_BILERP, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureLUT", G_MDSFT_TEXTLUT, 2, G_TT_NONE, G_TT_RGBA16, G_TT_IA16, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureLOD", G_MDSFT_TEXTLOD, 1, G_TL_TILE, G_TL_LOD, -1, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTextureDetail", G_MDSFT_TEXTDETAIL, 2, G_TD_CLAMP, G_TD_SHARPEN, G_TD_DETAIL, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetTexturePersp", G_MDSFT_TEXTPERSP, 1, G_TP_PERSP, G_TP_NONE, -1, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetCycleType", G_MDSFT_CYCLETYPE, 2, G_CYC_1CYCLE, G_CYC_2CYCLE, G_CYC_COPY, G_CYC_FILL),
|
|
|
|
F3DZEX_SETRENDERMACRO("SetColorDither", G_MDSFT_COLORDITHER, 2, G_CD_MAGICSQ, G_CD_BAYER, G_CD_NOISE, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("PipelineMode", G_MDSFT_PIPELINE, 1, G_PM_1PRIMITIVE, G_PM_NPRIMITIVE, -1, -1),
|
|
|
|
};
|
|
|
|
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/ucode_disas/UCodeDisas_Disassemble.rodata2.s")
|
|
|
|
F3dzexSetModeMacro sUCodeDisasModeLMacros[] = {
|
|
|
|
F3DZEX_SETRENDERMACRO("gsDPSetAlphaCompare", G_MDSFT_ALPHACOMPARE, 2, G_AC_NONE, G_AC_THRESHOLD, G_AC_DITHER, -1),
|
|
|
|
F3DZEX_SETRENDERMACRO("gsDPSetDepthSource", G_MDSFT_ZSRCSEL, 1, G_ZS_PIXEL, G_ZS_PRIM, -1, -1),
|
|
|
|
};
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/ucode_disas/UCodeDisas_Disassemble.s")
|
2021-10-31 20:39:29 +00:00
|
|
|
#endif
|
2020-06-05 17:18:39 +00:00
|
|
|
|
|
|
|
void UCodeDisas_RegisterUCode(UCodeDisas* this, s32 count, UCodeInfo* ucodeArray) {
|
|
|
|
this->ucodeInfoCount = count;
|
|
|
|
this->ucodeInfo = ucodeArray;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UCodeDisas_SetCurUCode(UCodeDisas* this, void* ptr) {
|
|
|
|
UCodeDisas_SetCurUCodeImpl(this, ptr);
|
|
|
|
}
|
2021-08-31 22:53:35 +00:00
|
|
|
|
|
|
|
// 4 bytes of nops, separating this file from audio_synthesis and padding .text
|
|
|
|
// to a 32-byte boundary. Unclear what this comes from... maybe the audio
|
|
|
|
// library was built separately and aligned to 32 bytes?
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/ucode_disas/pad_800DACB0.s")
|