mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-07-12 12:21:26 -07:00
more adjustments
This commit is contained in:
+28
-35
@@ -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)
|
||||
|
||||
|
||||
+3
-47
@@ -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_<field>(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,
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user