mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-14 11:38:14 +00:00
Redesign: Not making local var in MipsAtom_Proc_ or MipsAtomComp_Proc_ have sym tied to proc name. Adjusted parser as well base do that.
This commit is contained in:
@@ -190,6 +190,7 @@ WORD_COUNT(mac_gte_gpf_scale, 13)
|
|||||||
, store_word(r_t2, r_mtx, O_(MT3_S2S4,t[2]))
|
, store_word(r_t2, r_mtx, O_(MT3_S2S4,t[2]))
|
||||||
WORD_COUNT(mac_trans_mt3s3s4, 6)
|
WORD_COUNT(mac_trans_mt3s3s4, 6)
|
||||||
|
|
||||||
|
/* atom_dbg_skip */
|
||||||
#define mac_gcmd_push(cmd, reg_transfer, reg_base, port) \
|
#define mac_gcmd_push(cmd, reg_transfer, reg_base, port) \
|
||||||
mac_load_word_imm(reg_transfer, cmd) \
|
mac_load_word_imm(reg_transfer, cmd) \
|
||||||
, store_word( reg_transfer, reg_base, port)
|
, store_word( reg_transfer, reg_base, port)
|
||||||
@@ -214,6 +215,7 @@ WORD_COUNT(mac_pack_color_word, 3)
|
|||||||
mac_pack_color_word(r_base, O_(Poly_F3,color), gp0_cmd_poly_f3, r, g, b)
|
mac_pack_color_word(r_base, O_(Poly_F3,color), gp0_cmd_poly_f3, r, g, b)
|
||||||
WORD_COUNT(mac_format_f3_color, 3)
|
WORD_COUNT(mac_format_f3_color, 3)
|
||||||
|
|
||||||
|
/* atom_dbg_skip */
|
||||||
#define mac_format_g4_color(r_prim_cursor, r0, g0, b0, r1, g1, b1, r2, g2, b2, r3, g3, b3) \
|
#define mac_format_g4_color(r_prim_cursor, r0, g0, b0, r1, g1, b1, r2, g2, b2, r3, g3, b3) \
|
||||||
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c0), gp0_cmd_poly_g4, r0,g0,b0) \
|
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c0), gp0_cmd_poly_g4, r0,g0,b0) \
|
||||||
, mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c1), 0, r1,g1,b1) \
|
, mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c1), 0, r1,g1,b1) \
|
||||||
|
|||||||
+12
-6
@@ -8,34 +8,40 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(gp_atom_c);
|
|||||||
|
|
||||||
#pragma region MACs (Mips Atom Components)
|
#pragma region MACs (Mips Atom Components)
|
||||||
|
|
||||||
|
atom_dbg_skip
|
||||||
FI_ Slice_MipsCode ac_gcmd_push(AtomBuilder_R ab, U4 cmd, U4 reg_transfer, U4 reg_base, U2 port)
|
FI_ Slice_MipsCode ac_gcmd_push(AtomBuilder_R ab, U4 cmd, U4 reg_transfer, U4 reg_base, U2 port)
|
||||||
MipsAtomComp_Proc_(ac_gcmd_push, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
mac_load_word_imm(reg_transfer, cmd),
|
mac_load_word_imm(reg_transfer, cmd),
|
||||||
store_word( reg_transfer, reg_base, port),
|
store_word( reg_transfer, reg_base, port),
|
||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_store_rgb8(AtomBuilder_R ab, U1 rr, U1 rg, U1 rb, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_store_rgb8, ab, {
|
atom_dbg_skip
|
||||||
|
FI_ Slice_MipsCode ac_store_rgb8(AtomBuilder_R ab, U1 rr, U1 rg, U1 rb, U4 base, U4 offset)
|
||||||
|
MipsAtomComp_Proc_(ab, {
|
||||||
store_byte(rr, base, offset + O_(RGB8,r)),
|
store_byte(rr, base, offset + O_(RGB8,r)),
|
||||||
store_byte(rg, base, offset + O_(RGB8,g)),
|
store_byte(rg, base, offset + O_(RGB8,g)),
|
||||||
store_byte(rb, base, offset + O_(RGB8,b)),
|
store_byte(rb, base, offset + O_(RGB8,b)),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
atom_dbg_skip
|
||||||
FI_ Slice_MipsCode ac_pack_color_word(AtomBuilder_R ab, U4 r_base, U4 off, U4 cmd, U1 r, U1 g, U1 b)
|
FI_ Slice_MipsCode ac_pack_color_word(AtomBuilder_R ab, U4 r_base, U4 off, U4 cmd, U1 r, U1 g, U1 b)
|
||||||
atom_dbg_skip MipsAtomComp_Proc_(ac_pack_color_word, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
load_upper_i(R_AT, (cmd) << 8 | (b)),
|
load_upper_i(R_AT, (cmd) << 8 | (b)),
|
||||||
or_i_self( R_AT, ((g) << 8) | (r)),
|
or_i_self( R_AT, ((g) << 8) | (r)),
|
||||||
store_word( R_AT, r_base, (off)),
|
store_word( R_AT, r_base, (off)),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
atom_dbg_skip
|
||||||
FI_ Slice_MipsCode ac_format_f3_color(AtomBuilder_R ab, U4 r_base, U1 r, U1 g, U1 b)
|
FI_ Slice_MipsCode ac_format_f3_color(AtomBuilder_R ab, U4 r_base, U1 r, U1 g, U1 b)
|
||||||
atom_dbg_skip MipsAtomComp_Proc_(ac_format_f3_color, ab, { mac_pack_color_word(r_base, O_(Poly_F3,color), gp0_cmd_poly_f3, r, g, b) })
|
MipsAtomComp_Proc_(ab, { mac_pack_color_word(r_base, O_(Poly_F3,color), gp0_cmd_poly_f3, r, g, b) })
|
||||||
|
|
||||||
|
atom_dbg_skip
|
||||||
FI_ Slice_MipsCode ac_format_g4_color(AtomBuilder_R ab, U4 r_prim_cursor,
|
FI_ Slice_MipsCode ac_format_g4_color(AtomBuilder_R ab, U4 r_prim_cursor,
|
||||||
U1 r0, U1 g0, U1 b0,
|
U1 r0, U1 g0, U1 b0,
|
||||||
U1 r1, U1 g1, U1 b1,
|
U1 r1, U1 g1, U1 b1,
|
||||||
U1 r2, U1 g2, U1 b2,
|
U1 r2, U1 g2, U1 b2,
|
||||||
U1 r3, U1 g3, U1 b3)
|
U1 r3, U1 g3, U1 b3)
|
||||||
MipsAtomComp_Proc_(ac_format_g4_color, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c0), gp0_cmd_poly_g4, r0,g0,b0),
|
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c0), gp0_cmd_poly_g4, r0,g0,b0),
|
||||||
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c1), 0, r1,g1,b1),
|
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c1), 0, r1,g1,b1),
|
||||||
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c2), 0, r2,g2,b2),
|
mac_pack_color_word(r_prim_cursor, O_(Poly_G4,c2), 0, r2,g2,b2),
|
||||||
@@ -43,7 +49,7 @@ MipsAtomComp_Proc_(ac_format_g4_color, ab, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
/* Words: 11; Correctly inserts a primitive into the Ordering Table linked list. */
|
/* Words: 11; Correctly inserts a primitive into the Ordering Table linked list. */
|
||||||
I_ Slice_MipsCode ac_insert_ot_tag(AtomBuilder_R ab, U4 r_ot_base, U4 r_prim_cursor, U4 poly_size) MipsAtomComp_Proc_(ac_insert_ot_tag, ab, {
|
I_ Slice_MipsCode ac_insert_ot_tag(AtomBuilder_R ab, U4 r_ot_base, U4 r_prim_cursor, U4 poly_size) MipsAtomComp_Proc_(ab, {
|
||||||
shift_lleft( R_T1, R_T1, S_(U4)/2), // T1 = otz * S_(U4) (otz arg is implicit R_T1)
|
shift_lleft( R_T1, R_T1, S_(U4)/2), // T1 = otz * S_(U4) (otz arg is implicit R_T1)
|
||||||
add_u_self( R_T1, r_ot_base), // T1 = & OrderingTable[OTZ]
|
add_u_self( R_T1, r_ot_base), // T1 = & OrderingTable[OTZ]
|
||||||
load_word( R_AT, R_T1, O_(PolyTag,code)), // AT = old_ot_head
|
load_word( R_AT, R_T1, O_(PolyTag,code)), // AT = old_ot_head
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(gte_atom_c);
|
|||||||
#pragma region MACs (Mips Atom Components)
|
#pragma region MACs (Mips Atom Components)
|
||||||
|
|
||||||
/* Words: 3; Loads 3 S2 indices from the face array */
|
/* Words: 3; Loads 3 S2 indices from the face array */
|
||||||
FI_ Slice_MipsCode ac_load_tri_indices(AtomBuilder_R ab, U4 r_face_cusor, U4 r_i0, U4 r_i1, U4 r_i2) atom_dbg_skip MipsAtomComp_Proc_(ac_load_tri_indices, ab, {
|
FI_ Slice_MipsCode ac_load_tri_indices(AtomBuilder_R ab, U4 r_face_cusor, U4 r_i0, U4 r_i1, U4 r_i2) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
load_half_u(r_i0, r_face_cusor, 0 * S_(S2)),
|
load_half_u(r_i0, r_face_cusor, 0 * S_(S2)),
|
||||||
load_half_u(r_i1, r_face_cusor, 1 * S_(S2)),
|
load_half_u(r_i1, r_face_cusor, 1 * S_(S2)),
|
||||||
load_half_u(r_i2, r_face_cusor, 2 * S_(S2)),
|
load_half_u(r_i2, r_face_cusor, 2 * S_(S2)),
|
||||||
@@ -19,14 +19,14 @@ FI_ Slice_MipsCode ac_load_tri_indices(AtomBuilder_R ab, U4 r_face_cusor, U4 r_i
|
|||||||
|
|
||||||
/* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices to the F3.
|
/* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices to the F3.
|
||||||
* PIPELINE: post-RTPT (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen). */
|
* PIPELINE: post-RTPT (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen). */
|
||||||
FI_ Slice_MipsCode ac_gte_store_f3(AtomBuilder_R ab, U4 r_primitive_cursor) atom_dbg_skip MipsAtomComp_Proc_(ac_gte_store_f3, ab, {
|
FI_ Slice_MipsCode ac_gte_store_f3(AtomBuilder_R ab, U4 r_primitive_cursor) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
gte_sw(C2_SXY0, r_primitive_cursor, O_(Poly_F3,p0)),
|
gte_sw(C2_SXY0, r_primitive_cursor, O_(Poly_F3,p0)),
|
||||||
gte_sw(C2_SXY1, r_primitive_cursor, O_(Poly_F3,p1)),
|
gte_sw(C2_SXY1, r_primitive_cursor, O_(Poly_F3,p1)),
|
||||||
gte_sw(C2_SXY2, r_primitive_cursor, O_(Poly_F3,p2)),
|
gte_sw(C2_SXY2, r_primitive_cursor, O_(Poly_F3,p2)),
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Words: 18; Translates indices to vertex addresses and pushes them to GTE */
|
/* Words: 18; Translates indices to vertex addresses and pushes them to GTE */
|
||||||
I_ Slice_MipsCode ac_gte_load_tri_verts(AtomBuilder_R ab, U4 r_vert_base, U4 r_v0, U4 r_v1, U4 r_v2) atom_dbg_skip MipsAtomComp_Proc_(ac_gte_load_tri_verts, ab, {
|
I_ Slice_MipsCode ac_gte_load_tri_verts(AtomBuilder_R ab, U4 r_vert_base, U4 r_v0, U4 r_v1, U4 r_v2) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
shift_lleft(R_AT, r_v0, v3s2_byteoff), add_u_self(R_AT, r_vert_base), 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_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0),
|
shift_lleft(R_AT, r_v0, v3s2_byteoff), add_u_self(R_AT, r_vert_base), 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_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0),
|
||||||
shift_lleft(R_AT, r_v1, v3s2_byteoff), add_u_self(R_AT, r_vert_base), 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_VXY1), gte_mv_to_data_r(R_V1, C2_VZ1),
|
shift_lleft(R_AT, r_v1, v3s2_byteoff), add_u_self(R_AT, r_vert_base), 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_VXY1), gte_mv_to_data_r(R_V1, C2_VZ1),
|
||||||
shift_lleft(R_AT, r_v2, v3s2_byteoff), add_u_self(R_AT, r_vert_base), 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),
|
shift_lleft(R_AT, r_v2, v3s2_byteoff), add_u_self(R_AT, r_vert_base), 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),
|
||||||
@@ -37,7 +37,7 @@ I_ Slice_MipsCode ac_gte_load_tri_verts(AtomBuilder_R ab, U4 r_vert_base, U4 r_v
|
|||||||
* PIPELINE: post-RTPT, pre-RTPS (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen).
|
* PIPELINE: post-RTPT, pre-RTPS (SXY0=v0.screen, SXY1=v1.screen, SXY2=v2.screen).
|
||||||
* MUST be called BEFORE V3-RTPS, otherwise SXY0/1/2 get overwritten with v3
|
* MUST be called BEFORE V3-RTPS, otherwise SXY0/1/2 get overwritten with v3
|
||||||
* (RTPS writes only to SXY2, but to keep the three registers aligned with v0/v1/v2 you must store before RTPS). */
|
* (RTPS writes only to SXY2, but to keep the three registers aligned with v0/v1/v2 you must store before RTPS). */
|
||||||
FI_ Slice_MipsCode ac_gte_store_g4_p012(AtomBuilder_R ab, U4 r_primitive_cursor) atom_dbg_skip MipsAtomComp_Proc_(ac_gte_store_g4_p012, ab, {
|
FI_ Slice_MipsCode ac_gte_store_g4_p012(AtomBuilder_R ab, U4 r_primitive_cursor) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
gte_sw(C2_SXY0, r_primitive_cursor, O_(Poly_G4,p0)),
|
gte_sw(C2_SXY0, r_primitive_cursor, O_(Poly_G4,p0)),
|
||||||
gte_sw(C2_SXY1, r_primitive_cursor, O_(Poly_G4,p1)),
|
gte_sw(C2_SXY1, r_primitive_cursor, O_(Poly_G4,p1)),
|
||||||
gte_sw(C2_SXY2, r_primitive_cursor, O_(Poly_G4,p2)),
|
gte_sw(C2_SXY2, r_primitive_cursor, O_(Poly_G4,p2)),
|
||||||
@@ -47,13 +47,13 @@ FI_ Slice_MipsCode ac_gte_store_g4_p012(AtomBuilder_R ab, U4 r_primitive_cursor)
|
|||||||
* PIPELINE: post-RTPS (SXY2 holds v3.screen because RTPS writes its single-vertex result to SXY2;
|
* PIPELINE: post-RTPS (SXY2 holds v3.screen because RTPS writes its single-vertex result to SXY2;
|
||||||
* SXY0 still holds v0.screen from the earlier RTPT.
|
* SXY0 still holds v0.screen from the earlier RTPT.
|
||||||
*/
|
*/
|
||||||
FI_ Slice_MipsCode ac_gte_store_g4_p3(AtomBuilder_R ab, U4 r_primitive_cursor) atom_dbg_skip MipsAtomComp_Proc_(ac_gte_store_g4_p3, ab, { gte_sw(C2_SXY2, r_primitive_cursor, O_(Poly_G4,p3)) })
|
FI_ Slice_MipsCode ac_gte_store_g4_p3(AtomBuilder_R ab, U4 r_primitive_cursor) atom_dbg_skip MipsAtomComp_Proc_(ab, { gte_sw(C2_SXY2, r_primitive_cursor, O_(Poly_G4,p3)) })
|
||||||
|
|
||||||
/* ─── STAGE 1 of normalize: SQR + mfc2 MAC1/2/3 ───
|
/* ─── STAGE 1 of normalize: SQR + mfc2 MAC1/2/3 ───
|
||||||
* Emits squared magnitude per component (in MAC1/2/3) into caller-provided scratch regs.
|
* Emits squared magnitude per component (in MAC1/2/3) into caller-provided scratch regs.
|
||||||
* Stage 2 of normalize consumes these directly.
|
* Stage 2 of normalize consumes these directly.
|
||||||
* Words: 8. Clobbers: IR1/2/3, MAC1/2/3. Uses gte_cmdw_sqr (sf=0, lm=1). */
|
* Words: 8. Clobbers: IR1/2/3, MAC1/2/3. Uses gte_cmdw_sqr (sf=0, lm=1). */
|
||||||
FI_ Slice_MipsCode ac_gte_sqr_v3(AtomBuilder_R ab, U4 r_sx, U4 r_sy, U4 r_sz, U4 r_sq_x, U4 r_sq_y, U4 r_sq_z) atom_dbg_skip MipsAtomComp_Proc_(ac_gte_sqr_v3, ab, {
|
FI_ Slice_MipsCode ac_gte_sqr_v3(AtomBuilder_R ab, U4 r_sx, U4 r_sy, U4 r_sz, U4 r_sq_x, U4 r_sq_y, U4 r_sq_z) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
gte_mv_to_data_r(r_sx, C2_IR1),
|
gte_mv_to_data_r(r_sx, C2_IR1),
|
||||||
gte_mv_to_data_r(r_sy, C2_IR2),
|
gte_mv_to_data_r(r_sy, C2_IR2),
|
||||||
gte_mv_to_data_r(r_sz, C2_IR3),
|
gte_mv_to_data_r(r_sz, C2_IR3),
|
||||||
@@ -68,7 +68,7 @@ FI_ Slice_MipsCode ac_gte_sqr_v3(AtomBuilder_R ab, U4 r_sx, U4 r_sy, U4 r_sz, U4
|
|||||||
* (typically (31 - LZCR)/2), multiplies IR0*IR[i] via GPF and shifts right to produce the normalized output.
|
* (typically (31 - LZCR)/2), multiplies IR0*IR[i] via GPF and shifts right to produce the normalized output.
|
||||||
* Used standalone for "scale vector by scalar".
|
* Used standalone for "scale vector by scalar".
|
||||||
* Words: 11. Clobbers: IR0..3, MAC1..3. Uses gte_cmdw_gpf (sf=0, lm=0). */
|
* Words: 11. Clobbers: IR0..3, MAC1..3. Uses gte_cmdw_gpf (sf=0, lm=0). */
|
||||||
FI_ Slice_MipsCode ac_gte_gpf_scale(AtomBuilder_R ab, U4 r_sx, U4 r_sy, U4 r_sz, U4 r_recip_est, U4 r_shift, U4 r_dx, U4 r_dy, U4 r_dz) atom_dbg_skip MipsAtomComp_Proc_(ac_gte_gpf_scale, ab, {
|
FI_ Slice_MipsCode ac_gte_gpf_scale(AtomBuilder_R ab, U4 r_sx, U4 r_sy, U4 r_sz, U4 r_recip_est, U4 r_shift, U4 r_dx, U4 r_dy, U4 r_dz) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
gte_mv_to_data_r(r_recip_est, C2_IR0),
|
gte_mv_to_data_r(r_recip_est, C2_IR0),
|
||||||
gte_mv_to_data_r(r_sx, C2_IR1),
|
gte_mv_to_data_r(r_sx, C2_IR1),
|
||||||
gte_mv_to_data_r(r_sy, C2_IR2),
|
gte_mv_to_data_r(r_sy, C2_IR2),
|
||||||
@@ -91,7 +91,7 @@ FI_ Slice_MipsCode ac_gte_gpf_scale(AtomBuilder_R ab, U4 r_sx, U4 r_sy, U4 r_sz,
|
|||||||
FI_ Slice_MipsCode ac_trans_mt3s3s4(AtomBuilder_R ab
|
FI_ Slice_MipsCode ac_trans_mt3s3s4(AtomBuilder_R ab
|
||||||
, U4 r_mtx, U4 r_off
|
, U4 r_mtx, U4 r_off
|
||||||
, U4 r_t0, U4 r_t1, U4 r_t2
|
, U4 r_t0, U4 r_t1, U4 r_t2
|
||||||
) MipsAtomComp_Proc_(ac_trans_mt3s3s4, ab, {
|
) MipsAtomComp_Proc_(ab, {
|
||||||
load_word(r_t0, r_off, O_(V3_S4,x)),
|
load_word(r_t0, r_off, O_(V3_S4,x)),
|
||||||
load_word(r_t1, r_off, O_(V3_S4,y)),
|
load_word(r_t1, r_off, O_(V3_S4,y)),
|
||||||
load_word(r_t2, r_off, O_(V3_S4,z)),
|
load_word(r_t2, r_off, O_(V3_S4,z)),
|
||||||
@@ -210,7 +210,7 @@ internal MipsAtom* normalize_v3s4_proc(AtomArena_R aa, U4 r_scratch /* GPR code:
|
|||||||
, U4 r_lzcr, U4 r_shift /* GPR codes: lzcr + final srav amount */
|
, U4 r_lzcr, U4 r_shift /* GPR codes: lzcr + final srav amount */
|
||||||
, U4 r_branch_tmp /* GPR code: scratch (shift count, branch target, lookup addr) */
|
, U4 r_branch_tmp /* GPR code: scratch (shift count, branch target, lookup addr) */
|
||||||
)
|
)
|
||||||
MipsAtom_Proc_(normalize_v3s4, aa, {
|
MipsAtom_Proc_(aa, {
|
||||||
add_si(r_src_ptr, r_scratch, r_src_offset), /* r_src_ptr = &src */
|
add_si(r_src_ptr, r_scratch, r_src_offset), /* r_src_ptr = &src */
|
||||||
add_si(r_dst_ptr, r_scratch, r_dst_offset), /* r_dst_ptr = &dst */
|
add_si(r_dst_ptr, r_scratch, r_dst_offset), /* r_dst_ptr = &dst */
|
||||||
nop,
|
nop,
|
||||||
|
|||||||
@@ -117,10 +117,13 @@ typedef Slice_(MipsAtom);
|
|||||||
#define MipsAtom_(sym) MipsCode sym [] align_(4) =
|
#define MipsAtom_(sym) MipsCode sym [] align_(4) =
|
||||||
|
|
||||||
// Used for atoms with value-args
|
// Used for atoms with value-args
|
||||||
// FI_ void ac_X(args) MipsAtomComp_Proc_(ac_X, { body })
|
// internal MipsAtom* X_proc(AtomArena_R aa, args) MipsAtom_Proc_(X, aa, { body })
|
||||||
// expands to:
|
// expands to:
|
||||||
// FI_ void ac_X(args) { MipsCode ac_X[] align_(4) = { body }; return ac_X; }
|
// internal MipsAtom* X_proc(AtomArena_R aa, args) { MipsCode atom_comp_code[] align_(4) = { body }; return atomarena_push(aa, slice_from_array(MipsCode, atom_comp_code)); }
|
||||||
#define MipsAtom_Proc_(sym, aa, ...) { MipsCode sym [] align_(4) = __VA_ARGS__; return atomarena_push(aa, slice_from_array(MipsCode, sym)); }
|
// The atom name is derived by the Lua metaprogram from the preceding
|
||||||
|
// `MipsAtom* X_proc(...)` declaration (backward walk from the macro site,
|
||||||
|
// strips the `_proc` suffix).
|
||||||
|
#define MipsAtom_Proc_(aa, ...) { MipsCode atom_comp_code[] align_(4) = __VA_ARGS__; return atomarena_push(aa, slice_from_array(MipsCode, atom_comp_code)); }
|
||||||
|
|
||||||
// Used for components with no args (e.g., ac_load_tri_indices) or identifier-args (hardcoded register names).
|
// Used for components with no args (e.g., ac_load_tri_indices) or identifier-args (hardcoded register names).
|
||||||
// MipsAtomComp_(ac_X) { body }
|
// MipsAtomComp_(ac_X) { body }
|
||||||
@@ -129,16 +132,18 @@ typedef Slice_(MipsAtom);
|
|||||||
#define MipsAtomComp_(sym) MipsCode sym [] align_(4) =
|
#define MipsAtomComp_(sym) MipsCode sym [] align_(4) =
|
||||||
|
|
||||||
// Used for components with value-args (mandatory `ab` (atom-builder) arg).
|
// Used for components with value-args (mandatory `ab` (atom-builder) arg).
|
||||||
// FI_ void ac_X(MipsAtomBuilder_R ab, args) MipsAtomComp_Proc_(ac_X, ab, { body })
|
// FI_ void ac_X(MipsAtomBuilder_R ab, args) MipsAtomComp_Proc_(ab, { body })
|
||||||
// expands to:
|
// expands to:
|
||||||
// FI_ void ac_X(MipsAtomBuilder_R ab, args) {
|
// FI_ void ac_X(MipsAtomBuilder_R ab, args) {
|
||||||
// MipsCode ac_X[] align_(4) = { body };
|
// MipsCode atom_comp_code[] align_(4) = { body };
|
||||||
// atombuilder_unroll(ab, slice_from_array(MipsCode, ac_X));
|
// atombuilder_push(ab, slice_from_array(MipsCode, atom_comp_code));
|
||||||
// }
|
// }
|
||||||
// The body must NOT include mac_yield() (the parent atom yields).
|
// The body must NOT include mac_yield() (the parent atom yields).
|
||||||
// Inline-only callers (the generated `mac_<name>` aliases) skip this arg via metaprogram filtering;
|
// The component name is derived by the Lua metaprogram from the preceding
|
||||||
|
// `FI_ Slice_MipsCode ac_X(...)` declaration (backward walk from the macro site).
|
||||||
|
// Inline-only callers (the generated `mac_<name>` aliases) skip the `ab` arg via metaprogram filtering;
|
||||||
// escape callers (ac_<name> invoked as a function) pass a long-lived builder.
|
// escape callers (ac_<name> invoked as a function) pass a long-lived builder.
|
||||||
#define MipsAtomComp_Proc_(sym, ab, ...) { MipsCode sym [] align_(4) = __VA_ARGS__; atombuilder_push(ab, slice_from_array(MipsCode, sym)); }
|
#define MipsAtomComp_Proc_(ab, ...) { MipsCode atom_comp_code[] align_(4) = __VA_ARGS__; atombuilder_push(ab, slice_from_array(MipsCode, atom_comp_code)); }
|
||||||
|
|
||||||
/* Line-table anchor: gcc only adds a file to the .debug_line file table when the contains line-numbered content.
|
/* Line-table anchor: gcc only adds a file to the .debug_line file table when the contains line-numbered content.
|
||||||
Files containing only atoms and atom components.
|
Files containing only atoms and atom components.
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(math_atom_c);
|
|||||||
|
|
||||||
// FI_ Slice_MipsCode ac_load_imm
|
// FI_ Slice_MipsCode ac_load_imm
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_load_v2s2(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 r_base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_load_v2s2, ab, {
|
FI_ Slice_MipsCode ac_load_v2s2(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 r_base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
load_half( rs_x, r_base, offset + O_(V3_S2,x)),
|
load_half( rs_x, r_base, offset + O_(V3_S2,x)),
|
||||||
load_half( rs_y, r_base, offset + O_(V3_S2,y)),
|
load_half( rs_y, r_base, offset + O_(V3_S2,y)),
|
||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_store_v2s2(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_store_v2s2, ab, {
|
FI_ Slice_MipsCode ac_store_v2s2(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
store_half(rt_x, base, offset + O_(V2_S2,x)),
|
store_half(rt_x, base, offset + O_(V2_S2,x)),
|
||||||
store_half(rt_y, base, offset + O_(V2_S2,y)),
|
store_half(rt_y, base, offset + O_(V2_S2,y)),
|
||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_load_v3s4(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 rs_z, U4 r_base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_load_v3s4, ab, {
|
FI_ Slice_MipsCode ac_load_v3s4(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 rs_z, U4 r_base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
load_word( rs_x, r_base, offset + O_(V3_S4,x)),
|
load_word( rs_x, r_base, offset + O_(V3_S4,x)),
|
||||||
load_word( rs_y, r_base, offset + O_(V3_S4,y)),
|
load_word( rs_y, r_base, offset + O_(V3_S4,y)),
|
||||||
load_word( rs_z, r_base, offset + O_(V3_S4,z)),
|
load_word( rs_z, r_base, offset + O_(V3_S4,z)),
|
||||||
@@ -30,7 +30,7 @@ FI_ Slice_MipsCode ac_load_v3s4(AtomBuilder_R ab, U4 rs_x, U4 rs_y, U4 rs_z, U4
|
|||||||
#define ac_load_p3s4 ac_load_v3s4
|
#define ac_load_p3s4 ac_load_v3s4
|
||||||
#define mac_load_p3s4 mac_load_v3s4
|
#define mac_load_p3s4 mac_load_v3s4
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_store_v3s4(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 rt_z, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_store_v3s4, ab, {
|
FI_ Slice_MipsCode ac_store_v3s4(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 rt_z, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
store_word(rt_x, base, offset + O_(V3_S4,x)),
|
store_word(rt_x, base, offset + O_(V3_S4,x)),
|
||||||
store_word(rt_y, base, offset + O_(V3_S4,y)),
|
store_word(rt_y, base, offset + O_(V3_S4,y)),
|
||||||
store_word(rt_z, base, offset + O_(V3_S4,z)),
|
store_word(rt_z, base, offset + O_(V3_S4,z)),
|
||||||
@@ -39,13 +39,13 @@ FI_ Slice_MipsCode ac_store_v3s4(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 rt_z, U4
|
|||||||
#define ac_store_p3s4 ac_store_v3s4
|
#define ac_store_p3s4 ac_store_v3s4
|
||||||
#define mac_store_p3s4 mac_store_v3s4
|
#define mac_store_p3s4 mac_store_v3s4
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_sub_v3s4(AtomBuilder_R ab, U4 rds_x, U4 rds_y, U4 rds_z, U4 rt_x, U4 rt_y, U4 rt_z) atom_dbg_skip MipsAtomComp_Proc_(ac_sub_v3s4, ab, {
|
FI_ Slice_MipsCode ac_sub_v3s4(AtomBuilder_R ab, U4 rds_x, U4 rds_y, U4 rds_z, U4 rt_x, U4 rt_y, U4 rt_z) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
sub_s(rds_x, rds_x, rt_x),
|
sub_s(rds_x, rds_x, rt_x),
|
||||||
sub_s(rds_y, rds_y, rt_y),
|
sub_s(rds_y, rds_y, rt_y),
|
||||||
sub_s(rds_z, rds_z, rt_z),
|
sub_s(rds_z, rds_z, rt_z),
|
||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_store_rects2(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 rt_width, U4 rt_height, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ac_store_rects2, ab, {
|
FI_ Slice_MipsCode ac_store_rects2(AtomBuilder_R ab, U4 rt_x, U4 rt_y, U4 rt_width, U4 rt_height, U4 base, U4 offset) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
store_half(rt_x, base, offset + O_(Rect_S2,x)),
|
store_half(rt_x, base, offset + O_(Rect_S2,x)),
|
||||||
store_half(rt_y, base, offset + O_(Rect_S2,y)),
|
store_half(rt_y, base, offset + O_(Rect_S2,y)),
|
||||||
store_half(rt_width, base, offset + O_(Rect_S2,width)),
|
store_half(rt_width, base, offset + O_(Rect_S2,width)),
|
||||||
|
|||||||
@@ -10,18 +10,11 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(mips_atom_c);
|
|||||||
|
|
||||||
#pragma region MACs (Mips Atom Components)
|
#pragma region MACs (Mips Atom Components)
|
||||||
|
|
||||||
// Tired of this signature:
|
|
||||||
FI_ Slice_MipsCode ac_load_word_imm(AtomBuilder_R ab, Reg dst, U4 imm)
|
FI_ Slice_MipsCode ac_load_word_imm(AtomBuilder_R ab, Reg dst, U4 imm)
|
||||||
atom_dbg_skip MipsAtomComp_Proc_(ac_load_word_imm, ab, {
|
atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
load_upper_i(dst, u4_hi(imm)),
|
load_upper_i(dst, u4_hi(imm)),
|
||||||
or_i_self( dst, u4_lo(imm)),
|
or_i_self( dst, u4_lo(imm)),
|
||||||
})
|
})
|
||||||
// Can I get away with this instead?
|
|
||||||
// atom_dbg_skip FI_ Slice_MipsCode
|
|
||||||
// ac_load_word_imm(AtomBuilder_R ab, Reg dst, U4 imm) MipsAtomComp_Proc_(ab, {
|
|
||||||
// load_upper_i(dst, u4_hi(imm)),
|
|
||||||
// or_i_self( dst, u4_lo(imm)),
|
|
||||||
// })
|
|
||||||
|
|
||||||
#pragma endregion MACs (Mips Atom Components)
|
#pragma endregion MACs (Mips Atom Components)
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,19 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(pad_atom_c);
|
|||||||
|
|
||||||
#pragma region MACs (Mips Atom Components)
|
#pragma region MACs (Mips Atom Components)
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_pad_set_centered_axes(AtomBuilder_R ab, U4 r_state, U4 r_scratch) atom_dbg_skip MipsAtomComp_Proc_(ac_pad_set_centered_axes, ab, {
|
FI_ Slice_MipsCode ac_pad_set_centered_axes(AtomBuilder_R ab, U4 r_state, U4 r_scratch) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
load_upper_i(r_scratch, (PadAxis_Centered_Word >> 16) & 0xFFFF),
|
load_upper_i(r_scratch, (PadAxis_Centered_Word >> 16) & 0xFFFF),
|
||||||
or_i_self( r_scratch, PadAxis_Centered_Word & 0xFFFF),
|
or_i_self( r_scratch, PadAxis_Centered_Word & 0xFFFF),
|
||||||
store_word( r_scratch, r_state, O_(PadState,axes)),
|
store_word( r_scratch, r_state, O_(PadState,axes)),
|
||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_pad_set_id_byte(AtomBuilder_R ab, U1 r_state, U1 r_id, U1 id_value) atom_dbg_skip MipsAtomComp_Proc_(ac_pad_set_id_byte, ab, {
|
FI_ Slice_MipsCode ac_pad_set_id_byte(AtomBuilder_R ab, U1 r_state, U1 r_id, U1 id_value)
|
||||||
|
atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
add_ui( r_id, R_0, id_value),
|
add_ui( r_id, R_0, id_value),
|
||||||
store_byte(r_id, r_state, O_(PadState,id)),
|
store_byte(r_id, r_state, O_(PadState,id)),
|
||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_pad_set_status(AtomBuilder_R ab, U4 r_tmp, U1 r_state, U4 pad_status) atom_dbg_skip MipsAtomComp_Proc_(ac_pad_set_status, ab, {
|
FI_ Slice_MipsCode ac_pad_set_status(AtomBuilder_R ab, U4 r_tmp, U1 r_state, U4 pad_status) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
add_ui( r_tmp, R_0, pad_status),
|
add_ui( r_tmp, R_0, pad_status),
|
||||||
store_word(r_tmp, r_state, O_(PadState,status)),
|
store_word(r_tmp, r_state, O_(PadState,status)),
|
||||||
})
|
})
|
||||||
@@ -30,7 +31,7 @@ FI_ Slice_MipsCode ac_pad_set_status(AtomBuilder_R ab, U4 r_tmp, U1 r_state, U4
|
|||||||
/* Invert r_buttons (active-low → active-high) and store to PadState.buttons.
|
/* Invert r_buttons (active-low → active-high) and store to PadState.buttons.
|
||||||
* r_buttons must already be loaded (the caller is responsible for filling the load-delay slot of
|
* r_buttons must already be loaded (the caller is responsible for filling the load-delay slot of
|
||||||
* the preceding load_half_u with an instruction that doesn't read r_buttons). */
|
* the preceding load_half_u with an instruction that doesn't read r_buttons). */
|
||||||
FI_ Slice_MipsCode ac_pad_store_inverted_buttons(AtomBuilder_R ab, U1 r_buttons, U1 r_pad_state) atom_dbg_skip MipsAtomComp_Proc_(ac_pad_store_inverted_buttons, ab, {
|
FI_ Slice_MipsCode ac_pad_store_inverted_buttons(AtomBuilder_R ab, U1 r_buttons, U1 r_pad_state) atom_dbg_skip MipsAtomComp_Proc_(ab, {
|
||||||
nor_u( r_buttons, r_buttons, R_0),
|
nor_u( r_buttons, r_buttons, R_0),
|
||||||
store_half( r_buttons, r_pad_state, O_(PadState,buttons)),
|
store_half( r_buttons, r_pad_state, O_(PadState,buttons)),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(hello_joypad_atom_c);
|
|||||||
#pragma region MACs (Mips Atom components)
|
#pragma region MACs (Mips Atom components)
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_put_disp_env(AtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
FI_ Slice_MipsCode ac_put_disp_env(AtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
||||||
MipsAtomComp_Proc_(ac_put_disp_env, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
// Emits 5 GP0 commands for buffer 0 (display_area = (0,0,320,240)).
|
// Emits 5 GP0 commands for buffer 0 (display_area = (0,0,320,240)).
|
||||||
// Sequence per libpsyx PutDispEnv: DrawArea TL → DrawArea BR → Mask → DrawArea TL → DrawArea BR
|
// Sequence per libpsyx PutDispEnv: DrawArea TL → DrawArea BR → Mask → DrawArea TL → DrawArea BR
|
||||||
mac_gcmd_push(gp0_word_draw_area_top_left_origin, reg_transfer, reg_base, port),
|
mac_gcmd_push(gp0_word_draw_area_top_left_origin, reg_transfer, reg_base, port),
|
||||||
@@ -37,7 +37,7 @@ MipsAtomComp_Proc_(ac_put_disp_env, ab, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
I_ Slice_MipsCode ac_put_draw_env(AtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
I_ Slice_MipsCode ac_put_draw_env(AtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
||||||
MipsAtomComp_Proc_(ac_put_draw_env, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
/*
|
/*
|
||||||
* ORIGIN: each code word corresponds to the EXACT value libpsyx's PutDrawEnv function would compute for the same DrawEnv settings.
|
* ORIGIN: each code word corresponds to the EXACT value libpsyx's PutDrawEnv function would compute for the same DrawEnv settings.
|
||||||
* References:
|
* References:
|
||||||
@@ -151,7 +151,7 @@ internal MipsAtom* resolve_look_at__input_and_sub_proc(AtomArena_R aa,
|
|||||||
U4 r_scratch
|
U4 r_scratch
|
||||||
, U4 r_target_ptr,U4 r_eye_ptr, U4 r_up_in_ptr
|
, U4 r_target_ptr,U4 r_eye_ptr, U4 r_up_in_ptr
|
||||||
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2, U4 r_tmp3
|
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2, U4 r_tmp3
|
||||||
) MipsAtom_Proc_(resolve_look_at__input_and_sub, aa, {
|
) MipsAtom_Proc_(aa, {
|
||||||
load_word(r_target_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,target)),
|
load_word(r_target_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,target)),
|
||||||
load_word(r_eye_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,eye)),
|
load_word(r_eye_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,eye)),
|
||||||
load_word(r_up_in_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,up_in)),
|
load_word(r_up_in_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,up_in)),
|
||||||
@@ -182,7 +182,7 @@ internal MipsAtom* resolve_look_at__cross_uz_up_in_to_right_proc(AtomArena_R aa,
|
|||||||
, U4 r_a, U4 r_b, U4 r_c /* load a.x/y/z; result out.x/y/z */
|
, U4 r_a, U4 r_b, U4 r_c /* load a.x/y/z; result out.x/y/z */
|
||||||
, U4 r_d /* load b.x */
|
, U4 r_d /* load b.x */
|
||||||
, U4 r_f, U4 r_g, U4 r_h /* r_f = &right (out ptr), r_g = &uz, r_h = &up_in */
|
, U4 r_f, U4 r_g, U4 r_h /* r_f = &right (out ptr), r_g = &uz, r_h = &up_in */
|
||||||
) MipsAtom_Proc_(resolve_look_at__cross_uz_up_in_to_right, aa, {
|
) MipsAtom_Proc_(aa, {
|
||||||
/* FIX: build packed RT22+RT33 with proper sign extension. */
|
/* FIX: build packed RT22+RT33 with proper sign extension. */
|
||||||
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_g = &uz */
|
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_g = &uz */
|
||||||
add_si(r_h, r_scratch, O_(ResolveLookAtScratch,up_in)), /* r_h = &up_in */
|
add_si(r_h, r_scratch, O_(ResolveLookAtScratch,up_in)), /* r_h = &up_in */
|
||||||
@@ -266,7 +266,7 @@ internal MipsAtom* resolve_look_at__cross_uz_ux_to_up_proc(AtomArena_R aa, U4 r_
|
|||||||
, U4 r_a, U4 r_b, U4 r_c /* load a.x/y/z; result out.x/y/z */
|
, U4 r_a, U4 r_b, U4 r_c /* load a.x/y/z; result out.x/y/z */
|
||||||
, U4 r_d /* load b.x */
|
, U4 r_d /* load b.x */
|
||||||
, U4 r_f, U4 r_g, U4 r_h /* r_f = &up (out ptr), r_g = &uz, r_h = &ux */
|
, U4 r_f, U4 r_g, U4 r_h /* r_f = &up (out ptr), r_g = &uz, r_h = &ux */
|
||||||
) MipsAtom_Proc_(resolve_look_at__cross_uz_ux_to_up, aa, {
|
) MipsAtom_Proc_(aa, {
|
||||||
/* Compute the three scratch pointers from r_scratch. */
|
/* Compute the three scratch pointers from r_scratch. */
|
||||||
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_g = &uz */
|
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_g = &uz */
|
||||||
add_si(r_h, r_scratch, O_(ResolveLookAtScratch,ux)), /* r_h = &ux */
|
add_si(r_h, r_scratch, O_(ResolveLookAtScratch,ux)), /* r_h = &ux */
|
||||||
@@ -363,7 +363,7 @@ internal MipsAtom* resolve_look_at__populate_proc(AtomArena_R aa
|
|||||||
, U4 r_scratch
|
, U4 r_scratch
|
||||||
, U4 r_pux, U4 r_puy, U4 r_puz
|
, U4 r_pux, U4 r_puy, U4 r_puz
|
||||||
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2
|
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2
|
||||||
) MipsAtom_Proc_(resolve_look_at__populate, aa, {
|
) MipsAtom_Proc_(aa, {
|
||||||
/* Pop look_at* (the matrix output) — advance R_TapePtr by 4 bytes. */
|
/* Pop look_at* (the matrix output) — advance R_TapePtr by 4 bytes. */
|
||||||
load_word(r_look_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)),
|
load_word(r_look_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)),
|
||||||
add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)),
|
add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)),
|
||||||
@@ -426,7 +426,7 @@ internal MipsAtom* resolve_look_at__matrix_vector_proc(AtomArena_R aa
|
|||||||
, U4 r_peye
|
, U4 r_peye
|
||||||
, U4 r_look_at
|
, U4 r_look_at
|
||||||
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2
|
, U4 r_tmp0, U4 r_tmp1, U4 r_tmp2
|
||||||
) MipsAtom_Proc_(resolve_look_at__matrix_vector, aa, {
|
) MipsAtom_Proc_(aa, {
|
||||||
/* === EXACT C11 ApplyMatrixLV replication ===
|
/* === EXACT C11 ApplyMatrixLV replication ===
|
||||||
* The C11 does:
|
* The C11 does:
|
||||||
* 1. ctc2 RT matrix (5 ctc2s to C2[0..4])
|
* 1. ctc2 RT matrix (5 ctc2s to C2[0..4])
|
||||||
@@ -517,7 +517,7 @@ I_ MipsAtom* resolve_look_at__trans_matrix_proc(AtomArena_R aa
|
|||||||
, U4 r_tmp0
|
, U4 r_tmp0
|
||||||
, U4 r_tmp1
|
, U4 r_tmp1
|
||||||
, U4 r_tmp2
|
, U4 r_tmp2
|
||||||
) MipsAtom_Proc_(resolve_look_at__trans_matrix, aa, {
|
) MipsAtom_Proc_(aa, {
|
||||||
/* Pop look_at* from tape. */
|
/* Pop look_at* from tape. */
|
||||||
// load_word(r_Vlook_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)),
|
// load_word(r_Vlook_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)),
|
||||||
// add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)),
|
// add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)),
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ ATOM_FILE_DEBUGGER_LINE_MARKER(hello_joypad_atom_c);
|
|||||||
#pragma region MACs (Mips Atom components)
|
#pragma region MACs (Mips Atom components)
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_put_disp_env(MipsAtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
FI_ Slice_MipsCode ac_put_disp_env(MipsAtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
||||||
MipsAtomComp_Proc_(ac_put_disp_env, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
// Emits 5 GP0 commands for buffer 0 (display_area = (0,0,320,240)).
|
// Emits 5 GP0 commands for buffer 0 (display_area = (0,0,320,240)).
|
||||||
// Sequence per libpsyx PutDispEnv: DrawArea TL → DrawArea BR → Mask → DrawArea TL → DrawArea BR
|
// Sequence per libpsyx PutDispEnv: DrawArea TL → DrawArea BR → Mask → DrawArea TL → DrawArea BR
|
||||||
mac_gcmd_push(gp0_word_draw_area_top_left_origin, reg_transfer, reg_base, port),
|
mac_gcmd_push(gp0_word_draw_area_top_left_origin, reg_transfer, reg_base, port),
|
||||||
@@ -36,7 +36,7 @@ MipsAtomComp_Proc_(ac_put_disp_env, ab, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
FI_ Slice_MipsCode ac_put_draw_env(MipsAtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
FI_ Slice_MipsCode ac_put_draw_env(MipsAtomBuilder_R ab, U4 reg_transfer, U4 reg_base, U2 port)
|
||||||
MipsAtomComp_Proc_(ac_put_draw_env, ab, {
|
MipsAtomComp_Proc_(ab, {
|
||||||
/*
|
/*
|
||||||
* ORIGIN: each code word corresponds to the EXACT value libpsyx's PutDrawEnv function would compute for the same DrawEnv settings.
|
* ORIGIN: each code word corresponds to the EXACT value libpsyx's PutDrawEnv function would compute for the same DrawEnv settings.
|
||||||
* References:
|
* References:
|
||||||
|
|||||||
@@ -2681,4 +2681,151 @@ function M.project_emission(body_text, component_index, word_counts, components)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- find_function_decl_for — backward walk for MipsAtomComp_Proc_ name extraction.
|
||||||
|
--
|
||||||
|
-- After the `sym` arg was dropped from MipsAtomComp_Proc_, the component name
|
||||||
|
-- is derived from the preceding `FI_ Slice_MipsCode ac_X(args)` function
|
||||||
|
-- declaration. This function walks backward from `before_pos` to find it.
|
||||||
|
--
|
||||||
|
-- Returns (raw_name, args_inner) or (nil, nil).
|
||||||
|
-- raw_name — e.g. "ac_load_word_imm"
|
||||||
|
-- args_inner — e.g. "AtomBuilder_R ab, Reg dst, U4 imm"
|
||||||
|
--
|
||||||
|
-- The walk finds the LAST "Slice_MipsCode" before before_pos, then skips
|
||||||
|
-- whitespace + qualifiers (FI_, atom_dbg_skip, comments) until it finds an
|
||||||
|
-- ident followed by "(". That ident is the function name; the parens contents
|
||||||
|
-- are the args.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
function M.find_function_decl_for(source, before_pos, slice_mips_code_len)
|
||||||
|
local search_pos = 1
|
||||||
|
local last_match = nil
|
||||||
|
while true do
|
||||||
|
local found = source:find("Slice_MipsCode", search_pos, true)
|
||||||
|
if not found or found >= before_pos then break end
|
||||||
|
last_match = found
|
||||||
|
search_pos = found + slice_mips_code_len
|
||||||
|
end
|
||||||
|
if not last_match then return nil, nil end
|
||||||
|
|
||||||
|
local pos = last_match + slice_mips_code_len
|
||||||
|
while pos < before_pos do
|
||||||
|
-- skip whitespace
|
||||||
|
while pos <= #source do
|
||||||
|
local c = source:sub(pos, pos)
|
||||||
|
if c == " " or c == "\t" or c == "\n" or c == "\r" then
|
||||||
|
pos = pos + 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if pos > #source then break end
|
||||||
|
-- skip line comments
|
||||||
|
if source:sub(pos, pos + 1) == "//" then
|
||||||
|
while pos <= #source and source:sub(pos, pos) ~= "\n" do pos = pos + 1 end
|
||||||
|
pos = pos + 1
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
-- skip block comments
|
||||||
|
if source:sub(pos, pos + 1) == "/*" then
|
||||||
|
local close = source:find("*/", pos + 2, true)
|
||||||
|
if not close then break end
|
||||||
|
pos = close + 2
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
-- try to read an ident
|
||||||
|
local ident, ident_end = M.read_ident(source, pos)
|
||||||
|
if not ident then break end
|
||||||
|
-- check if the next non-ws char after ident is "("
|
||||||
|
local next_pos = M.skip_ws_and_cmt(source, ident_end)
|
||||||
|
if source:sub(next_pos, next_pos) == "(" then
|
||||||
|
local inner = M.read_parens(source, next_pos)
|
||||||
|
if inner then
|
||||||
|
return ident, inner
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- ident not followed by "(" — it's a qualifier (FI_, atom_dbg_skip, etc); skip it
|
||||||
|
pos = ident_end
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
return nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- find_atom_proc_decl_for — backward walk for MipsAtom_Proc_ name extraction.
|
||||||
|
--
|
||||||
|
-- After the `sym` arg was dropped from MipsAtom_Proc_, the atom name is
|
||||||
|
-- derived from the preceding `MipsAtom* X_proc(args)` function declaration.
|
||||||
|
-- This function walks backward from `before_pos` to find it.
|
||||||
|
--
|
||||||
|
-- Returns (raw_name, args_inner) or (nil, nil).
|
||||||
|
-- raw_name — e.g. "normalize_v3s4" (the _proc suffix is stripped)
|
||||||
|
-- args_inner — e.g. "AtomArena_R aa, U4 r_scratch, ..."
|
||||||
|
--
|
||||||
|
-- The walk finds the LAST "MipsAtom*" before before_pos, then skips
|
||||||
|
-- whitespace + qualifiers (internal, I_, FI_, comments) until it finds an
|
||||||
|
-- ident followed by "(". That ident is the function name (with _proc suffix);
|
||||||
|
-- the suffix is stripped to get raw_name. The parens contents are the args.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
function M.find_atom_proc_decl_for(source, before_pos, mips_atom_ptr_len)
|
||||||
|
local search_pos = 1
|
||||||
|
local last_match = nil
|
||||||
|
while true do
|
||||||
|
-- plain=true: "*" is literal, no escaping needed
|
||||||
|
local found = source:find("MipsAtom*", search_pos, true)
|
||||||
|
if not found or found >= before_pos then break end
|
||||||
|
last_match = found
|
||||||
|
search_pos = found + mips_atom_ptr_len
|
||||||
|
end
|
||||||
|
if not last_match then return nil, nil end
|
||||||
|
|
||||||
|
local pos = last_match + mips_atom_ptr_len
|
||||||
|
while pos < before_pos do
|
||||||
|
-- skip whitespace
|
||||||
|
while pos <= #source do
|
||||||
|
local c = source:sub(pos, pos)
|
||||||
|
if c == " " or c == "\t" or c == "\n" or c == "\r" then
|
||||||
|
pos = pos + 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if pos > #source then break end
|
||||||
|
-- skip line comments
|
||||||
|
if source:sub(pos, pos + 1) == "//" then
|
||||||
|
while pos <= #source and source:sub(pos, pos) ~= "\n" do pos = pos + 1 end
|
||||||
|
pos = pos + 1
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
-- skip block comments
|
||||||
|
if source:sub(pos, pos + 1) == "/*" then
|
||||||
|
local close = source:find("*/", pos + 2, true)
|
||||||
|
if not close then break end
|
||||||
|
pos = close + 2
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
-- try to read an ident
|
||||||
|
local ident, ident_end = M.read_ident(source, pos)
|
||||||
|
if not ident then break end
|
||||||
|
-- check if the next non-ws char after ident is "("
|
||||||
|
local next_pos = M.skip_ws_and_cmt(source, ident_end)
|
||||||
|
if source:sub(next_pos, next_pos) == "(" then
|
||||||
|
local inner = M.read_parens(source, next_pos)
|
||||||
|
if inner then
|
||||||
|
-- strip the _proc suffix to get the atom name
|
||||||
|
local proc_suffix = "_proc"
|
||||||
|
if #ident > #proc_suffix and ident:sub(-#proc_suffix) == proc_suffix then
|
||||||
|
return ident:sub(1, #ident - #proc_suffix), inner
|
||||||
|
end
|
||||||
|
-- no _proc suffix — return as-is
|
||||||
|
return ident, inner
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- ident not followed by "(" — it's a qualifier; skip it
|
||||||
|
pos = ident_end
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
return nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -96,48 +96,21 @@ local M = {}
|
|||||||
-- so this file reads it forward rather than re-walking the source.
|
-- so this file reads it forward rather than re-walking the source.
|
||||||
-- ════════════════════════════════════════════════════════════════════════════
|
-- ════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
--- Find the args of the function declaration that immediately precedes a `MipsAtomComp_Proc_` invocation of the given name.
|
--- Find the args of the function declaration that immediately precedes a `MipsAtomComp_Proc_` invocation.
|
||||||
--- Returns the args string (e.g., `"U4 off, U4 code, U1 r, U1 g, U1 b"`) or nil if no function declaration is found.
|
--- Returns the args string (e.g., `"U4 off, U4 code, U1 r, U1 g, U1 b"`) or nil if no function declaration is found.
|
||||||
---
|
---
|
||||||
--- Convention: function form is
|
--- After the `sym` arg was dropped from MipsAtomComp_Proc_, the component name
|
||||||
--- `FI_ Slice_MipsCode ac_X(args) MipsAtomComp_Proc_(ac_X, { body })`
|
--- and the args both come from the preceding `FI_ Slice_MipsCode ac_X(args)`
|
||||||
--- We find the LAST occurrence of `"ac_X("` before `before_pos` and extract the args from inside the parens.
|
--- declaration. The shared `duffle.find_function_decl_for` helper does the
|
||||||
--- We then verify the preceding context ends with `Slice_MipsCode`
|
--- backward walk; this function returns just the args.
|
||||||
--- (the function-decl keyword with possible qualifiers between).
|
|
||||||
---
|
---
|
||||||
--- @param source string
|
--- @param source string
|
||||||
--- @param name string
|
--- @param name string (retained for signature stability; unused — the walk derives the name)
|
||||||
--- @param before_pos integer
|
--- @param before_pos integer
|
||||||
--- @return string|nil
|
--- @return string|nil
|
||||||
local function find_function_args_for(source, name, before_pos)
|
local function find_function_args_for(source, name, before_pos)
|
||||||
-- Find the LAST occurrence of `name + "("` in `source[1..before_pos]`.
|
local _, args_inner = duffle.find_function_decl_for(source, before_pos, #MIPS_ATOM)
|
||||||
local name_open = name .. "("
|
return args_inner
|
||||||
local last_idx = nil
|
|
||||||
local scan_pos = 1
|
|
||||||
while true do
|
|
||||||
-- Pass `before_pos + 1` so string.find only returns positions < before_pos + 1
|
|
||||||
-- (string.find's 4th arg `plain` is true; we use the 3rd arg `init` for the upper bound).
|
|
||||||
local found = source:find(name_open, scan_pos, true)
|
|
||||||
if not found or found >= before_pos then break end
|
|
||||||
last_idx = found
|
|
||||||
scan_pos = found + #name_open
|
|
||||||
end
|
|
||||||
if not last_idx then return nil end
|
|
||||||
|
|
||||||
-- Verify the preceding context ends with "MipsAtom" (with possible qualifiers between).
|
|
||||||
local before = source:sub(1, last_idx - 1)
|
|
||||||
local trimmed = duffle.trim(before)
|
|
||||||
if trimmed:sub(-#MIPS_ATOM) ~= MIPS_ATOM then
|
|
||||||
-- Preceding context is not a function declaration.
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local open_paren = last_idx + #name -- position of "("
|
|
||||||
-- scan: MipsAtom ac_X(
|
|
||||||
local inner = duffle.read_parens(source, open_paren)
|
|
||||||
-- scan: MipsAtom ac_X(<args>)
|
|
||||||
if not inner then return nil end
|
|
||||||
return inner
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ════════════════════════════════════════════════════════════════════════════
|
-- ════════════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
@@ -137,6 +137,16 @@ local QUALIFIER_KEYWORDS = {
|
|||||||
local AC_PREFIX = "ac_"
|
local AC_PREFIX = "ac_"
|
||||||
local AC_PREFIX_LEN = 3
|
local AC_PREFIX_LEN = 3
|
||||||
|
|
||||||
|
-- The function-decl keyword that precedes a MipsAtomComp_Proc_ call.
|
||||||
|
-- Used by the backward walk in duffle.find_function_decl_for.
|
||||||
|
local SLICE_MIPS_CODE = "Slice_MipsCode"
|
||||||
|
local SLICE_MIPS_CODE_LEN = #SLICE_MIPS_CODE
|
||||||
|
|
||||||
|
-- The return type that precedes a MipsAtom_Proc_ function declaration.
|
||||||
|
-- Used by the backward walk in duffle.find_atom_proc_decl_for.
|
||||||
|
local MIPS_ATOM_PTR = "MipsAtom*"
|
||||||
|
local MIPS_ATOM_PTR_LEN = #MIPS_ATOM_PTR
|
||||||
|
|
||||||
--- Strip the "ac_" prefix from a component name.
|
--- Strip the "ac_" prefix from a component name.
|
||||||
--- Returns the input unchanged if it doesn't start with the prefix.
|
--- Returns the input unchanged if it doesn't start with the prefix.
|
||||||
--- @param raw_name string
|
--- @param raw_name string
|
||||||
@@ -1357,7 +1367,11 @@ local function parse_mips_atom_comp_proc(source, pos, ident_end, line_of, out)
|
|||||||
local body, close_pos = duffle.read_braces(inner, last_brace_pos)
|
local body, close_pos = duffle.read_braces(inner, last_brace_pos)
|
||||||
if close_pos > #inner + 1 then return after_paren end
|
if close_pos > #inner + 1 then return after_paren end
|
||||||
|
|
||||||
local raw_name = inner:match("^%s*([%w_]+)") or "?"
|
-- The component name is derived from the preceding function declaration
|
||||||
|
-- (`FI_ Slice_MipsCode ac_X(...)`), not from the first macro arg (which
|
||||||
|
-- is now `ab`). The backward walk finds the function decl before open_paren.
|
||||||
|
local raw_name = duffle.find_function_decl_for(source, open_paren, SLICE_MIPS_CODE_LEN)
|
||||||
|
if not raw_name then raw_name = "?" end
|
||||||
local name = strip_ac_prefix(raw_name)
|
local name = strip_ac_prefix(raw_name)
|
||||||
-- Position of body[1] in source = open_paren + 1 (start of inner) + last_brace_pos + 1 (past '{').
|
-- Position of body[1] in source = open_paren + 1 (start of inner) + last_brace_pos + 1 (past '{').
|
||||||
local body_off = open_paren + 2 + last_brace_pos
|
local body_off = open_paren + 2 + last_brace_pos
|
||||||
@@ -1398,9 +1412,12 @@ local function parse_mips_atom_proc(source, pos, ident_end, line_of, out)
|
|||||||
local body, close_pos = duffle.read_braces(inner, last_brace_pos)
|
local body, close_pos = duffle.read_braces(inner, last_brace_pos)
|
||||||
if close_pos > #inner + 1 then return after_paren end
|
if close_pos > #inner + 1 then return after_paren end
|
||||||
|
|
||||||
-- The atom name is the FIRST ident of the args (matches MipsAtomComp_Proc_'s "first ident" rule).
|
-- The atom name is derived from the preceding function declaration
|
||||||
-- MipsAtom_Proc_ has no `ac_` prefix; `strip_ac_prefix` is a no-op for unprefixed names.
|
-- (`internal MipsAtom* X_proc(...)`), not from the first macro arg (which
|
||||||
local raw_name = inner:match("^%s*([%w_]+)") or "?"
|
-- is now `aa`). The backward walk finds the function decl before open_paren
|
||||||
|
-- and strips the `_proc` suffix.
|
||||||
|
local raw_name = duffle.find_atom_proc_decl_for(source, open_paren, MIPS_ATOM_PTR_LEN)
|
||||||
|
if not raw_name then raw_name = "?" end
|
||||||
local name = strip_ac_prefix(raw_name)
|
local name = strip_ac_prefix(raw_name)
|
||||||
-- Position of body[1] in source = open_paren + 1 (start of inner) + last_brace_pos + 1 (past '{').
|
-- Position of body[1] in source = open_paren + 1 (start of inner) + last_brace_pos + 1 (past '{').
|
||||||
local body_off = open_paren + 2 + last_brace_pos
|
local body_off = open_paren + 2 + last_brace_pos
|
||||||
|
|||||||
Reference in New Issue
Block a user