diff --git a/code/duffle/gp.h b/code/duffle/gp.h index 473d41f..2b4c1de 100644 --- a/code/duffle/gp.h +++ b/code/duffle/gp.h @@ -49,9 +49,8 @@ /* IO base address (KSEG2 0x1F800000+ for the I/O register region). * The 16-bit upper half `IO_BASE_ADDR_HI16` is the form used by * tape-side macros that pin a register to hold the IO base and access - * ports via offsets — `lui $reg, 0x1F80` (1 word) then `sw $data, - * GPIO_PORT*_OFFSET($reg)` (1 word). Mirrors the `IO_BASE_ADDR equ - * 0x1F80` + `gpio_port0 equ 0x1810` pattern from graphics_hello/gp.s. */ + * ports via offsets — `lui $reg, 0x1F80` (1 word) then `sw $data, GPIO_PORT*_OFFSET($reg)` (1 word). + * Mirrors the `IO_BASE_ADDR equ 0x1F80` + `gpio_port0 equ 0x1810` pattern from graphics_hello/gp.s. */ enum { IO_BASE_ADDR = 0x1F800000, /* full 32-bit I/O region base */ IO_BASE_ADDR_HI16 = 0x1F80, /* fits in a single `lui $reg, 0x1F80` */ @@ -77,13 +76,12 @@ enum { * GP0 command byte constants + Layer 1 (GPU bitfield shifts) * ============================================================================ * - * 8-bit GP0 opcodes (the upper byte of a primitive's first word). - * These are the BYTE only; pre-baked 32-bit words are in §10.4. + * 8-bit GP0 opcodes (the upper byte of a primitive's first word). These are the BYTE only. * The layer-1 bitfield-layout constants live in the same enum block - * so the encoder in §10.4 can reference them by name. NO macro body - * past this point uses a raw shift or raw mask — every shift/width/mask - * is named here, named once. Mirrors the OPCODE_SHIFT / RS_SHIFT / - * REG_MASK convention from mips.h. + * so the encoder can reference them by name. + * NO macro body past this point uses a raw shift or raw mask. + * Every shift/width/mask is named here, named once. + * Mirrors the OPCODE_SHIFT / RS_SHIFT / REG_MASK convention from mips.h. * ============================================================================ */ enum { gp0_cmd_Nop = 0x00, @@ -147,19 +145,19 @@ enum { * ============================================================================ * * Layer 1.5 encoders take one field's value, mask it to its own width, - * and shift it to its own position. Mirrors `enc_op` / `enc_rs` / - * `enc_rt` in mips.h and `enc_gte_sf` / `enc_gte_mx` in gte.h. Layer-2 composite encoders - * OR the per-field encoders together; layer-3 semantic macros delegate to the composites. + * and shift it to its own position. + * Mirrors `enc_op` / `enc_rs` / `enc_rt` in mips.h and `enc_gte_sf` / `enc_gte_mx` in gte.h. + * Layer-2 composite encoders OR the per-field encoders together; layer-3 semantic macros delegate to the composites. * No raw shifts or magic numbers in any macro body below this point. * ============================================================================ */ /* ---- Layer 1.5: per-field encoders ---- */ -#define enc_gp0_cmd(cmd) (((cmd) & gp0_cmd_mask) << gp0_cmd_shift) +#define enc_gp0_cmd(cmd) (((cmd) & gp0_cmd_mask) << gp0_cmd_shift) -#define enc_gp0_color_cmd(cmd) (((cmd) & gp0_color_cmd_mask) << gp0_color_cmd_shift) -#define enc_gp0_color_r(r) (((r) & gp0_color_red_mask) << gp0_color_red_shift) -#define enc_gp0_color_g(g) (((g) & gp0_color_green_mask) << gp0_color_green_shift) -#define enc_gp0_color_b(b) (((b) & gp0_color_blue_mask) << gp0_color_blue_shift) +#define enc_gp0_color_cmd(cmd) (((cmd) & gp0_color_cmd_mask) << gp0_color_cmd_shift) +#define enc_gp0_color_r(r) (((r) & gp0_color_red_mask) << gp0_color_red_shift) +#define enc_gp0_color_g(g) (((g) & gp0_color_green_mask) << gp0_color_green_shift) +#define enc_gp0_color_b(b) (((b) & gp0_color_blue_mask) << gp0_color_blue_shift) /* ---- Layer 2: composite encoders ---- */ #define enc_color_word(cmd, r, g, b) (enc_gp0_color_cmd(cmd) | enc_gp0_color_r(r) | enc_gp0_color_g(g) | enc_gp0_color_b(b)) @@ -285,9 +283,7 @@ enum { * Pre-baked GPU state words * ============================================================================ * - * Common command words for boot-time GPU init and standard - * display configurations. Each one is a pure compile-time integer - * constant ready to drop into a `.word` directive. + * Common command words for boot-time GPU init and standard display configurations. * ============================================================================ */ /* ---- Display enable (1-bit payload on DisplayEnable cmd) ---- */ @@ -327,7 +323,7 @@ enum { #define gp1_word_vertical_range_pal enc_gp1_vrange_word(gp1_vrange_PAL_y1, gp1_vrange_PAL_y2) /* ---- Draw-mode setting (TPage / draw-area allowance) ---- */ -/* The pre-baked "drawing enabled" word is the standard post-init state. */ +/* The "drawing enabled" word is the standard post-init state. */ enum { gp0_DrawMode_DrawToDispBit = 10, }; @@ -361,16 +357,14 @@ enum { * Primitive structs (8 polygon variants + tag) * ============================================================================ * - * Each struct follows the GPU-documented memory layout for the corresponding - * primitive command. The PolyTag is the OT-link header; the rest of the - * struct is the primitive's body. + * Each struct follows the GPU-documented memory layout for the corresponding primitive command. + * The PolyTag is the OT-link header; the rest of the struct is the primitive's body. * - * The current working layouts match the existing demo (floor_tri uses - * Poly_F3; cube_tri uses Poly_G4). They are NOT necessarily byte-identical - * to the PSX-SPX reference layout — the demo layout uses color+vertex - * interleaving that doesn't match the standard PSX SDK file format. For - * PSX-SDK file compatibility, the textured variants (FT*, GT*) would need - * layout adjustments; out of scope for this track. + * The current working layouts match the existing demo + * (floor_tri uses Poly_F3; cube_tri uses Poly_G4). + * They are NOT necessarily byte-identical to the PSX-SPX reference layout. + * The demo layout uses color+vertex interleaving that doesn't match the standard PSX SDK file format. + * For PSX-SDK file compatibility, the textured variants (FT*, GT*) would need layout adjustments. * ============================================================================ */ /* ---------- RGB8 (3-byte packed color) ---------- */ @@ -392,15 +386,14 @@ typedef Struct_(PolyTag) { }; }; -/* DSL cast convention: every cast uses `C_()`, every pointer qualifier - * is `R_` (restrict) or `V_` (volatile). No raw C-style casts. RHS values - * are assumed to be `U4` — caller passes a `U4` directly. */ +/* DSL cast convention: every cast uses `C_()`, every pointer qualifier is `R_` (restrict) or `V_` (volatile). + * No raw C-style casts. RHS values are assumed to be `U4` — caller passes a `U4` directly. */ #define set_len(tag,v) (C_(PolyTag_R,tag)->len = u4_(v)) #define set_addr(tag,v) (C_(PolyTag_R,tag)->addr = u4_(v)) /* `set_code` is no longer in the new PolyTag design — the code byte lives * in the primitive body (e.g. `((Poly_F3*)(p))->code`), not in the tag. - * Use the typed primitive structs (Poly_F3, Poly_G4, etc.) and the - * `set_poly_*` setters, which set both the tag's length and the code. */ + * Use the typed primitive structs (Poly_F3, Poly_G4, etc.) and the `set_poly_*` setters, + * which set both the tag's length and the code. */ #define get_len(tag) C_(U4,C_(PolyTag_R,tag)->len) #define get_addr(tag) C_(U4,C_(PolyTag_R,tag)->addr) diff --git a/code/duffle/gte.h b/code/duffle/gte.h index a5acd73..595a646 100644 --- a/code/duffle/gte.h +++ b/code/duffle/gte.h @@ -37,49 +37,6 @@ * Hand-rolled DSL for emitting GTE/MIPS instruction words as raw `.word` * constants from C. No GCC inline-assembly string syntax in the code body. * - * PHILOSOPHY - * ---------- - * 1. A 32-bit instruction word is composed from per-field encoders. Each - * encoder knows only its own bit range; the composite ORs them together. - * No magic numbers inside any encoder body. Every shift and mask is a - * named constant from the bitfield-layout enum below. - * - * 2. Pure (compile-time) instructions. Every GTE *command* (RTPS, RTPT, - * NCLIP, MVMVA, …) and every COP2 *transfer* (ctc2/cfc2) with a constant - * rs/rt/rd — are emitted as a single integer constant via - * `asm_inline(...)` from gcc_asm.h. The C compiler constant-folds - * these into `.word` directives in .rodata. - * - * 3. Runtime-base-register instructions (lwc2, swc2, lw, sw, …) cannot be - * a pure compile-time word because the `rs` field is chosen by the - * compiler at codegen. For these we use a "placeholder-pun" pattern: - * a fixed register number (R_T4 = $12) is baked into the rs field of - * the `.word` constant, and the macro declares a `"r"(arg)` input - * constraint plus a clobber on the same register. The compiler is - * therefore *forced* to bind `arg` to that exact register, and the - * constant is correct. - * - * USAGE - * ----- - * // Pure command sequence — all bits compile-time: - * asm volatile( - * asm_inline( gte_cmd_rtpt , gte_cmd_nclip , gte_cmd_avsz3 ) - * asm_clobber( clbr_volatile_gprs ) - * ); - * - * // Runtime-base-register load — caller picks the base GPR: - * register V3_S2* p_in_12 __asm__("$12") = verts[0].ptr; - * gte_load_v0(p_in_12, R_T4); // R_T4 = 12 = $t4 = $12 - * - * // Three independent bases for an RTPT pipeline: - * register V3_S2* p0 gcc_reg(R_T4) = verts[0].ptr; - * register V3_S2* p1 gcc_reg(R_T5) = verts[1].ptr; - * register V3_S2* p2 gcc_reg(R_T6) = verts[2].ptr; - * gte_load_v0(p0, R_T4); - * gte_load_v1(p1, R_T5); - * gte_load_v2(p2, R_T6); - * gte_rtpt(); - * * STYLE NOTES * ----------- * - Per-field encoders are named `enc_gte_(value)` and each one @@ -94,8 +51,7 @@ * * SEE ALSO * -------- - * - gcc_asm.h: the `.word` emitter (`asm_inline`, `asm_clobber`, clobbers) - * - mips.h: the MIPS encoder layer this builds on + * - mips.h: The MIPS encoder layer this builds on. */ /* C2 data registers */ @@ -222,8 +178,8 @@ enum { * \_____ GTE_PAYLOAD _____/ \__ GTE_CMD __/ * * Shifts/masks below are the *bit positions* and *bit widths* of each - * configurable field, used by the ENC_GTE_CMD encoder. Mirrors the - * OPCODE_SHIFT / RS_SHIFT convention used in mips.h. + * configurable field, used by the ENC_GTE_CMD encoder. + * Mirrors the OPCODE_SHIFT / RS_SHIFT convention used in mips.h. */ gte_shift_sf = 19, gte_width_sf = 1, gte_mask_sf = 0x1, diff --git a/code/duffle/lottes_tape.h b/code/duffle/lottes_tape.h index f862a73..3c91faa 100644 --- a/code/duffle/lottes_tape.h +++ b/code/duffle/lottes_tape.h @@ -17,8 +17,7 @@ typedef Slice_MipsCode MipsAtom; #define MipsAtom_(sym) MipsCode tmpl(code,sym) [] align_(4) = // Bare form: file-scope declaration with hardcoded body. -// 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 } // expands to: // MipsCode ac_X[] align_(4) = { body };