mirror of
https://github.com/libretro/virtualjaguar-libretro.git
synced 2026-11-08 08:10:33 -10:00
Fix BIOS regression, CI failures, and PR review feedback
- Revert DSP IRQ dispatch `who != DSP` guard that broke BIOS mode by preventing the DSP from self-dispatching interrupts during ISR return. WMCJ with BIOS dropped from 8.1M to 4.9M pixels at 900 frames; now restored to 8.1M. - Export DSP/GPU/memory symbols in link.T so Linux CI can dlsym them for DSP instruction set tests (was "Missing: DSPReset"). - Remove `inline` from vj_log_stderr in log.h (MSVC compatibility). - Add pack assertion in test_gpu_ops.c (was always-pass). - Fix LEA test comment inconsistency in test_m68k_ops.c. - Add <strings.h> for strcasecmp in test_rom_smoke.c. - Remove tomWidth bounds guard from TOMExecHalfline (already clamped in TOMGetVideoModeWidth). Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
1 parent
fe0557a79a
commit
3e0a4e7872
8 files changed
+36
-23
No files matched your search
@@ -1,5 +1,21 @@
|
||||
{
|
||||
global: retro_*;
|
||||
global:
|
||||
retro_*;
|
||||
DSP*;
|
||||
dsp_*;
|
||||
m68k_*;
|
||||
jaguarMainRAM;
|
||||
jaguarMainROM;
|
||||
jagMemSpace;
|
||||
pcQueue;
|
||||
pcQPtr;
|
||||
a6Queue;
|
||||
d0Queue;
|
||||
GPUReadLong;
|
||||
GPUWriteLong;
|
||||
JERRY*;
|
||||
TOM*;
|
||||
tomRam8;
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -621,12 +621,9 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
|
||||
DSPUpdateRegisterBanks();
|
||||
dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3);
|
||||
dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1);
|
||||
/* Dispatch pending IRQs when an external caller (M68K/GPU)
|
||||
* enables INT_ENA while INT_LAT is pending. Do NOT dispatch
|
||||
* when the DSP itself writes flags (ISR return) — the
|
||||
* IMASKCleared path in DSPExec handles that between
|
||||
* instructions, matching real-hardware timing. */
|
||||
if (who != DSP && DSP_RUNNING && !(dsp_flags & IMASK))
|
||||
// Dispatch pending IRQs after CINT clears latches.
|
||||
// Newly-enabled INT_ENA fires if INT_LAT is still pending.
|
||||
if (DSP_RUNNING && !(dsp_flags & IMASK))
|
||||
DSPHandleIRQsNP();
|
||||
break;
|
||||
}
|
||||
@@ -819,7 +816,7 @@ void DSPHandleIRQsNP(void)
|
||||
return;
|
||||
|
||||
// Get the active interrupt bits (latches) & interrupt mask (enables)
|
||||
bits = ((dsp_control >> 11) & 0x20) | ((dsp_control >> 6) & 0x1F);
|
||||
bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F);
|
||||
mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F);
|
||||
|
||||
bits &= mask;
|
||||
|
||||
@@ -11,7 +11,7 @@ extern "C" {
|
||||
|
||||
extern retro_log_printf_t vj_log_cb;
|
||||
|
||||
static inline void vj_log_stderr(const char *fmt, ...)
|
||||
static void vj_log_stderr(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
@@ -777,7 +777,7 @@ void TOMExecHalfline(uint16_t halfline, bool render)
|
||||
|
||||
// Here's our virtualized scanline code...
|
||||
|
||||
if ((halfline >= topVisible) && (halfline < bottomVisible) && tomWidth > 0 && tomWidth <= 1024)
|
||||
if ((halfline >= topVisible) && (halfline < bottomVisible))
|
||||
{
|
||||
if (inActiveDisplayArea)
|
||||
scanline_render[TOMGetVideoMode()](TOMCurrentLine);
|
||||
|
||||
@@ -444,9 +444,8 @@ static void test_int_ena_dispatch(void)
|
||||
p_DSPWriteLong(DSP_CTRL_ADDR, DSPGO, 6);
|
||||
pc_before = *p_dsp_pc;
|
||||
|
||||
/* Now write INT_ENA0 to flags -- this should trigger dispatch.
|
||||
* Use who=M68K (6) to simulate the 68K enabling the interrupt. */
|
||||
p_DSPWriteLong(DSP_FLAGS_ADDR, INT_ENA0, 6);
|
||||
/* Now write INT_ENA0 to flags -- this should trigger dispatch */
|
||||
p_DSPWriteLong(DSP_FLAGS_ADDR, INT_ENA0, 2);
|
||||
|
||||
pc_after = *p_dsp_pc;
|
||||
|
||||
@@ -520,8 +519,8 @@ static void test_interrupt_priority(void)
|
||||
p_DSPWriteLong(DSP_PC_ADDR, 0xF1B800, 6);
|
||||
p_DSPWriteLong(DSP_CTRL_ADDR, DSPGO, 6);
|
||||
|
||||
/* Enable both interrupts (who=M68K=6) */
|
||||
p_DSPWriteLong(DSP_FLAGS_ADDR, INT_ENA0 | INT_ENA1, 6);
|
||||
/* Enable both interrupts */
|
||||
p_DSPWriteLong(DSP_FLAGS_ADDR, INT_ENA0 | INT_ENA1, 2);
|
||||
|
||||
pc_after = *p_dsp_pc;
|
||||
|
||||
|
||||
+6
-6
@@ -695,15 +695,15 @@ static void test_pack(void)
|
||||
gwmovei(0x100, 0x001F03E0, 0);
|
||||
gw16(0x106, OP_PACK(0, 0));
|
||||
run(20);
|
||||
/* pack: ((0x001F03E0 >> 10) & 0xF000) | ((0x001F03E0 >> 5) & 0x0F00) | (0x001F03E0 & 0xFF)
|
||||
* = (0x00007C0F >> ... hmm let me calculate:
|
||||
/* pack: ((val >> 10) & 0xF000) | ((val >> 5) & 0x0F00) | (val & 0xFF)
|
||||
* val = 0x001F03E0
|
||||
* (val >> 10) = 0x00007C0F, & 0xF000 = 0x0000
|
||||
* (val >> 5) = 0x000F81F0, & 0x0F00 = 0x0100
|
||||
* val & 0xFF = 0xE0
|
||||
* result = 0x0000 | 0x0100 | 0xE0 = 0x01E0
|
||||
* (val >> 5) = 0x000F81F0, & 0x0F00 = 0x0100
|
||||
* val & 0xFF = 0xE0
|
||||
* result = 0x0000 | 0x0100 | 0x00E0 = 0x01E0
|
||||
*/
|
||||
PASS("pack executed (R0=%08X)", REG(0));
|
||||
if (REG(0) == 0x000001E0) PASS("pack(0x001F03E0)=0x000001E0");
|
||||
else FAIL("pack(0x001F03E0)=%08X (expected 000001E0)", REG(0));
|
||||
|
||||
/* unpack (RM=1): reverse of pack */
|
||||
prep();
|
||||
|
||||
@@ -721,11 +721,11 @@ static void test_lea(void)
|
||||
{
|
||||
printf("\n--- LEA ---\n");
|
||||
prep();
|
||||
/* LEA $12345678, A0 */
|
||||
/* LEA $00012345, A0 */
|
||||
w16(CODE_BASE, M68K_LEA_ABS_L(0));
|
||||
w32(CODE_BASE + 2, 0x00012345);
|
||||
run(20);
|
||||
if (A(0) == 0x00012345) PASS("lea $12345, A0");
|
||||
if (A(0) == 0x00012345) PASS("lea $00012345, A0");
|
||||
else FAIL("lea: A0=%08X", A(0));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
Reference in new issue
Block a user