// RAP TA command surface, decompiled with restored names, prototypes and types. // Source: psp_out/versions_win/ta_7-0-2-19_f368676e.bin // Handlers resolved from fw/cmdmaps/rap.json; loc_* labels mapped to their // containing function. Generated by fw/ta_surface.py. // ================ cmd 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 @ 0x40160c ================ int __fastcall rap_cmd02(void *ctx, struct ta_params *params) { _DWORD *v2; // r3 char *v3; // r7 _DWORD *v5; // r9 int v6; // r0 int v7; // r5 int v8; // r0 int v9; // r6 int v10; // r5 int *v11; // r4 int v12; // r1 int v13; // r2 int v14; // r3 int v15; // r0 int v16; // r0 int v17; // r1 int v18; // r3 int v19; // r4 int v20; // r7 int v22; // [sp+0h] [bp-34h] BYREF _DWORD v23[12]; // [sp+4h] [bp-30h] BYREF int *v24; // [sp+50h] [bp+1Ch] int v25; // [sp+54h] [bp+20h] int *v26; // [sp+58h] [bp+24h] v3 = off_4016F4[0]; if ( *off_4016F4[0] == 0 ) return *off_4016F8; if ( params != (struct ta_params *)1 ) return 4; v5 = v2; ((void (__fastcall *)(_DWORD *, int))loc_401000)(a1: v23, a2: 48); v22 = 1; rap_sysdrv_rpc_1076(a1: (int)&v22); v22 = 10; v6 = rap_sysdrv_rpc_1076(a1: (int)&v22); *v26 = v6; if ( v6 == 0 ) { v23[1] = 1; v22 = (int)ctx; if ( ctx == (void *)5 ) { v8 = rap_sysdrv_rpc_1076(a1: (int)&v22); v7 = 11; *v26 = v8; if ( v8 == 0 ) v7 = 1; v9 = 0; } else { v10 = v25; if ( v25 == 0 ) { v7 = 9; *v26 = dword_4016FC; LABEL_26: v22 = 11; rap_sysdrv_rpc_1076(a1: (int)&v22); return v7; } v11 = v24; v12 = *((_DWORD *)v3 + 12); v13 = *((_DWORD *)v3 + 13); v14 = *((_DWORD *)v3 + 14); v23[2] = *((_DWORD *)v3 + 6); v23[3] = v12; v23[4] = v13; v23[5] = v14; v9 = 0; while ( 1 ) { if ( v10 == 0 ) { v7 = 1; goto LABEL_20; } v9 = *v11; if ( *v11 != 0 ) { v23[0] = *v11; v15 = rap_sysdrv_rpc_1076(a1: (int)&v22); *v26 = v15; if ( v15 != 0 ) break; } --v10; ++v11; } v7 = 11; } LABEL_20: rap_sysdrv_rpc_107B(a1: (int)&v22); v16 = v23[6]; v17 = v23[7]; v18 = v23[8]; v19 = v23[9]; v20 = v23[10]; *v5 = v23[11]; v5[1] = v16; v5[2] = v17; v5[3] = v18; v5[4] = v19; v5[5] = v20; if ( *v26 != 0 ) { if ( *v26 == dword_4016FC ) *v5 = v9; } else if ( v16 != v17 ) { v7 = 7; } goto LABEL_26; } return 11; } // --------------------------------------------------------------- // COMMANDS ENTERED AT AN INTERNAL LABEL, NOT AT A FUNCTION ENTRY. // These dispatch into the middle of a larger function, which is what a // switch-style dispatcher produces. IDA refuses to split them out, and // undefining the owner to force a split was not worth the risk, so the // containing function is reproduced below IN FULL. Read the command's // code at the stated offset -- the function as a whole is NOT the handler. // --------------------------------------------------------------- // cmd 0x1 -> 0x401000 (enters start+0xf00) // ---- containing function start @ 0x400100 (entered mid-body by the commands above) ---- _DWORD *__fastcall start(int a1, int a2, int a3, int a4) { int v4; // r6 char v5; // r7 int v6; // r9 int v7; // r1 int v8; // r5 int v9; // r1 _DWORD *result; // r0 bool v11; // cf unsigned int v12; // r1 _DWORD *v13; // r0 int v14; // r1 int v15; // r1 v7 = a3 >> 30 << 16; v8 = v7 >> 31; *(_BYTE *)((a3 >> 30) + 1) = v5; *(_DWORD *)(v4 + 20) = a3 >> 30; *(_DWORD *)((v7 >> 31) + 0x10) = v4; *(_BYTE *)(v4 + 1) = 0; v9 = v7 + v6; if ( __OFSUB__(v4, 100) ) __udf(0x9Du); *(_DWORD *)(*(_DWORD *)(v8 + 20) + 20) = a4; result = nullptr; MEMORY[0x10] = v9; *(_DWORD *)(v8 + 68) = v8; *(_DWORD *)(v8 + 96) = v4; v11 = false; v12 = -32; do { if ( !v11 ) break; *result = 0; result[1] = 0; result[2] = 0; result[3] = 0; v13 = result + 4; *v13 = 0; v13[1] = 0; v13[2] = 0; v13[3] = 0; result = v13 + 4; v11 = v12 >= 0x20; v12 -= 32; } while ( v11 ); v11 = __CFSHL__(v12, 28); v14 = v12 << 28; if ( v11 ) { *result = 0; result[1] = 0; result[2] = 0; result[3] = 0; result += 4; } if ( v14 < 0 ) { *result = 0; result[1] = 0; result += 2; } v11 = __CFSHL__(v14, 2); v15 = 4 * v14; if ( v11 ) *result++ = 0; if ( v15 != 0 ) { if ( v15 < 0 ) { *(_WORD *)result = 0; result = (_DWORD *)((char *)result + 2); } if ( (v15 & 0x40000000) != 0 ) { *(_BYTE *)result = 0; return (_DWORD *)((char *)result + 1); } } return result; }