Skip to content

[Blocker 3/6] F3D_Gold w1 low-bits encoding mystery #2

@mgrz18

Description

@mgrz18

Symptom

Across matrix/vertex/texture commands, w1 consistently has low 3 bits set:

  • Matrix: seg=0x00264503 (low 3 = 0x3 = exactly the params byte 0x03)
  • Vertex: seg=0x0026450B (low 4 = 0xB)
  • Texture: seg=0x00264503 (same)

After mask & 0x00FFFFF8, address resolves to 0x00264500 — but bytes there are a DL command stream (opcodes E7, BA, B9, BB, FC, FD, F5), not matrix/vertex/texture data.

What we know

  • F3D_Gold ucode is tolerant of low 3 bits in w1 — DMA hardware truncates them, ucode never reads them as flags. Per gmain.s line 612-621.
  • C-side macros (gSPMatrix, gSPVertex, gSPSetTextureImage) put raw addresses in w1, no OR with flags.
  • Yet observed bytes at masked address are NOT what they should be.

Hypothesis

Heap aliasing in the bump allocator at /tmp/ge_decomp/src/game/dyn.c:85 (g_GfxMemPos):

  • dynAllocateMatrix() returns g_GfxMemPos then g_GfxMemPos += sizeof(Mtx)
  • Same allocator backs dynAllocate(size) for arbitrary blocks AND DL chunks
  • DL chunks emitted via gSPDisplayList(rodata->BaseAddr) reference addresses inside the same heap region
  • Possible: a gSPMatrix(addr_X) actually receives a pointer to a sub-DL chunk because field_10E0 was set wrong upstream

Try next

  1. Read gmain.s more carefully — find the EXACT instruction that consumes w1 in matrix/vertex/texture handlers. Confirm low-bits truly are masked vs extracted as flags.
  2. Trace g_CurrentPlayer->field_10E0 — find ALL writers and verify they only ever set it to a Mtx pointer.
  3. Add runtime assertion in dynAllocateMatrix that g_GfxMemPos & 0x3F == 0 (64-byte aligned).

Files

  • n64decomp/007 rsp/graphics/gmain.s (RSP asm — 1545 lines)
  • lib/rt64/src/hle/rt64_rsp.cpp::matrix (current decoder)
  • lib/rt64/src/hle/rt64_rsp.cpp::setTextureImage:1160
  • /tmp/ge_decomp/src/game/dyn.c:85 (allocator)
  • /tmp/ge_decomp/src/game/bondview.c:11882 (set_BONDdata_field_10E0 caller)

Acceptance criteria

Matrix calls decode to sensible affine/projection values (m[3] = [0,0,0,1] or m[*][3] = [0,0,0,1]).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions