VDP timing improvements
authorkub <derkub@gmail.com>
Sun, 26 Jan 2020 19:46:21 +0000 (20:46 +0100)
committerkub <derkub@gmail.com>
Sun, 26 Jan 2020 19:46:21 +0000 (20:46 +0100)
pico/pico.c
pico/pico_cmn.c
pico/pico_int.h
pico/videoport.c

index 2a16a0e..b65b7de 100644 (file)
@@ -254,7 +254,7 @@ PICO_INTERNAL int CheckDMA(int cycles)
   dma_op1 = dma_op;\r
   if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode?\r
   if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display?\r
-  xfers_can = (dma_timings[dma_op] * cycles + 0xff) >> 16;\r
+  xfers_can = (dma_timings[dma_op] * cycles + 0x8000) >> 16;\r
   if(xfers <= xfers_can)\r
   {\r
     Pico.video.status &= ~SR_DMA;\r
@@ -265,6 +265,7 @@ PICO_INTERNAL int CheckDMA(int cycles)
     if(!(dma_op&2)) burn = cycles;\r
     Pico.m.dma_xfers -= xfers_can;\r
   }\r
+  Pico.t.dma_end = SekCyclesDone() + burn;\r
 \r
   elprintf(EL_VDPDMA, "~Dma %i op=%i can=%i burn=%i [%u]",\r
     Pico.m.dma_xfers, dma_op1, xfers_can, burn, SekCyclesDone());\r
index 8c22c97..b7e7d83 100644 (file)
@@ -56,10 +56,10 @@ static void SekSyncM68k(void)
 static __inline void SekRunM68k(int cyc)
 {
   Pico.t.m68c_aim += cyc;
+  Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns
   cyc = Pico.t.m68c_aim - Pico.t.m68c_cnt;
   if (cyc <= 0)
     return;
-  Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns
   SekSyncM68k();
 }
 
index a24fc6f..357de4a 100644 (file)
@@ -137,9 +137,7 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k;
 \r
 // burn cycles while not in SekRun() and while in\r
 #define SekCyclesBurn(c)    Pico.t.m68c_cnt += c\r
-#define SekCyclesBurnRun(c) { \\r
-  SekCyclesLeft -= c; \\r
-}\r
+#define SekCyclesBurnRun(c) SekCyclesLeft -= c\r
 \r
 // note: sometimes may extend timeslice to delay an irq\r
 #define SekEndRun(after) { \\r
@@ -421,6 +419,7 @@ struct PicoTiming
   unsigned int z80c_aim;\r
   int z80_scanline;\r
 \r
+  unsigned int dma_end;                 // end of current DMA op (m68k cycles)\r
   int timer_a_next_oflow, timer_a_step; // in z80 cycles\r
   int timer_b_next_oflow, timer_b_step;\r
 };\r
index c2fbd0c..16a7311 100644 (file)
@@ -376,12 +376,12 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
       pvid->pending=0;\r
     }\r
 \r
-    if (!(pvid->status & SR_VB) && !(PicoIn.opt&POPT_DIS_VDP_FIFO))\r
+    if (!(pvid->status & SR_VB) && (pvid->reg[1]&0x40) && !(PicoIn.opt&POPT_DIS_VDP_FIFO))\r
     {\r
       int use = pvid->type == 1 ? 2 : 1;\r
       pvid->lwrite_cnt -= use;\r
       if (pvid->lwrite_cnt < 0)\r
-        SekCyclesLeft = 0;\r
+        SekCyclesBurnRun(488 - (SekCyclesDone()-Pico.t.m68c_line_start));\r
       elprintf(EL_ASVDP, "VDP data write: [%04x] %04x [%u] {%i} #%i @ %06x",\r
         Pico.video.addr, d, SekCyclesDone(), Pico.video.type, pvid->lwrite_cnt, SekPc);\r
     }\r
@@ -509,9 +509,11 @@ static u32 SrLow(const struct PicoVideo *pv)
 {\r
   unsigned int c, d = pv->status;\r
 \r
-  c = SekCyclesDone() - Pico.t.m68c_line_start - 39;\r
-  if (c < 92)\r
+  c = SekCyclesDone();\r
+  if (c - Pico.t.m68c_line_start - 39 < 92)\r
     d |= SR_HB;\r
+  if (CYCLES_GT(c, Pico.t.dma_end))\r
+    d &= ~SR_DMA;\r
   return d;\r
 }\r
 \r