mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-07-12 20:31:25 -07:00
Still learning/de-obfuscating
This commit is contained in:
+47
-9
@@ -284,26 +284,64 @@ enum {
|
||||
};
|
||||
|
||||
enum { _C2_OPS_ = 0
|
||||
|
||||
, op_lwc2 = 0x32 /* Load Word to Coprocessor 2 (GTE) */
|
||||
, op_swc2 = 0x3A /* Store Word from Coprocessor 2 (GTE) */
|
||||
};
|
||||
|
||||
/* COP2 (GTE) Transfer Format: ctc2 rt, rd or cfc2 rt, rd
|
||||
/* COP2 transfer sub-opcodes (5-bit field in the `rs` slot of enc_gte_tx).
|
||||
*
|
||||
* Spans the 2x2 {From, To} × {Data, Control} register classes that the
|
||||
* GTE exposes:
|
||||
*
|
||||
* bit 1 (0x02): register class — 0 = data, 1 = control
|
||||
* bit 2 (0x04): direction — 0 = read, 1 = write
|
||||
*
|
||||
* The values 0x00 (sub_mfc2) and 0x04 (sub_mtc2) are the same 5-bit
|
||||
* numbers as the general MIPS `cop_mf` / `cop_mt` defined in mips.h
|
||||
* (which target the data register file on any coprocessor). They are
|
||||
* re-aliased here so the four-way table reads like the spec mnemonics
|
||||
* (MFC2 / CFC2 / MTC2 / CTC2) and so the encoding lives next to its
|
||||
* only consumer (this header).
|
||||
*
|
||||
* Vendor mnemonic aliases (gte_mfc2 / gte_mtc2 / gte_cfc2 / gte_ctc2)
|
||||
* live in gte_vendor_sym.h. */
|
||||
enum { _C2_TX_SUBS_ = 0
|
||||
, sub_mfc2 = 0x00 /* MFC2: Move From Coprocessor 2 data reg */
|
||||
, sub_cfc2 = 0x02 /* CFC2: Copy From Coprocessor 2 ctrl reg */
|
||||
, sub_mtc2 = 0x04 /* MTC2: Move To Coprocessor 2 data reg */
|
||||
, sub_ctc2 = 0x06 /* CTC2: Copy To Coprocessor 2 ctrl reg */
|
||||
};
|
||||
|
||||
/* COP2 (GTE) Transfer Format: mfc2 / cfc2 / mtc2 / ctc2 rt, rd
|
||||
* Layout: [op_cop2:6][sub:5][rt:5][rd:5][0:11]
|
||||
* - sub: cop_mf (0x00) for cfc2, cop_mt (0x04) for ctc2
|
||||
* - sub: one of sub_mfc2 / sub_cfc2 / sub_mtc2 / sub_ctc2
|
||||
* - rt: GPR source/dest
|
||||
* - rd: COP2 control register index (0..31) */
|
||||
* - rd: COP2 register index (0..31):
|
||||
* data class → C2_VXY0_Code..C2_LZCR_Code (gte_in_v0_xy..gte_math_accum2 aliases)
|
||||
* ctrl class → gte_cr_RT11_Code..gte_cr_OFY_Code */
|
||||
#define enc_gte_tx(sub, rt, rd) (enc_op(op_cop2) | enc_rs(sub) | enc_rt(rt) | enc_rd(rd))
|
||||
|
||||
|
||||
// #define gte_mv_to_data_r(rt, rd) enc_gte_tx(cop_mt, (rt), (rd)) /* Move GPR (rt) to GTE Control Register (rd) */
|
||||
// #define gte_mv_from_data_r(rt, rd) enc_gte_tx(cop_mf, (rt), (rd)) /* Move GTE Control Register (rd) to GPR (rt) */
|
||||
|
||||
/* GTE Data vs Control Register Transfers */
|
||||
#define gte_mv_from_data_r(rt, rd) enc_gte_tx(0x00, (rt), (rd)) /* Move from GTE Data Reg (e.g. MAC0, OTZ) */
|
||||
#define gte_mv_from_ctrl_r(rt, rd) enc_gte_tx(0x02, (rt), (rd)) /* Move from GTE Control Reg */
|
||||
#define gte_mv_to_data_r(rt, rd) enc_gte_tx(0x04, (rt), (rd)) /* Move to GTE Data Reg (e.g. VXY0) */
|
||||
#define gte_mv_to_ctrl_r(rt, rd) enc_gte_tx(0x06, (rt), (rd)) /* Move to GTE Control Reg (e.g. Matrices) */
|
||||
/* GTE Data vs Control Register Transfers
|
||||
*
|
||||
* Each macro emits a single .word constant for one of MFC2/CFC2/MTC2/CTC2.
|
||||
*
|
||||
* `rd` is the C2 register index in the file the sub-opcode names:
|
||||
* gte_mv_from_data_r / gte_mv_to_data_r → C2 data register file
|
||||
* gte_mv_from_ctrl_r / gte_mv_to_ctrl_r → C2 ctrl register file
|
||||
*
|
||||
* Common pairs:
|
||||
* gte_mv_from_data_r(R_T0, C2_MAC0) — read MAC0 into a GPR
|
||||
* gte_mv_to_data_r (R_V0, C2_VXY0) — write GPR into VXY0
|
||||
* gte_mv_to_ctrl_r (R_T0, gte_cr_RT11) — write GPR into rotation matrix
|
||||
* gte_mv_from_ctrl_r(R_T0, gte_cr_OFX) — read screen-X offset */
|
||||
#define gte_mv_from_data_r(rt, rd) enc_gte_tx(sub_mfc2, (rt), (rd)) /* Move From data reg */
|
||||
#define gte_mv_from_ctrl_r(rt, rd) enc_gte_tx(sub_cfc2, (rt), (rd)) /* Copy From ctrl reg */
|
||||
#define gte_mv_to_data_r(rt, rd) enc_gte_tx(sub_mtc2, (rt), (rd)) /* Move To data reg */
|
||||
#define gte_mv_to_ctrl_r(rt, rd) enc_gte_tx(sub_ctc2, (rt), (rd)) /* Copy To ctrl reg */
|
||||
|
||||
/* COP2 Data Load (lwc2): `lwc2 rt, off(rs)`
|
||||
* Layout: [op_lwc2:6][rs:5][rt:5][imm:16]
|
||||
|
||||
+11
-16
@@ -107,11 +107,11 @@ FI_ Slice_U4 tb_slice(TapeBuilder tb) { return (Sli
|
||||
, shift_lleft(R_AT, rId_2, v3s2_byteoff), add_u_self(R_AT, R_VertBase), load_word(R_V0, R_AT, O_(V3_S2,x)), load_word(R_V1, R_AT, O_(V3_S2,z)), gte_mv_to_data_r(R_V0, C2_VXY2), gte_mv_to_data_r(R_V1, C2_VZ2)
|
||||
|
||||
/* Words: 11; Correctly inserts a primitive into the Ordering Table linked list */
|
||||
#define mac_insert_ot_tag(r_otz, prim_length) \
|
||||
shift_lleft( R_T1, r_otz, 2) /* T1 = r_otz * S_(U4) */ \
|
||||
, add_u( R_T1, R_T1, R_OtBase) /* T1 = & OrderingTable[OTZ] */ \
|
||||
#define mac_insert_ot_tag(r_otz, prim_type) \
|
||||
shift_lleft( R_T1, r_otz, S_(U4)/2) /* T1 = r_otz * S_(U4) */ \
|
||||
, add_u_self( R_T1, R_OtBase) /* T1 = & OrderingTable[OTZ] */ \
|
||||
, load_word( R_AT, R_T1, O_(PolyTag,bf_addr_len)) /* AT = old_ot_head */ \
|
||||
, load_upper_i(R_V0, prim_length) /* V0 = prim_length << 16 (high 16 bits of a tag) */ \
|
||||
, load_upper_i(R_V0, (S_(prim_type)/S_(U4) - S_(PolyTag)/S_(U4)) << polytag_len_bits) /* V0 = S_(prim_type without tag field) */ \
|
||||
, mask_upper( R_AT, R_AT, S_(polytag_len_bits)) /* Strip upper 8 bits (length from prev cell) → keep only low 24 */ \
|
||||
, or_u( R_AT, R_AT, R_V0) /* Merge length */ \
|
||||
, store_word( R_AT, R_PrimCursor, O_(PolyTag,bf_addr_len)) /* prim->tag = packed(prim_length, old_addr) */ \
|
||||
@@ -200,13 +200,10 @@ internal MipsAtom_(mips_flush_icache) {
|
||||
typedef Struct_(Binds_SetGteWorld) {
|
||||
U4 transform;
|
||||
};
|
||||
// TODO(Ed): Bugged, fix
|
||||
internal MipsAtom_(set_gte_world) {
|
||||
/* Pop matrix address from tape into R_T3 ($11) */
|
||||
load_word(R_T3, R_TapePtr, O_(Binds_SetGteWorld,transform)),
|
||||
add_ui_self( R_TapePtr, S_(Binds_SetGteWorld)),
|
||||
|
||||
// TODO(Ed): Annotate magic offsets.
|
||||
/* Load 3x3 Rotation + 3x1 Translation from R_T3 into GTE CONTROL Regs (ctc2) */
|
||||
load_word(R_T0, R_T3, 0), load_word(R_T1, R_T3, 4),
|
||||
gte_mv_to_ctrl_r(R_T0, gte_cr_RT11), gte_mv_to_ctrl_r(R_T1, gte_cr_RT12),
|
||||
@@ -214,7 +211,6 @@ internal MipsAtom_(set_gte_world) {
|
||||
gte_mv_to_ctrl_r(R_T0, gte_cr_RT13), gte_mv_to_ctrl_r(R_T1, gte_cr_RT21), gte_mv_to_ctrl_r(R_T2, gte_cr_RT22),
|
||||
load_word(R_T0, R_T3, 20), load_word(R_T1, R_T3, 24), load_word(R_T2, R_T3, 28),
|
||||
gte_mv_to_ctrl_r(R_T0, gte_cr_TRX), gte_mv_to_ctrl_r(R_T1, gte_cr_TRY), gte_mv_to_ctrl_r(R_T2, gte_cr_TRZ),
|
||||
|
||||
mac_yield()
|
||||
};
|
||||
|
||||
@@ -237,15 +233,14 @@ internal MipsAtom_(diag_color) {
|
||||
load_upper_i(R_AT, 0x0010), or_i_self(R_AT, 0x0050), store_word(R_AT, R_T7, 16), /* (16, 80) */
|
||||
|
||||
add_ui( R_T1, R_0, 10),
|
||||
shift_lleft_self(R_T1, 2),
|
||||
shift_lleft_self(R_T1, S_(U4)/2),
|
||||
add_u_self( R_T1, R_T6),
|
||||
|
||||
load_word( R_AT, R_T1, 0),
|
||||
load_upper_i(R_V0, 0x0400), // <--- Fills load delay slot!
|
||||
load_upper_i(R_V0, (S_(Poly_F3)/S_(U4) - S_(PolyTag)/S_(U4)) << polytag_len_bits),
|
||||
store_word( R_AT, R_T7, 0),
|
||||
|
||||
shift_lleft(R_AT, R_T7, 8), shift_lright(R_AT, R_AT, 8),
|
||||
or_u_self( R_AT, R_V0),
|
||||
shift_lleft(R_AT, R_T7, S_(polytag_len_bits)), shift_lright(R_AT, R_AT, S_(polytag_len_bits)),
|
||||
or_u_self( R_AT, R_V0),
|
||||
store_word( R_AT, R_T1, 0),
|
||||
|
||||
add_ui(R_T7, R_T7, 20),
|
||||
@@ -275,9 +270,9 @@ internal MipsAtom_(diag_gte) {
|
||||
gte_mv_to_data_r(R_V0, C2_VXY2), gte_mv_to_data_r(R_V1, C2_VZ2),
|
||||
|
||||
/* Run Math */
|
||||
nop, nop, gte_cmdw_rtpt,
|
||||
nop, nop, gte_cmdw_nclip,
|
||||
nop, nop,
|
||||
nop2, gte_cmdw_rtpt,
|
||||
nop2, gte_cmdw_nclip,
|
||||
nop2,
|
||||
|
||||
/* Advance Face Cursor and Yield */
|
||||
add_ui(R_T4, R_T4, 8),
|
||||
|
||||
+2
-1
@@ -464,7 +464,8 @@ enum { _BitOffsets = 0
|
||||
#define shift_amount(rd, rt, n) shift_lleft(rd, rt, n)
|
||||
|
||||
/* nop — canonical sll $0, $0, 0 */
|
||||
#define nop shift_lleft(rdiscard, rdiscard, 0)
|
||||
#define nop shift_lleft(rdiscard, rdiscard, 0)
|
||||
#define nop2 nop, nop
|
||||
|
||||
#define load_imm_1w(rt, imm) add_ui((rt), R_0, (imm))
|
||||
#define load_imm_1w_s0(rt, imm) add_si((rt)), R_0, (imm))
|
||||
|
||||
@@ -12,13 +12,6 @@
|
||||
* (mac_format_f3_color takes _r, _g, _b byte values rather than raw
|
||||
* 16-bit half-words). */
|
||||
|
||||
enum fack {
|
||||
ah = gp0_cmd_poly_f3 << 8 | 0xFF,
|
||||
};
|
||||
void fk() {
|
||||
(void*)ah;
|
||||
}
|
||||
|
||||
#pragma endregion MACs
|
||||
|
||||
#pragma region Baked Atoms
|
||||
@@ -143,7 +136,7 @@ MipsAtom_(cube_tri) {
|
||||
nop, /* BD slot */
|
||||
|
||||
/* ── 11. Insert into Ordering Table (length = 8 for Poly_G4) ─────────── */
|
||||
mac_insert_ot_tag(R_T1, 0x0800), /* 0x0800 = 8 << 8 = length 8 in tag */
|
||||
mac_insert_ot_tag(R_T1, Poly_G4), /* 0x0800 = 8 << 8 = length 8 in tag */
|
||||
|
||||
/* ── 12. Advance cursors & yield ─────────────────────────────────────── */
|
||||
add_ui(R_PrimCursor, R_PrimCursor, 36), /* 9 words × 4 bytes */
|
||||
@@ -184,9 +177,9 @@ internal
|
||||
MipsAtom_(floor_tri) {
|
||||
mac_load_tri_indices(R_T0, R_T1, R_T2),
|
||||
mac_load_tri_verts( R_T0, R_T1, R_T2),
|
||||
nop, nop, gte_cmdw_rotate_translate_perspective_triple,
|
||||
nop, nop, gte_cmdw_nclip,
|
||||
nop, nop,
|
||||
nop2, gte_cmdw_rotate_translate_perspective_triple,
|
||||
nop2, gte_cmdw_nclip,
|
||||
nop2,
|
||||
/* Culling (Branch forward if Backface) */
|
||||
gte_mv_from_data_r(R_T0, C2_MAC0),
|
||||
nop, branch_le_zero(R_T0, atom_offset(culling, floor_tri_exit)),
|
||||
@@ -197,15 +190,15 @@ MipsAtom_(floor_tri) {
|
||||
mac_gte_store_f3(),
|
||||
|
||||
/* Calculate Depth */
|
||||
nop, nop, gte_avg_sort_z3,
|
||||
nop, nop, gte_mv_from_data_r(R_T1, C2_OTZ),
|
||||
nop2, gte_avg_sort_z3,
|
||||
nop2, gte_mv_from_data_r(R_T1, C2_OTZ),
|
||||
/* Bounds Check OTZ < 2048 (Branch forward to skip insertion) */
|
||||
add_ui( R_AT, R_0, OrderingTbl_Len),
|
||||
set_lt_u( R_AT, R_T1, R_AT),
|
||||
branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_tri_exit)),
|
||||
nop,
|
||||
/* Insert into Ordering Table Linked List */
|
||||
mac_insert_ot_tag(R_T1, 0x0400),
|
||||
mac_insert_ot_tag(R_T1, Poly_F3),
|
||||
add_ui_self(R_PrimCursor, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */
|
||||
// Note(Ed): No bounds checking, should be checked before atom runs.
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ WORD_COUNT(set_lt_u, 1)
|
||||
WORD_COUNT(set_lt_s, 1)
|
||||
WORD_COUNT(set_lt_si, 1)
|
||||
WORD_COUNT(set_lt_ui, 1)
|
||||
WORD_COUNT(load_ui, 1)
|
||||
WORD_COUNT(load_word, 1)
|
||||
WORD_COUNT(load_half_u, 1)
|
||||
WORD_COUNT(store_word, 1)
|
||||
@@ -30,8 +29,11 @@ WORD_COUNT(add_ui_self, 1)
|
||||
WORD_COUNT(add_u_self, 1)
|
||||
WORD_COUNT(add_u, 1)
|
||||
WORD_COUNT(or_i, 1)
|
||||
WORD_COUNT(or_i_self, 1)
|
||||
WORD_COUNT(or_u, 1)
|
||||
WORD_COUNT(or_u_self, 1)
|
||||
WORD_COUNT(shift_lleft, 1)
|
||||
WORD_COUNT(shift_lleft_self, 1)
|
||||
WORD_COUNT(shift_lright, 1)
|
||||
WORD_COUNT(shift_aright, 1)
|
||||
WORD_COUNT(mask_upper, 2)
|
||||
|
||||
Reference in New Issue
Block a user