mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-07 08:08:49 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccdf1b832b | ||
|
|
4d177bc34d | ||
|
|
32a754cd06 | ||
|
|
407c7d352a |
@@ -459,4 +459,9 @@
|
||||
* ============================================================================*/
|
||||
|
||||
#define atom_offset(F, T) atom_offset_ ## F ## _ ## T
|
||||
#define atom_label(name) /* anchor — see metaprogram documentation */
|
||||
/* atom_label is a pure annotation for the metaprogram's offset calculations.
|
||||
* The macro expands to a C comment, so the C preprocessor strips it to
|
||||
* whitespace — NO instruction word is emitted in the asm. The metaprogram
|
||||
* still recognises the literal `atom_label(name)` token in source and
|
||||
* records the marker at the current pos. */
|
||||
#define atom_label(name) /* atom_label anchor: name */
|
||||
|
||||
+4
-1
@@ -1,4 +1,4 @@
|
||||
/* ============================================================================
|
||||
/* ============================================================================
|
||||
* duffle DSL Suffix Conventions
|
||||
* ============================================================================
|
||||
*
|
||||
@@ -442,6 +442,7 @@ enum { _C2_TX_SUBS_ = 0
|
||||
#define gte_cmdw_op (gte_cmd_base | enc_gte_cmd(gte_cmd_op ))
|
||||
#define gte_cmdw_mvmva (gte_cmd_base | enc_gte_cmd(gte_cmd_mvmva))
|
||||
|
||||
#define gte_cmdw_rotate_translate_perspective_single gte_cmdw_rtps
|
||||
#define gte_cmdw_rotate_translate_perspective_triple gte_cmdw_rtpt
|
||||
|
||||
/* PsyQ compatibility bits for AVSZ3 (Bits 20, 22, 24 must be set) */
|
||||
@@ -457,6 +458,8 @@ enum { _C2_TX_SUBS_ = 0
|
||||
#define gte_cmd_avsz4 0x2E
|
||||
#define gte_cmdw_avsz4 (gte_cmd_base | enc_gte_cmd(gte_cmd_avsz4) | gte_cmdw_psyq_avsz3_compat)
|
||||
|
||||
#define gte_cmdw_avg_sort_z4 gte_cmdw_avsz4
|
||||
|
||||
/**
|
||||
* @brief Loads a single SVECTOR to GTE vector register V0
|
||||
*
|
||||
|
||||
@@ -119,21 +119,66 @@ FI_ Slice_U4 tb_slice(TapeBuilder tb) { return (Sli
|
||||
, shift_lright(R_AT, R_AT, S_(polytag_len_bits)) \
|
||||
, store_word( R_AT, R_T1, O_(PolyTag,bf_addr_len)) /* OrderingTable[OTZ] = PrimCursor */
|
||||
|
||||
/* Words: 3; Emits one (cmd|color) word to R_PrimCursor at the given
|
||||
* byte offset. Internal helper used by the *_format_*_color macros.
|
||||
* Args: off = U4 byte offset, code = GP0 cmd byte (0 for c1/c2/c3 of
|
||||
* a Poly_G4), r/g/b = 8-bit RGB byte values. */
|
||||
#define mac_pack_color_word(off, code, r,g,b) \
|
||||
load_upper_i(R_AT, (code) << 8 | (b)) \
|
||||
, or_i_self( R_AT, ((g) << 8) | (r)) \
|
||||
, store_word( R_AT, R_PrimCursor, (off))
|
||||
|
||||
/* Words: 3; Emits the F3 command+color word (cmd byte | BLUE | GREEN | RED)
|
||||
* Args: _r, _g, _b are 8-bit RGB byte values (not raw 16-bit fields).
|
||||
* Migrated from hello_gte_tape.c; takes RGB form per the Phase 3
|
||||
* convention. */
|
||||
#define mac_format_f3_color(r,g,b) \
|
||||
load_upper_i(R_AT, gp0_cmd_poly_f3 << 8 | (b)) \
|
||||
, or_i_self( R_AT, ((g) << 8) | (r)) \
|
||||
, store_word( R_AT, R_PrimCursor, O_(Poly_F3,color))
|
||||
#define mac_format_f3_color(r,g,b) mac_pack_color_word(O_(Poly_F3,color), gp0_cmd_poly_f3, r,g,b)
|
||||
|
||||
/* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices to the F3 */
|
||||
#define mac_gte_store_f3() \
|
||||
gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_F3,p0)) \
|
||||
/* 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).
|
||||
* The macro name declares the pipeline position; check #6 (GTE state-
|
||||
* machine validation) verifies the call site matches the declaration. */
|
||||
#define mac_gte_store_f3_post_rtpt() \
|
||||
gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_F3,p0)) \
|
||||
, gte_sw(C2_SXY1, R_PrimCursor, O_(Poly_F3,p1)) \
|
||||
, gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_F3,p2))
|
||||
|
||||
/* Words: 12; Emits the four (code|color) words of a Poly_G4.
|
||||
* Args: rN,gN,bN are 8-bit RGB byte values for each of the 4 vertices. */
|
||||
#define mac_format_g4_color(r0,g0,b0, r1,g1,b1, r2,g2,b2, r3,g3,b3) \
|
||||
mac_pack_color_word(O_(Poly_G4,c0), gp0_cmd_poly_g4, r0,g0,b0) \
|
||||
, mac_pack_color_word(O_(Poly_G4,c1), 0, r1,g1,b1) \
|
||||
, mac_pack_color_word(O_(Poly_G4,c2), 0, r2,g2,b2) \
|
||||
, mac_pack_color_word(O_(Poly_G4,c3), 0, r3,g3,b3)
|
||||
|
||||
/* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices of the
|
||||
* G4 triangle portion to p0/p1/p2.
|
||||
* 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 (RTPS writes only to SXY2, but to keep the
|
||||
* three registers aligned with v0/v1/v2 you must store before RTPS).
|
||||
* The macro name declares the pipeline position; check #6 (GTE state-
|
||||
* machine validation) verifies the call site matches the declaration. */
|
||||
#define mac_gte_store_g4_p012_post_rtpt_pre_rtps() \
|
||||
gte_sw(C2_SXY0, R_PrimCursor, O_(Poly_G4,p0)) \
|
||||
, gte_sw(C2_SXY1, R_PrimCursor, O_(Poly_G4,p1)) \
|
||||
, gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p2))
|
||||
|
||||
/* Words: 1; Stores the V3 screen coord to the G4's p3 slot.
|
||||
* 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 — DO NOT read SXY0 here, that's the bug this name
|
||||
* prevents).
|
||||
* The macro name declares the pipeline position; check #6 (GTE state-
|
||||
* machine validation) verifies the call site matches the declaration.
|
||||
*
|
||||
* History: this macro was named `mac_gte_store_g4_p3` until 2026-07-09
|
||||
* when it was discovered to be reading C2_SXY0 (which held v0.screen)
|
||||
* instead of C2_SXY2 (which holds v3.screen after RTPS). The rename
|
||||
* encodes the pipeline position in the name so the next bug of this
|
||||
* class is impossible. */
|
||||
#define mac_gte_store_g4_p3_post_rtps() gte_sw(C2_SXY2, R_PrimCursor, O_(Poly_G4,p3))
|
||||
|
||||
#pragma endregion Macro Atom Components
|
||||
|
||||
#pragma region Mips Atom Builder
|
||||
|
||||
@@ -5,14 +5,24 @@
|
||||
#pragma region hello_gte_tape
|
||||
|
||||
|
||||
// --- atom: floor_tri (49 words) ---
|
||||
// --- atom: cube_g4_face (87 words) ---
|
||||
|
||||
#define _atom_offset_culling_floor_tri_exit 15
|
||||
#define _atom_offset_bounds_chk_floor_tri_exit 3
|
||||
#define _atom_offset_cull_cube_g4_face_exit 48
|
||||
#define _atom_offset_bounds_chk_cube_g4_face_exit 12
|
||||
|
||||
enum {
|
||||
atom_offset_culling_floor_tri_exit = _atom_offset_culling_floor_tri_exit,
|
||||
atom_offset_bounds_chk_floor_tri_exit = _atom_offset_bounds_chk_floor_tri_exit,
|
||||
atom_offset_cull_cube_g4_face_exit = _atom_offset_cull_cube_g4_face_exit,
|
||||
atom_offset_bounds_chk_cube_g4_face_exit = _atom_offset_bounds_chk_cube_g4_face_exit,
|
||||
};
|
||||
|
||||
// --- atom: floor_f3_face (66 words) ---
|
||||
|
||||
#define _atom_offset_culling_floor_f3_face_exit 29
|
||||
#define _atom_offset_bounds_chk_floor_f3_face_exit 13
|
||||
|
||||
enum {
|
||||
atom_offset_culling_floor_f3_face_exit = _atom_offset_culling_floor_f3_face_exit,
|
||||
atom_offset_bounds_chk_floor_f3_face_exit = _atom_offset_bounds_chk_floor_f3_face_exit,
|
||||
};
|
||||
|
||||
#pragma endregion hello_gte_tape
|
||||
|
||||
@@ -154,6 +154,10 @@ void gp_screen_init_c11(DoubleBuffer* screen_buf, S4* active_buf_id)
|
||||
|
||||
// Initialize and setup the GTE geometry offsets
|
||||
geom_init();
|
||||
// NOTE: geom_set_offset/geom_set_screen are kept as-is (the libgte versions
|
||||
// are known to be broken in this PSYQ 4.7 build — see report 2026-07-09).
|
||||
// The user's research wants the C-side non-tape reference to work as a
|
||||
// known-good baseline for comparison against the tape.
|
||||
geom_set_offset(ScreenRes_CenterX, ScreenRes_CenterY);
|
||||
geom_set_screen(ScreenZ);
|
||||
|
||||
@@ -201,12 +205,12 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
||||
S4 flag; //????
|
||||
|
||||
// Draw Cube
|
||||
if (1)
|
||||
if (0)
|
||||
{
|
||||
m3s2_rotation (& smem.cube.rot, & smem.tform_world);
|
||||
m3s2_translation(& smem.tform_world, & smem.cube.pos);
|
||||
m3s2_scale (& smem.tform_world, & smem.cube.scale);
|
||||
gte_matrix_set_rotation (& smem.tform_world);
|
||||
// gte_matrix_set_rotation (& smem.tform_world);
|
||||
gte_matrix_set_translation(& smem.tform_world);
|
||||
for (U4 face_id = 0; face_id < Cube_num_faces; face_id += 1)
|
||||
{
|
||||
@@ -241,7 +245,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
||||
smem.cube.rot.y += 30;
|
||||
}
|
||||
// Draw cube (tape method) - two triangles per face
|
||||
if (0)
|
||||
if (1)
|
||||
{
|
||||
m3s2_rotation (& smem.cube.rot, & smem.tform_world);
|
||||
m3s2_translation(& smem.tform_world, & smem.cube.pos);
|
||||
@@ -254,7 +258,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
||||
|
||||
LP_ U4 mem_temp_tape[512]; FArena tape_arena; farena_init(& tape_arena, slice_ut_arr(mem_temp_tape));
|
||||
TapeBuilder tb = tb_make_old(&tape_arena); tb_scope(& tb) {
|
||||
tb_emit(& tb, code_rbind_cube_tri);
|
||||
tb_emit(& tb, code_rbind_cube_g4_face);
|
||||
tb_data(& tb, prim_cursor);
|
||||
tb_data(& tb, u4_(smem.cube.faces));
|
||||
tb_data(& tb, u4_(smem.cube.verts));
|
||||
@@ -262,7 +266,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
||||
|
||||
for (U4 i = 0; i < Cube_num_faces; i++) {
|
||||
// Two triangles per quad face: (x,y,z) and (x,z,w)
|
||||
tb_emit(& tb, code_cube_tri);
|
||||
tb_emit(& tb, code_cube_g4_face);
|
||||
}
|
||||
|
||||
tb_emit(& tb, code_sync_primitive_arena);
|
||||
@@ -350,16 +354,16 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
||||
tb_emit(& tb, code_set_gte_world);
|
||||
tb_data(& tb, u4_(& smem.tform_world));
|
||||
|
||||
tb_emit(& tb, code_rbind_floor_tri);
|
||||
tb_emit(& tb, code_rbind_floor_f3_face);
|
||||
// TODO(Ed): Just use a single context struct ref
|
||||
tb_data(& tb, prim_cursor);
|
||||
tb_data(& tb, u4_(smem.floor.faces));
|
||||
tb_data(& tb, u4_(smem.floor.verts));
|
||||
tb_data(& tb, u4_(ordering_buf));
|
||||
for (U4 i = 0; i < Floor_num_faces; i++) {
|
||||
tb_emit(& tb, code_floor_tri);
|
||||
tb_emit(& tb, code_floor_f3_face);
|
||||
}
|
||||
// After code_floor_tri iterations complete, the primitive arena's used counter needs updating.
|
||||
// After code_floor_f3_face iterations complete, the primitive arena's used counter needs updating.
|
||||
tb_emit(& tb, code_sync_primitive_arena);
|
||||
tb_data(& tb, u4_(& pa->used));
|
||||
tb_data(& tb, prim_base);
|
||||
@@ -384,7 +388,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
||||
// 2. code_diag_color -> Tests OT and Prim Arena memory
|
||||
// 3. code_diag_gte -> Tests Vertex arrays and GTE Math
|
||||
// tb_emit(& tb, code_diag_yield);
|
||||
tb_emit(& tb, code_diag_color);
|
||||
// tb_emit(& tb, code_diag_color);
|
||||
// tb_emit(& tb, code_diag_gte);
|
||||
}
|
||||
}
|
||||
|
||||
+69
-104
@@ -22,7 +22,7 @@ typedef Struct_(Binds_CubeTri) {
|
||||
U4 VertBase;
|
||||
U4 OtBase;
|
||||
};
|
||||
internal MipsAtom_(rbind_cube_tri) {
|
||||
internal MipsAtom_(rbind_cube_g4_face) {
|
||||
/* Pop 4 arguments from the tape directly into the workspace registers */
|
||||
load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,PrimCursor)),
|
||||
load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,FaceCursor)),
|
||||
@@ -35,112 +35,78 @@ internal MipsAtom_(rbind_cube_tri) {
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* cube_tri — Draw one cube face (Gouraud-shaded quad) via the GTE tape pipeline
|
||||
* cube_g4_face — Draw one cube face (Gouraud-shaded quad) via the GTE tape pipeline
|
||||
* ============================================================================
|
||||
*
|
||||
* Reads 4 indices from R_FaceCur (V4_S2 = 8 bytes), loads 4 vertices into
|
||||
* the GTE, runs the PsyQ RotAverageNclip4 sequence, and renders a Poly_G4.
|
||||
*/
|
||||
atom_region (cube_tri, REGION_PRIM_ARENA)
|
||||
atom_group (cube_tri, GROUP_RENDER_PRIMS)
|
||||
atom_cadence (cube_tri, CADENCE_FRAME)
|
||||
atom_annot(cube_tri, phase_work,
|
||||
tape_regs(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase),
|
||||
tape_regs(R_PrimCursor, R_FaceCursor))
|
||||
atom_region (cube_g4_face, REGION_PRIM_ARENA)
|
||||
atom_group (cube_g4_face, GROUP_RENDER_PRIMS)
|
||||
atom_cadence (cube_g4_face, CADENCE_FRAME)
|
||||
atom_annot(cube_g4_face, phase_work,
|
||||
atom_reads( R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase),
|
||||
atom_writes(R_PrimCursor, R_FaceCursor))
|
||||
internal
|
||||
MipsAtom_(cube_tri) {
|
||||
/* ── 1. Load 4 face indices from R_FaceCur ──────────────────────────── */
|
||||
load_half_u(R_T0, R_FaceCursor, 0), /* T0 = face->x (vertex 0 index) */
|
||||
load_half_u(R_T1, R_FaceCursor, 2), /* T1 = face->y (vertex 1 index) */
|
||||
load_half_u(R_T2, R_FaceCursor, 4), /* T2 = face->z (vertex 2 index) */
|
||||
load_half_u(R_T3, R_FaceCursor, 6), /* T3 = face->w (vertex 3 index) */
|
||||
MipsAtom_(cube_g4_face) {
|
||||
/* ── 1. Load 4 face indices from R_FaceCur (V4_S2 = 8 bytes) ───────── */
|
||||
load_half_u(R_T0, R_FaceCursor, 0 * S_(S2)),
|
||||
load_half_u(R_T1, R_FaceCursor, 1 * S_(S2)),
|
||||
load_half_u(R_T2, R_FaceCursor, 2 * S_(S2)),
|
||||
load_half_u(R_T3, R_FaceCursor, 3 * S_(S2)),
|
||||
|
||||
/* ── 2. Load V0, V1, V2 into GTE ────────────────────────────────────── */
|
||||
/* V0 = verts[face->x] */
|
||||
shift_lleft(R_AT, R_T0, 3), add_u(R_AT, R_AT, R_VertBase),
|
||||
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
|
||||
gte_mv_to_data_r(R_V0, C2_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0),
|
||||
|
||||
/* V1 = verts[face->y] */
|
||||
shift_lleft(R_AT, R_T1, 3), add_u(R_AT, R_AT, R_VertBase),
|
||||
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
|
||||
gte_mv_to_data_r(R_V0, C2_VXY1), gte_mv_to_data_r(R_V1, C2_VZ1),
|
||||
|
||||
/* V2 = verts[face->z] */
|
||||
shift_lleft(R_AT, R_T2, 3), add_u(R_AT, R_AT, R_VertBase),
|
||||
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
|
||||
gte_mv_to_data_r(R_V0, C2_VXY2), gte_mv_to_data_r(R_V1, C2_VZ2),
|
||||
/* ── 2. Load V0, V1, V2 into GTE (parallel to mac_load_tri_verts) ── */
|
||||
mac_load_tri_verts(R_T0, R_T1, R_T2),
|
||||
|
||||
/* ── 3. RTPT — transforms V0/V1/V2 → SXY0/SXY1/SXY2 + SZ1/SZ2/SZ3 ─── */
|
||||
nop, nop, gte_cmdw_rtpt,
|
||||
nop2, gte_cmdw_rotate_translate_perspective_triple,
|
||||
|
||||
/* ── 4. NCLIP — backface culling on SXY0/SXY1/SXY2 (p0,p1,p2) ──────── */
|
||||
/* MUST be done BEFORE RTPS overwrites SXY0 with p3! */
|
||||
nop, nop, gte_cmdw_nclip,
|
||||
nop, nop,
|
||||
/* MUST be done BEFORE V3-RTPS overwrites SXY0 with p3. */
|
||||
nop2, gte_cmdw_nclip,
|
||||
|
||||
/* ── 5. Cull check: skip format/insert if MAC0 ≤ 0 (backface) ───────── */
|
||||
gte_mv_from_data_r(R_T0, C2_MAC0),
|
||||
nop,
|
||||
branch_le_zero(R_T0, 49), /* Skip 49 if MAC0 ≤ 0 (backface) → cull */
|
||||
nop, /* BD slot */
|
||||
nop2, gte_mv_from_data_r(R_T0, C2_MAC0),
|
||||
nop, /* COP2 stall */
|
||||
branch_le_zero(R_T0, atom_offset(cull, cube_g4_face_exit)),
|
||||
nop, /* BD slot */
|
||||
|
||||
/* ── 6. Store p0,p1,p2 to primitive buffer (BEFORE RTPS overwrites) ─── */
|
||||
store_word(R_0, R_PrimCursor, 0),
|
||||
/* ── 6. Format c0..c3 (color+code words) BEFORE V3-RTPS ─────────────── */
|
||||
store_word(R_0, R_PrimCursor, O_(Poly_G4, tag)),
|
||||
mac_format_g4_color(
|
||||
/* c0 magenta */ 0xFF, 0x00, 0xFF,
|
||||
/* c1 yellow */ 0xFF, 0xFF, 0x00,
|
||||
/* c2 cyan */ 0x00, 0xFF, 0xFF,
|
||||
/* c3 green */ 0x00, 0xFF, 0x00),
|
||||
|
||||
/* Word 1: c0 (BGR) + code = 0x38FF00FF (magenta, opcode 0x38) */
|
||||
load_upper_i(R_AT, 0x38FF), or_i(R_AT, R_AT, 0x00FF),
|
||||
store_word(R_AT, R_PrimCursor, 4),
|
||||
/* ── 7. Store p0..p2 BEFORE V3-RTPS overwrites SXY0 ─────────────────── */
|
||||
mac_gte_store_g4_p012_post_rtpt_pre_rtps(),
|
||||
|
||||
/* Word 2: p0 = SXY0 (stored BEFORE RTPS overwrites it) */
|
||||
gte_sw(C2_SXY0, R_PrimCursor, 8),
|
||||
/* ── 8. Load V3 = verts[face->w] into V0 ─────────────────────────────── */
|
||||
shift_lleft(R_AT, R_T3, v3s2_byteoff), add_u(R_AT, 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_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0),
|
||||
|
||||
/* Word 3: c1 (BGR) + pad = 0x0000FFFF (yellow) */
|
||||
load_upper_i(R_AT, 0x0000), or_i(R_AT, R_AT, 0xFFFF),
|
||||
store_word(R_AT, R_PrimCursor, 12),
|
||||
/* ── 9. RTPS — transforms V0 (now V3) → SXY0 (p3) + SZ3 ─────────────── */
|
||||
nop2, gte_cmdw_rotate_translate_perspective_single,
|
||||
mac_gte_store_g4_p3_post_rtps(),
|
||||
|
||||
/* Word 4: p1 = SXY1 */
|
||||
gte_sw(C2_SXY1, R_PrimCursor, 16),
|
||||
/* ── 10. AVSZ4 — average Z from SZ0/SZ1/SZ2/SZ3 ─────────────────────── */
|
||||
nop2, gte_cmdw_avg_sort_z4,
|
||||
nop2, gte_mv_from_data_r(R_T1, C2_OTZ),
|
||||
|
||||
/* Word 5: c2 (BGR) + pad = 0x00FFFF00 (cyan) */
|
||||
load_upper_i(R_AT, 0x00FF), or_i(R_AT, R_AT, 0xFF00),
|
||||
store_word(R_AT, R_PrimCursor, 20),
|
||||
/* ── 11. Bounds check OTZ < OrderingTbl_Len ─────────────────────────── */
|
||||
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, cube_g4_face_exit)), nop,
|
||||
|
||||
/* Word 6: p2 = SXY2 */
|
||||
gte_sw(C2_SXY2, R_PrimCursor, 24),
|
||||
/* ── 12. Insert into Ordering Table (length = 8 words for Poly_G4) ──── */
|
||||
mac_insert_ot_tag(R_T1, Poly_G4),
|
||||
|
||||
/* Word 7: c3 (BGR) + pad = 0x0000FF00 (green) */
|
||||
load_upper_i(R_AT, 0x0000), or_i(R_AT, R_AT, 0xFF00),
|
||||
store_word(R_AT, R_PrimCursor, 28),
|
||||
|
||||
/* ── 7. Load V3 = verts[face->w] into V0 ─────────────────────────────── */
|
||||
shift_lleft(R_AT, R_T3, 3), add_u(R_AT, R_AT, R_VertBase),
|
||||
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
|
||||
gte_mv_to_data_r(R_V0, C2_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0),
|
||||
|
||||
/* ── 8. RTPS — transforms V0 (now V3) → SXY0 (p3) + SZ0 ─────────────── */
|
||||
nop, nop, gte_cmdw_rtps,
|
||||
|
||||
/* Word 8: p3 = SXY0 (written AFTER RTPS with V3's screen coords) */
|
||||
gte_sw(C2_SXY0, R_PrimCursor, 32),
|
||||
|
||||
/* ── 9. AVSZ4 — average Z from SZ0/SZ1/SZ2/SZ3 ────────────── */
|
||||
nop, nop, gte_cmdw_avsz4,
|
||||
nop, nop,
|
||||
gte_mv_from_data_r(R_T1, C2_OTZ),
|
||||
|
||||
/* ── 10. Bounds check OTZ < 2048 ─────────────────────────────────────── */
|
||||
add_ui( R_AT, R_0, 2048),
|
||||
set_lt_u( R_AT, R_T1, R_AT),
|
||||
branch_equal(R_AT, R_0, 13), /* Skip 13 → land at add_ui(R_FaceCur,...) */
|
||||
nop, /* BD slot */
|
||||
|
||||
/* ── 11. Insert into Ordering Table (length = 8 for Poly_G4) ─────────── */
|
||||
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 */
|
||||
add_ui(R_FaceCursor, R_FaceCursor, 8), /* 4 × S2 = 8 bytes */
|
||||
/* ── 13. Advance cursors & yield (both branch targets land here) ────── */
|
||||
atom_label(cube_g4_face_exit)
|
||||
add_ui_self(R_PrimCursor, S_(Poly_G4)), /* 9 words = Poly_G4 */
|
||||
add_ui_self(R_FaceCursor, S_(S2) * 4), /* 4 × S2 = 8 bytes */
|
||||
mac_yield()
|
||||
};
|
||||
|
||||
@@ -150,14 +116,14 @@ typedef Struct_(Binds_FloorTri) {
|
||||
U4 VertBase;
|
||||
U4 OtBase;
|
||||
};
|
||||
atom_region(rbind_floor_tri, REGION_PRIM_ARENA)
|
||||
atom_group(rbind_floor_tri, GROUP_RENDER_FLOOR)
|
||||
atom_cadence(rbind_floor_tri, CADENCE_FRAME)
|
||||
atom_annot(rbind_floor_tri, phase_bind
|
||||
atom_region(rbind_floor_f3_face, REGION_PRIM_ARENA)
|
||||
atom_group(rbind_floor_f3_face, GROUP_RENDER_FLOOR)
|
||||
atom_cadence(rbind_floor_f3_face, CADENCE_FRAME)
|
||||
atom_annot(rbind_floor_f3_face, phase_bind
|
||||
, atom_reads()
|
||||
, atom_writes(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase))
|
||||
internal
|
||||
MipsAtom_(rbind_floor_tri) {
|
||||
MipsAtom_(rbind_floor_f3_face) {
|
||||
/* Pop 4 arguments from the tape directly into the workspace registers */
|
||||
load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,PrimCursor)),
|
||||
load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,FaceCursor)),
|
||||
@@ -167,27 +133,27 @@ MipsAtom_(rbind_floor_tri) {
|
||||
mac_yield()
|
||||
};
|
||||
|
||||
atom_region( floor_tri, REGION_PRIM_ARENA)
|
||||
atom_group( floor_tri, GROUP_RENDER_FLOOR)
|
||||
atom_cadence(floor_tri, CADENCE_FRAME)
|
||||
atom_annot( floor_tri, phase_work,
|
||||
atom_region( floor_f3_face, REGION_PRIM_ARENA)
|
||||
atom_group( floor_f3_face, GROUP_RENDER_FLOOR)
|
||||
atom_cadence(floor_f3_face, CADENCE_FRAME)
|
||||
atom_annot( floor_f3_face, phase_work,
|
||||
atom_reads( R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase),
|
||||
atom_writes(R_PrimCursor, R_FaceCursor))
|
||||
internal
|
||||
MipsAtom_(floor_tri) {
|
||||
MipsAtom_(floor_f3_face) {
|
||||
mac_load_tri_indices(R_T0, R_T1, R_T2),
|
||||
mac_load_tri_verts( R_T0, R_T1, R_T2),
|
||||
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)),
|
||||
nop,
|
||||
nop2, gte_mv_from_data_r(R_T0, C2_MAC0),
|
||||
nop,
|
||||
branch_le_zero(R_T0, atom_offset(culling, floor_f3_face_exit)), nop,
|
||||
/* Format Primitive */
|
||||
// mac_format_f3_color(0x20FF, 0xFFFF), // works
|
||||
mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white)
|
||||
mac_gte_store_f3(),
|
||||
mac_gte_store_f3_post_rtpt(),
|
||||
|
||||
/* Calculate Depth */
|
||||
nop2, gte_avg_sort_z3,
|
||||
@@ -195,15 +161,14 @@ MipsAtom_(floor_tri) {
|
||||
/* 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,
|
||||
branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_f3_face_exit)), nop,
|
||||
/* Insert into Ordering Table Linked List */
|
||||
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.
|
||||
|
||||
/* Advance Input Cursor & Yield (Both branch targets land here) */
|
||||
atom_label(floor_tri_exit)
|
||||
atom_label(floor_f3_face_exit)
|
||||
add_ui_self(R_FaceCursor, S_(S2) * 4), /* Advance Face Cursor (4 * S2 = 8 bytes) */
|
||||
mac_yield()
|
||||
};
|
||||
|
||||
@@ -18,10 +18,10 @@ WORD_COUNT(call_addr, 1)
|
||||
WORD_COUNT(branch_le_zero, 1)
|
||||
WORD_COUNT(branch_equal, 1)
|
||||
WORD_COUNT(add_ui, 1)
|
||||
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(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_word, 1)
|
||||
WORD_COUNT(load_half_u, 1)
|
||||
WORD_COUNT(store_word, 1)
|
||||
@@ -37,7 +37,7 @@ WORD_COUNT(shift_lleft_self, 1)
|
||||
WORD_COUNT(shift_lright, 1)
|
||||
WORD_COUNT(shift_aright, 1)
|
||||
WORD_COUNT(mask_upper, 2)
|
||||
WORD_COUNT(gte_mv_from_data_r, 1)
|
||||
WORD_COUNT(gte_mv_from_data_r, 1)
|
||||
WORD_COUNT(gte_mv_from_ctrl_r, 1)
|
||||
WORD_COUNT(gte_mv_to_data_r, 1)
|
||||
WORD_COUNT(gte_mv_to_ctrl_r, 1)
|
||||
@@ -45,10 +45,16 @@ WORD_COUNT(gte_sw, 1)
|
||||
WORD_COUNT(gte_cmdw_rtpt, 1)
|
||||
WORD_COUNT(gte_cmdw_nclip, 1)
|
||||
WORD_COUNT(gte_avg_sort_z3, 1)
|
||||
WORD_COUNT(sub_u, 1)
|
||||
WORD_COUNT(nop2, 2)
|
||||
WORD_COUNT(mac_load_tri_indices, 3)
|
||||
WORD_COUNT(mac_load_tri_verts, 18)
|
||||
WORD_COUNT(mac_format_f3_color, 3)
|
||||
WORD_COUNT(mac_gte_store_f3, 3)
|
||||
WORD_COUNT(mac_gte_store_f3_post_rtpt, 3)
|
||||
WORD_COUNT(mac_pack_color_word, 3)
|
||||
WORD_COUNT(mac_format_g4_color, 12)
|
||||
WORD_COUNT(mac_gte_store_g4_p012_post_rtpt_pre_rtps, 3)
|
||||
WORD_COUNT(mac_gte_store_g4_p3_post_rtps, 1)
|
||||
WORD_COUNT(mac_insert_ot_tag, 11)
|
||||
WORD_COUNT(mac_yield, 4)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user