Skip to content

Commit 04abb58

Browse files
committed
HLE CD: signal completion via DSP RAM [\$F1B4C8] = \$FFFFFFFF
Per docs/cd-bios-calling-convention.md and the retail BIOS disassembly: "The BIOS does NOT use CD_poll. It polls DSP RAM flag at [\$F1B4C8] — the GPU ISR writes \$FFFFFFFF there when the transfer completes, and the BIOS loops until negative." HLEHandleCDRead now mirrors that contract: clear the flag at the start of the read and write \$FFFFFFFF when the transfer finishes. This is the hardware-correct completion primitive. Game boot stubs that follow the BIOS convention will pick this up automatically. The remaining failing CUE games (Baldies, BrainDead 13, Iron Soldier 2, Primal Rage) do NOT poll [\$F1B4C8] — they either spin in STOP waiting for a JERRY ext IRQ from BUTCH, or they read the BUTCH FIFO data register (\$DFFF24/\$DFFF28) directly from the 68K. Both are separate, larger problems (interrupt-driven streaming and direct-FIFO emulation) tracked for follow-up work. Test diagnostic: the boot smoke test now also dumps 32 bytes of code around each visited PC when fewer than 32 unique PCs are seen, so the wait-loop instruction stream can be decoded without re-running. Result: 4 PASS / 5 FAIL (no regression vs prior baseline). Made-with: Cursor
1 parent 8d7c3d6 commit 04abb58

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

src/jagcd_hle.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@
1919
#include "log.h"
2020
#include "vjag_memory.h"
2121
#include "gpu.h"
22+
#include "dsp.h"
2223
#include "m68000/m68kinterface.h"
2324

25+
/* DSP RAM "CD transfer done" flag. Per docs/cd-bios-calling-convention.md:
26+
* "The BIOS does NOT use CD_poll. It polls DSP RAM flag at [$F1B4C8] —
27+
* the GPU ISR writes $FFFFFFFF there when the transfer completes, and
28+
* the BIOS loops until negative."
29+
* Game boot stubs follow the same convention. */
30+
#define CD_DSP_DONE_FLAG_ADDR 0x00F1B4C8
31+
2432
/* file_stream_transforms.h redefines fprintf; restore real stdio. */
2533
#undef fprintf
2634

@@ -231,6 +239,11 @@ static void HLEHandleCDRead(void)
231239
return;
232240
}
233241

242+
/* Clear the DSP completion flag so polling code sees a 0 -> $FFFFFFFF
243+
* transition once the transfer finishes. Real hardware: the GPU CD ISR
244+
* writes $FFFFFFFF here when its write pointer reaches the end address. */
245+
DSPWriteLong(CD_DSP_DONE_FLAG_ADDR, 0x00000000, UNKNOWN);
246+
234247
/* Scan for the D1 sentinel sync block in the byte-swapped disc data.
235248
*
236249
* On real hardware the I2S path byte-swaps each 16-bit word, and the
@@ -468,6 +481,11 @@ static void HLEHandleCDRead(void)
468481
GPUWriteLong(hle_gpu_data_base + 16, d1, 0);
469482
}
470483

484+
/* Signal completion to BIOS-style polling code via DSP RAM flag.
485+
* Real GPU CD ISR writes $FFFFFFFF here when its write pointer reaches
486+
* the end address. */
487+
DSPWriteLong(CD_DSP_DONE_FLAG_ADDR, 0xFFFFFFFFu, UNKNOWN);
488+
471489
HLE_LOG("CD_read: transferred %u bytes (%u sectors) "
472490
"to $%06X-$%06X\n",
473491
byteCount, s, destAddr, hle_read_end_addr - 1);

test/test_cd_hle_boot.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,22 @@ static void cd_run_one_disc(const char *path, unsigned frames,
221221
for (size_t i = 0; i < hist.unique_count; i++)
222222
fprintf(stderr, " $%06X", hist.unique[i]);
223223
fprintf(stderr, "\n");
224+
225+
/* Dump 32 bytes around each visited PC so the developer can decode
226+
* the instruction stream of the wait loop without re-running. */
227+
if (ram) {
228+
for (size_t i = 0; i < hist.unique_count; i++) {
229+
uint32_t pc = hist.unique[i];
230+
if (pc >= 0x200000) continue;
231+
uint32_t base = (pc >= 8) ? (pc - 8) : 0;
232+
uint32_t end = base + 32;
233+
if (end > 0x200000) end = 0x200000;
234+
fprintf(stderr, " [PC-BYTES $%06X]", pc);
235+
for (uint32_t a = base; a < end; a++)
236+
fprintf(stderr, " %02X", ram[a]);
237+
fprintf(stderr, "\n");
238+
}
239+
}
224240
}
225241

226242
cd_unload_game();

0 commit comments

Comments
 (0)