diff --git a/code/duffle/dsl.atom.h b/code/duffle/dsl.atom.h index 598516c..0ffec4e 100644 --- a/code/duffle/dsl.atom.h +++ b/code/duffle/dsl.atom.h @@ -160,7 +160,7 @@ * ----------------------------------------------------------------------------*/ #define atom_bind(binds_struct) /* atom_bind(binds_struct) */ -#define Binds_(type) (tmpl(Binds,type) // TODO(Ed): Do we want to use this? +#define Binds_(type) (tmpl(Binds,type)) // TODO(Ed): Do we want to use this? /* ============================================================================ * atom_label / atom_offset — branch target machinery @@ -179,9 +179,3 @@ #define atom_offset(F, T) atom_offset_ ## F ## _ ## T // atom_label is a pure annotation for the metaprogram's offset calculations. #define atom_label(name) /* atom_label anchor: name */ - -// WIP: Atoms Assocated closely with each other to form a tape procedure. (Maybe also a phase in a procedure/pipeline?) - -#define AtomBundle_(name) Struct_(tmpl(AtomBundle,name)) -#define AtomBundle_Len(name) S_(tmpl(AtomBundle,name))/S_(MipsAtom*) -#define AtomBundleEntry_(bundle,entry) tmpl(bundle,entry) diff --git a/code/duffle/gen/macs.h b/code/duffle/gen/macs.h index 77e2c71..34daca9 100644 --- a/code/duffle/gen/macs.h +++ b/code/duffle/gen/macs.h @@ -228,21 +228,21 @@ WORD_COUNT(mac_gte_op_cross_v3s4, 13) WORD_COUNT(mac_gte_store_f3, 3) /* atom_dbg_skip */ -#define mac_gte_load_tri_verts(r_vert_base, r_v0, r_v1, r_v2) \ - shift_lleft(R_AT, r_v0, v3s2_byteoff) \ -, add_u_self(R_AT, r_vert_base) \ +#define mac_gte_load_tri_verts(vbase, v0, v1, v2) \ + shift_lleft(R_AT, v0, v3s2_byteoff) \ +, add_u_self(R_AT, vbase) \ , load_word(R_V0, R_AT, O_(V3_S2,x)) \ , load_word(R_V1, R_AT, O_(V3_S2,z)) \ , LdSlot_ 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) \ +, shift_lleft(R_AT, v1, v3s2_byteoff) \ +, add_u_self(R_AT, vbase) \ , load_word(R_V0, R_AT, O_(V3_S2,x)) \ , load_word(R_V1, R_AT, O_(V3_S2,z)) \ , LdSlot_ 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) \ +, shift_lleft(R_AT, v2, v3s2_byteoff) \ +, add_u_self(R_AT, vbase) \ , load_word(R_V0, R_AT, O_(V3_S2,x)) \ , load_word(R_V1, R_AT, O_(V3_S2,z)) \ , LdSlot_ gte_mv_to_data_r(R_V0, C2_VXY2) \ diff --git a/code/duffle/gte.atom.c b/code/duffle/gte.atom.c index 8a1a516..531dcbe 100644 --- a/code/duffle/gte.atom.c +++ b/code/duffle/gte.atom.c @@ -63,10 +63,10 @@ FI_ Slice_MipsCode ac_gte_store_f3(AtomBuilder_R ab, U4 r_primitive_cursor) atom }) /* 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_(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)), LdSlot_ 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)), LdSlot_ 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)), LdSlot_ gte_mv_to_data_r(R_V0, C2_VXY2), gte_mv_to_data_r(R_V1, C2_VZ2), +I_ Slice_MipsCode ac_gte_load_tri_verts(AtomBuilder_R ab, Reg vbase, Reg v0, Reg v1, Reg v2) atom_dbg_skip MipsAtomComp_Proc_(ab, { + shift_lleft(R_AT, v0, v3s2_byteoff), add_u_self(R_AT, vbase), load_word(R_V0, R_AT, O_(V3_S2,x)), load_word(R_V1, R_AT, O_(V3_S2,z)), LdSlot_ gte_mv_to_data_r(R_V0, C2_VXY0), gte_mv_to_data_r(R_V1, C2_VZ0), + shift_lleft(R_AT, v1, v3s2_byteoff), add_u_self(R_AT, vbase), load_word(R_V0, R_AT, O_(V3_S2,x)), load_word(R_V1, R_AT, O_(V3_S2,z)), LdSlot_ gte_mv_to_data_r(R_V0, C2_VXY1), gte_mv_to_data_r(R_V1, C2_VZ1), + shift_lleft(R_AT, v2, v3s2_byteoff), add_u_self(R_AT, vbase), load_word(R_V0, R_AT, O_(V3_S2,x)), load_word(R_V1, R_AT, O_(V3_S2,z)), LdSlot_ gte_mv_to_data_r(R_V0, C2_VXY2), gte_mv_to_data_r(R_V1, C2_VZ2), }) /* Words: 3; Stores the 3 transformed (V2_S2 screen) vertices of the @@ -267,11 +267,11 @@ internal S2 const gte_normalize_sqr_tbl[192] align_(2) = { 0x0820, 0x081c, 0x0818, 0x0814, 0x0810, 0x080c, 0x0808, 0x0804, }; -typedef Struct_(Binds_NormalizeV3S4) { +typedef Struct_(Binds_normalize_v3s4) { U2 src_offset; /* offset of src V3_S4 within the BIOS scratchpad */ U2 dst_offset; /* offset of dst V3_S4 within the BIOS scratchpad */ }; -typedef Struct_(RegUse_build_normalize_v3s4) { +typedef Struct_(RegUse_normalize_v3s4) { union { Reg_(V3_S4) res, src; }; union { Reg r0, src_ptr, mac2; }; union { Reg r1, dst_ptr; }; @@ -282,13 +282,13 @@ typedef Struct_(RegUse_build_normalize_v3s4) { }; /* ─── Full normalize (all 4 stages inline) ─── * Generic 4-stage GTE normalize (SQR → sum+LZCR → align+sqrtbl → GPF+srav). */ -internal MipsAtom* build_normalize_v3s4(AtomArena_R aa, RegUse_build_normalize_v3s4 r) +internal MipsAtom* normalize_v3s4(AtomArena_R aa, RegUse_normalize_v3s4 r) MipsAtom_Proc_(aa, { - load_half(r.src_offset, R_TapePtr, O_(Binds_NormalizeV3S4, src_offset)), - load_half(r.dst_offset, R_TapePtr, O_(Binds_NormalizeV3S4, dst_offset)), + load_half(r.src_offset, R_TapePtr, O_(Binds_normalize_v3s4, src_offset)), + load_half(r.dst_offset, R_TapePtr, O_(Binds_normalize_v3s4, dst_offset)), LdSlot_ add_u(r.src_ptr, R_ScratchBase, r.src_offset), LdSlot_ add_u(r.dst_ptr, R_ScratchBase, r.dst_offset), - LdSlot_ add_ui_self(R_TapePtr, S_(Binds_NormalizeV3S4)), + LdSlot_ add_ui_self(R_TapePtr, S_(Binds_normalize_v3s4)), mac_load_v3s4(r.src, r.src_ptr, 0), diff --git a/code/duffle/lottes_tape.h b/code/duffle/lottes_tape.h index 585cb87..963e5e0 100644 --- a/code/duffle/lottes_tape.h +++ b/code/duffle/lottes_tape.h @@ -163,6 +163,12 @@ typedef Slice_(MipsAtom); // Used for trivial mappings from one atom component proc to the command of a more baser (meant for type-mapping) #define MipsAtomComp_ProcMap_(ab, base_command) atom_dbg_skip MipsAtomComp_Proc_(ab, {base_command }) +// WIP: Atoms Assocated closely with each other to form a tape procedure. (Maybe also a phase in a procedure/pipeline?) + +#define AtomBundle_(name) Struct_(tmpl(AtomBundle,name)) +#define AtomBundle_Len(name) S_(tmpl(AtomBundle,name))/S_(MipsAtom*) +#define AtomBundleEntry_(bundle,entry) tmpl(bundle,entry) + /* 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. Place `ATOM_FILE_LINE_MARKER();` once at file scope in any `.atom.c` that defines atoms. @@ -247,6 +253,9 @@ FI_ void tb_data(TapeBuilder* tb, U4 data) { u4_r(tb->ptr)[tb->used] = u4 FI_ void tb_bind(TapeBuilder* tb, Slice data) { mem_copy(tb->ptr + tb->used * S_(MipsCode), u4_(data.ptr), data.len); tb->used += data.len / S_(MipsCode); } #define tb_bind_(tb,type,...) tb_bind(tb, (Slice){ (B1*)(& (type){__VA_ARGS__}), S_(type) }); static_assert(S_(type) % S_(MipsCode) == 0) +#define tb_emit_wbind_(tb,atom,...) tb_emit(tb,atom); tb_bind_(tb,tmpl(Binds,atom),__VA_ARGS__) +#define tb_emit_wbind2_(tb,atom,type,...) tb_emit(tb,atom); tb_bind_(tb,type,__VA_ARGS__) + FI_ Tape tb_end (TapeBuilder* tb) { tb_emit(tb,tape_exit); return (Tape){ C_(U4*,tb->ptr), tb->used }; } FI_ Tape tb_slice(TapeBuilder tb) { return (Tape){ C_(U4*,tb.ptr), tb.used }; } #define tb_scope(tb) for(U4 tbs_once=0;tbs_once==0;++tbs_once,tb_emit(tb,tape_exit)) diff --git a/code/duffle/pad.h b/code/duffle/pad.h index 014abee..41cafa3 100644 --- a/code/duffle/pad.h +++ b/code/duffle/pad.h @@ -4,10 +4,7 @@ # include "math.h" #endif -/* PSX button bit positions — 1:1 with PSX-SPX docs at docs/psx-spx/docs/controllersandmemorycards.md:405-421. - * Wire is active-low (0 = pressed). - * The decoder atom computes buttons = (~raw_buttons) & 0xFFFF; - * active-low-to-active-high inversion is applied bit-by-bit. */ +// PSX button bit positions: PSX-SPX docs/psx-spx/docs/controllersandmemorycards.md:405-421. typedef Enum_(U2, PadBtns) { Bit_(Pad_Select, 0), Bit_(Pad_L3, 1), @@ -62,11 +59,7 @@ typedef Enum_(U4, PadStatus) { PadStatus_Invalid, }; -/* Distinct from the game-facing PadStatus enum: PadRawStatus_Ok and PadRawStatus_Timeout are raw BIOS values; - * PadStatus_* are game-facing post-decode states. PadUnknownId_Sentinel is written by the decoder - * when the controller id does not match any known controller type. - * PadAxisCentered_Word: Four-byte 0x80 pattern used to clear / center - * four byte axes at PadState.left_x through PadState.right_y. */ +// Distinct from the game-facing PadStatus enum: PadRawStatus_Ok and PadRawStatus_Timeout are raw BIOS values typedef Enum_(U1, PadRawStatus) { PadRawStatus_Ok = 0x00, PadRawStatus_Timeout = 0xFF, diff --git a/code/duffle/psyq.h b/code/duffle/psyq.h index 3fdfd44..c0a99f3 100644 --- a/code/duffle/psyq.h +++ b/code/duffle/psyq.h @@ -104,7 +104,7 @@ void gte_matrix_set_translation(MT3_S2S4* mat) asm("SetTransMatrix"); // Einheit, Metrication to unit vector. "Normalization", not Orthogonal "Normal, Normalis". Directionalization. // RGA(Lengyel): Normalize the bulk of a zero-weight direction. This is not finite-point unitization (which forces w=1). -S4 normalize_v3s4(V3_S4* v0, V3_S4* v1) asm("VectorNormal"); +S4 psy_normalize_v3s4(V3_S4* v0, V3_S4* v1) asm("VectorNormal"); // RGA(Lengyel): Apply the matrix expansion of a rigid transformation. // Motor antiproduct is equivalent for unitized points; LA form is what GTE consumes. diff --git a/code/hello_camera/hello_camera.atom.c b/code/hello_camera/hello_camera.atom.c index 080f7b7..fa1016b 100644 --- a/code/hello_camera/hello_camera.atom.c +++ b/code/hello_camera/hello_camera.atom.c @@ -155,7 +155,7 @@ atom_info(atom_bind(Binds_ResolveLookAtSub)) MipsAtom_Proc_(aa, { }) typedef Struct_(Binds_ResolveLookAt_PopulateMT3S4S2) { - U4 look_at; /* MT3_S2S4* — destination matrix address */ + MT3_S2S4* look_at; /* MT3_S2S4* — destination matrix address */ }; typedef Struct_(RegUse_resolve_look_at_populate_mt3s4s2) { Reg look_at; diff --git a/code/hello_camera/hello_camera.c b/code/hello_camera/hello_camera.c index 3c92459..580178c 100644 --- a/code/hello_camera/hello_camera.c +++ b/code/hello_camera/hello_camera.c @@ -80,9 +80,6 @@ typedef Struct_(SMemory) { PadBiosRaw pad_raw[2]; PadState pad[2]; - // TODO(Ed): We don't need this we can just cast at any point an address to a desired view of scratchpad, we have the address. - U4_V scratchpad; // d-cache - U1 ct_init_atom_mem[CT_InitAtomMem_Size]; MipsAtom* normalize_v3s4; MipsAtom* gte_cross_v3s4; @@ -114,7 +111,7 @@ I_ void resolve_look_at_c11(MT3_S2S4* look_at, P3_S4* eye, P3_S4* target, V3_S4* V3_S4 pos, off; forward = target[0]; sub_v3s4(& forward, eye[0]); // RGA(Lengyel): Affine point - point = zero-weight direction. - normalize_v3s4(& forward, & uz); // RGA(Lengyel): Normalize the direction bulk. Not finite-point unitization. + psy_normalize_v3s4(& forward, & uz); // RGA(Lengyel): Normalize the direction bulk. Not finite-point unitization. cross_v3s4(& uz, up_in, & right); normalize_v3s4(& right, & ux); // RGA(Lengyel): Complement(Wedge(forward, up_in)) -> right axis. cross_v3s4(& uz, & ux, & up); normalize_v3s4(& up, & uy); // RGA(Lengyel): Complement(Wedge(forward, right)) -> up axis. @@ -149,8 +146,8 @@ internal void compile_init_atoms(void) { }); regfile_reset(& rf); - smem.normalize_v3s4 = build_normalize_v3s4(& ab, - RegUse_(build_normalize_v3s4) { + smem.normalize_v3s4 = normalize_v3s4(& ab, + RegUse_(normalize_v3s4) { .res = ralloc_v3(), .r0 = ralloc(), .r1 = ralloc(), @@ -208,37 +205,36 @@ I_ void resolve_look_at(TapeBuilder_R tb, MT3_S2S4* look_at, P3_S4* eye, P3_S4* /* Typed view of the scratchpad for field-address arithmetic. */ ResolveLookAtScratch* sp = C_scratch(ResolveLookAtScratch*); AtomBundle_resolve_look_at_R bundle = C_(void*, smem.resolve_look_at_bundle); - tb_emit(tb, bundle->input_and_sub); { - tb_data(tb, u4_(target)); - tb_data(tb, u4_(eye)); - tb_data(tb, u4_(up_in)); - } - tb_emit(tb, bundle->normalize_fwd_uz); { - // tb_data(tb, u4_(O_(ResolveLookAtScratch, fwd) | (O_(ResolveLookAtScratch, uz) << 16))); - tb_bind_(tb, Binds_NormalizeV3S4, - .src_offset = O_(ResolveLookAtScratch,fwd), - .dst_offset = O_(ResolveLookAtScratch,uz), - ); - } - tb_emit(tb, bundle->cross_to_right); { - tb_data(tb, u4_(& sp->uz)); - tb_data(tb, u4_(& sp->up_in)); - tb_data(tb, u4_(& sp->right)); - } - tb_emit(tb, bundle->normalize_right_ux); { - tb_data(tb, u4_(O_(ResolveLookAtScratch, right) | (O_(ResolveLookAtScratch, ux) << 16))); - } - tb_emit(tb, bundle->cross_to_up); { - tb_data(tb, u4_(& sp->uz)); - tb_data(tb, u4_(& sp->ux)); - tb_data(tb, u4_(& sp->up)); - } - tb_emit(tb, bundle->normalize_up_uy); { - tb_data(tb, u4_(O_(ResolveLookAtScratch, up) | (O_(ResolveLookAtScratch, uy) << 16))); - } - tb_emit(tb, bundle->populate_mt3s4s2); { - tb_data(tb, u4_(look_at)); - } + tb_emit(tb, bundle->input_and_sub); tb_bind_(tb, Binds_ResolveLookAtSub, + .target = target, + .eye = eye, + .up_in = up_in, + ); + tb_emit(tb, bundle->normalize_fwd_uz); tb_bind_(tb, Binds_normalize_v3s4, + .src_offset = O_(ResolveLookAtScratch,fwd), + .dst_offset = O_(ResolveLookAtScratch,uz), + ); + tb_emit(tb, bundle->cross_to_right); tb_bind_(tb, Binds_gte_cross_v3s4, + .src_a = & sp->uz, + .src_b = & sp->up_in, + .out = & sp->right, + ); + tb_emit(tb, bundle->normalize_right_ux); tb_bind_(tb, Binds_normalize_v3s4, + .src_offset = O_(ResolveLookAtScratch,right), + .dst_offset = O_(ResolveLookAtScratch,ux), + ); + tb_emit(tb, bundle->cross_to_up); tb_bind_(tb, Binds_gte_cross_v3s4, + .src_a = & sp->uz, + .src_b = & sp->ux, + .out = & sp->up, + ); + tb_emit(tb, bundle->normalize_up_uy); tb_bind_(tb, Binds_normalize_v3s4, + .src_offset = O_(ResolveLookAtScratch,up), + .dst_offset = O_(ResolveLookAtScratch,uy), + ); + tb_emit(tb, bundle->populate_mt3s4s2); tb_bind_(tb, Binds_ResolveLookAt_PopulateMT3S4S2, + .look_at = look_at, + ); } FI_ void camera_look_at(TapeBuilder_R tb, Camera* c, P3_S4* target, V3_S4* up_in) { resolve_look_at(tb, & c->look_at, & c->pos, target, up_in); } @@ -397,8 +393,6 @@ GCC_OPTIMIZATION_DISABLE int main(void) { smem = (SMemory){0}; - // TODO(Ed): remove this field we don't need it in smem. - smem.scratchpad = C_(U4_V, Scratchpad_Loc); // smem.primitives.used = 0; // smem.active_buf_id = 0; smem.cam.pos = v3s4(500, -1000, -1500);