PC port: phase 2 — D59-D68 milestone: full intro renders; blocker is D69 (BG-file BE headers)

D59/D64: the 'external GL DLL' crash was an unbounded blood-RLE write
(sentinel die_blood_image_end lost its N64 section adjacency on PC)
clobbering the gun-barrel sub-DL at ptr_logo_and_walletbond_DL+0x200.
D60: osPiStartDma DMA-target validation (VirtualQuery-based) in libultra.c.
D61/D63: TEMP env-gated ROM-read / VTX-pool / menu probes (strip list in
HANDOFF Task 3). D62: OSMesgQueue/OSScMsg PC layout verification.
D65/D65b: enum HEADS/BODIES signed sentinels under PORT (PC GCC picks
unsigned underlying types; N64 semantics were signed).
D66: romCopyAligned + ramrom replay 64-bit pointer width (s32 truncation
of .bss targets > 4 GiB). D67: struct image_entry N64 layout
reconstruction (dataoffset:24 first, all-u32 bitfields, sizeof==8).
D68: Globalimagetable BE->LE fixup (port/src/gimgfixup.c): bswap the
IMAGESEG-marked Gfx w1 words in the 17 ROM-copied DLs + sImageTableEntry.
index in the 32 tables after texReset's romCopy; marker scan moved to
bytes 6..7 under PORT; compiled globalDL shadows synced post-texLoad for
explosion.c's g_ExplosionDisplayLists.

Result: game boots, plays intro music, and renders the entire ~3.5-minute
intro (logo -> gun barrel with Brosnan -> cast screen) at ~59 fps. New
blocker D69: load_bg_file faults on first stage load - BG-file headers are
N64 big-endian segment-0x0F offsets read LE on PC. Full analysis + strategy
in PCPortResearch.md §F/D69; HANDOFF rewritten for the D69 session.
This commit is contained in:
James Dansereau committed 2026-08-24 03:27:29 -04:00
1 parent 2c0c0515dd
commit 8f631462f3
50 files changed
+2526 -376

No files matched your search

+101 -2
View File
@@ -2320,6 +2320,13 @@ static inline void *seg_addr(uintptr_t w1) {
uintptr_t clearMtx;
/* TEMP D63 (strip before commit) */
static int s_d63taskcount = 0;
static int s_d63ctxdump = 0;
extern "C" void d63RecordBranch(const Gfx *from, const Gfx *to);
extern "C" void d63DumpTrail(void);
extern "C" void d63LogLastBranchReread(void);
static void gfx_run_dl(Gfx* cmd) {
// puts("dl");
int dummy = 0;
@@ -2357,7 +2364,30 @@ static void gfx_run_dl(Gfx* cmd) {
case G_VTX:
gfx_sp_vertex(C0(0, 16) / sizeof(Vtx), C0(16, 4), (const Vtx*)seg_addr(cmd->words.w1));
break;
case G_DL:
case G_DL: {
/* TEMP D63: record the branch trail for post-mortem */
{
const Gfx *tgt = (const Gfx *)seg_addr(cmd->words.w1);
uintptr_t ta = (uintptr_t)tgt;
if (ta >= 0x70000000 && ta < 0xA0000000)
{
sysLogPrintf(LOG_NOTE, "D63 dram-branch t=%d from=%p to=%p first=(%08x,%08x)",
s_d63taskcount++, (const void *)cmd, (const void *)tgt,
tgt->words.w0, tgt->words.w1);
/* Context: 4 commands before the parent G_DL */
if (ta == 0x8012EC38 && s_d63ctxdump < 3)
{
for (int k = 4; k >= 0; --k)
{
const Gfx *c = cmd - k;
sysLogPrintf(LOG_NOTE, "D63 ctx[%d]=%p (%08x,%08x)",
k, (const void *)c, c->words.w0, c->words.w1);
}
++s_d63ctxdump;
}
}
}
d63RecordBranch(cmd, (const Gfx *)seg_addr(cmd->words.w1));
if (C0(16, 1) == 0) {
// Push return address
Gfx* subGFX = (Gfx*)seg_addr(cmd->words.w1);
@@ -2370,6 +2400,7 @@ static void gfx_run_dl(Gfx* cmd) {
--cmd; // increase after break
}
break;
}
case (uint8_t)G_ENDDL:
return;
case (uint8_t)G_SETGEOMETRYMODE:
@@ -2576,9 +2607,28 @@ static void gfx_run_dl(Gfx* cmd) {
case G_RDPLOADSYNC:
case G_RDPTILESYNC:
break;
default:
default: {
/* TEMP D63: dump context around the garbage command */
uint32_t *w = (uint32_t *)cmd;
sysLogPrintf(LOG_ERROR,
"D63 unknown opcode 0x%02x at %p (dlstart=%p); words[-2..+2]:",
opcode, (void *)cmd, (void *)dListStart);
for (int i = -2; i <= 2; ++i)
sysLogPrintf(LOG_ERROR, "D63 [%d] %p = %08x %08x",
i, (void *)&w[i], w[i * 2], w[i * 2 + 1]);
d63DumpTrail();
d63LogLastBranchReread();
/* TEMP D63: dump the sub-DL region to see the 0xFF extent. */
if (getenv("GE_D63")) {
uint32_t *r = (uint32_t *)dListStart;
for (int i = 0; i < 128; i += 4) {
sysLogPrintf(LOG_ERROR, "D63 region +%03x: %08x %08x %08x %08x",
i * 4, r[i], r[i + 1], r[i + 2], r[i + 3]);
}
}
sysFatalError("Unknown GBI opcode 0x%02x at %p.\nw0 %08x\nw1 %08x", opcode, cmd, cmd->words.w0, cmd->words.w1);
break;
}
}
++cmd;
}
@@ -2848,3 +2898,52 @@ extern "C" void gfx_reset_framebuffer(void) {
gfx_rapi->start_draw_to_framebuffer(0, (float)gfx_current_dimensions.height / SCREEN_HEIGHT);
active_fb = framebuffers.end();
}
/* TEMP D63: G_DL branch trail for post-mortem (strip before commit) */
#include <cstdio>
#define D63_TRAIL_SIZE 4096
static struct { const Gfx *from; const Gfx *to; uintptr_t w1; } s_d63trail[D63_TRAIL_SIZE];
static int s_d63count = 0;
extern "C" void d63RecordBranch(const Gfx *from, const Gfx *to) {
int idx = s_d63count % D63_TRAIL_SIZE;
s_d63trail[idx].from = from;
s_d63trail[idx].to = to;
s_d63trail[idx].w1 = from->words.w1;
++s_d63count;
}
extern "C" void d63LogLastBranchReread(void) {
if (s_d63count > 0) {
int li = (s_d63count - 1) % D63_TRAIL_SIZE;
const Gfx *lf = s_d63trail[li].from;
sysLogPrintf(LOG_ERROR, "D63 last-branch re-read: from=%p now w0=%08x w1=%llx (w1@rec was %llx) to=%p",
(const void *)lf, lf->words.w0,
(unsigned long long)lf->words.w1,
(unsigned long long)s_d63trail[li].w1,
(const void *)s_d63trail[li].to);
}
}
extern "C" void d63DumpTrail(void) {
int n = 24;
if (s_d63count < n) n = s_d63count;
sysLogPrintf(LOG_ERROR, "D63 branch trail (last %d of %d):", n, s_d63count);
for (int i = s_d63count - n; i < s_d63count; ++i)
sysLogPrintf(LOG_ERROR, "D63 [%d] from=%p w1@rec=%llx to=%p",
i % D63_TRAIL_SIZE, (const void *)s_d63trail[i % D63_TRAIL_SIZE].from,
(unsigned long long)s_d63trail[i % D63_TRAIL_SIZE].w1,
(const void *)s_d63trail[i % D63_TRAIL_SIZE].to);
/* Also: every branch whose target is in the DRAM views, to reconstruct
* the sub-DL chain that led to the fault. */
int span = s_d63count < D63_TRAIL_SIZE ? s_d63count : D63_TRAIL_SIZE;
sysLogPrintf(LOG_ERROR, "D63 DRAM-targeted branches (last %d):", span);
for (int i = s_d63count - span; i < s_d63count; ++i)
{
int idx = i % D63_TRAIL_SIZE;
uintptr_t to = (uintptr_t)s_d63trail[idx].to;
if (to >= 0x70000000 && to < 0xA0000000)
sysLogPrintf(LOG_ERROR, "D63 [%d] from=%p to=%p",
idx, (const void *)s_d63trail[idx].from, (const void *)to);
}
}