HW_DMA2_MADR = SWAPu32(madr_next);
// timing hack with some lame heuristics
- if (Config.gpu_timing_override && (do_walking || cycles_sum > 64))
+ if (Config.gpu_timing_override && (do_walking || cycles_sum > 64)
+ && !(HW_GPU_STATUS & SWAP32(PSXGPU_DHEIGHT | PSXGPU_RGB24)))
cycles_sum = Config.gpu_timing_override;
psxRegs.gpuIdleAfter = psxRegs.cycle + cycles_sum + cycles_last_cmd;
void gpuInterrupt() {
if (HW_DMA2_CHCR == SWAP32(0x01000401) && !(HW_DMA2_MADR & SWAP32(0x800000)))
{
- u32 madr_next = 0xffffff, madr = SWAPu32(HW_DMA2_MADR);
+ u32 madr_next = SWAPu32(HW_DMA2_MADR);
+ s32 cycles_sum = psxRegs.gpuIdleAfter - psxRegs.cycle;
s32 cycles_last_cmd = 0;
- long cycles_sum;
- cycles_sum = GPU_dmaChain((u32 *)psxM, madr & 0x1fffff,
- &madr_next, &cycles_last_cmd);
+ do {
+ cycles_sum += cycles_last_cmd;
+ cycles_sum += GPU_dmaChain((u32 *)psxM, madr_next & 0x1fffff,
+ &madr_next, &cycles_last_cmd);
+ }
+ while (cycles_sum <= 0 && !(madr_next & 0x800000));
HW_DMA2_MADR = SWAPu32(madr_next);
- if ((s32)(psxRegs.gpuIdleAfter - psxRegs.cycle) > 0)
- cycles_sum += psxRegs.gpuIdleAfter - psxRegs.cycle;
psxRegs.gpuIdleAfter = psxRegs.cycle + cycles_sum + cycles_last_cmd;
set_event(PSXINT_GPUDMA, cycles_sum);
- //printf("%u dma2cn: %6ld,%4d %08x\n", psxRegs.cycle, cycles_sum,
+ //printf("%u dma2cn: %6d,%4d %08x\n", psxRegs.cycle, cycles_sum,
// cycles_last_cmd, HW_DMA2_MADR);
return;
}
addr = LE32TOH(list[0]) & 0xffffff;
preload(rambase + (addr & 0x1fffff) / 4);
- cpu_cycles_sum += 10;
+ cpu_cycles_sum += 10 + cpu_cycles_last;
+ cpu_cycles_last = 0;
if (len > 0)
cpu_cycles_sum += 5 + len;
}
}
- if (progress_addr && (cpu_cycles_last + cpu_cycles_sum > 512))
- break;
+ if (progress_addr) {
+ // hack for bios boot logo race (must be not too fast or too slow)
+ if (gpu.status & PSX_GPU_STATUS_DHEIGHT)
+ cpu_cycles_sum += 5;
+ if (cpu_cycles_sum > 512)
+ break;
+ }
if (addr == ld_addr) {
log_anomaly(&gpu, "GPUdmaChain: loop @ %08x, cnt=%u\n", addr, count);
break;