void GPUwriteStatus(uint32_t data)
{
uint32_t cmd = data >> 24;
+ uint32_t fb_dirty = 1;
int src_x, src_y;
if (cmd < ARRAY_SIZE(gpu.regs)) {
gpu.regs[cmd] = data;
}
- gpu.state.fb_dirty = 1;
-
switch (cmd) {
case 0x00:
do_reset();
break;
case 0x01:
do_cmd_reset();
+ fb_dirty = 0;
break;
case 0x03:
if (data & 1) {
case 0x04:
gpu.status &= ~PSX_GPU_STATUS_DMA_MASK;
gpu.status |= PSX_GPU_STATUS_DMA(data & 3);
+ fb_dirty = 0;
break;
case 0x05:
src_x = data & 0x3ff; src_y = (data >> 10) & 0x1ff;
default:
if ((cmd & 0xf0) == 0x10)
get_gpu_info(data);
+ fb_dirty = 0;
break;
}
+ gpu.state.fb_dirty |= fb_dirty;
+
#ifdef GPUwriteStatus_ext
GPUwriteStatus_ext(data);
#endif
if (is_read)
gpu.status &= ~PSX_GPU_STATUS_IMG;
else {
- gpu.state.fb_dirty = 1;
+ int32_t screen_r = gpu.screen.src_x + gpu.screen.hres;
+ int32_t screen_b = gpu.screen.src_y + gpu.screen.vres;
+ int32_t dma_r = gpu.dma_start.x + gpu.dma_start.w;
+ int32_t dma_b = gpu.dma_start.y + gpu.dma_start.h;
+ int32_t not_dirty;
+ not_dirty = screen_r - gpu.dma_start.x - 1;
+ not_dirty |= screen_b - gpu.dma_start.y - 1;
+ not_dirty |= dma_r - gpu.screen.src_x - 1;
+ not_dirty |= dma_b - gpu.screen.src_y - 1;
+ not_dirty >>= 31;
+ log_io("dma %3d,%3d %dx%d scr %3d,%3d %3dx%3d -> dirty %d\n",
+ gpu.dma_start.x, gpu.dma_start.y, gpu.dma_start.w, gpu.dma_start.h,
+ gpu.screen.src_x, gpu.screen.src_y, gpu.screen.hres, gpu.screen.vres, !not_dirty);
+ gpu.state.fb_dirty |= !not_dirty;
renderer_update_caches(gpu.dma_start.x, gpu.dma_start.y,
gpu.dma_start.w, gpu.dma_start.h, 0);
}
for (pos = 0; pos < count; )
{
if (gpu.dma.h && !gpu.dma_start.is_read) { // XXX: need to verify
- vram_dirty = 1;
+ // vram_dirty = 1; // handled in finish_vram_transfer()
pos += do_vram_io(data + pos, count - pos, 0);
if (pos == count)
break;
pos += 4;
continue;
}
- else if (cmd == 0x1f) {
- log_anomaly("irq1?\n");
+ else if (cmd < 0x20 && cmd != 2) {
+ if (cmd == 0x1f)
+ log_anomaly("irq1?\n");
pos++;
continue;
}