PicoVideoRead optimization
authornotaz <notasas@gmail.com>
Tue, 1 Jul 2008 16:12:04 +0000 (16:12 +0000)
committernotaz <notasas@gmail.com>
Tue, 1 Jul 2008 16:12:04 +0000 (16:12 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@511 be3aeb3a-fb24-0410-a615-afba39da0efa

Pico/Memory.c
Pico/Memory.s
Pico/Memory_amips.s
Pico/Pico.c
Pico/Pico/Memory.c
Pico/PicoFrameHints.c
Pico/PicoInt.h
Pico/VideoPort.c
Pico/cd/Memory.c
Pico/cd/Memory.s

index 22bd7ad..290dba4 100644 (file)
@@ -344,9 +344,9 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
   log_io(a, 8, 0);\r
   if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
 \r
-  if ((a&0xe700e0)==0xc00000) // VDP\r
-       d=PicoVideoRead(a);\r
-  else d=OtherRead16(a&~1, 8);\r
+  if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP\r
+  \r
+  d=OtherRead16(a&~1, 8);\r
   if ((a&1)==0) d>>=8;\r
 \r
 end:\r
index a042d81..cf2036d 100644 (file)
@@ -415,13 +415,7 @@ m_read8_vdp:
     tst     r0, #0x70000\r
     tsteq   r0, #0x000e0\r
     bxne    lr              @ invalid read\r
-    stmfd   sp!,{r0,lr}\r
-    bic     r0, r0, #1\r
-    bl      PicoVideoRead\r
-    ldmfd   sp!,{r1,lr}\r
-    tst     r1, #1\r
-    moveq   r0, r0, lsr #8\r
-    bx      lr\r
+    b       PicoVideoRead8\r
 \r
 m_read8_ram:\r
     ldr     r1, =Pico\r
index 5a6b768..e6247c6 100644 (file)
@@ -469,7 +469,9 @@ m_read8_vdp:
     andi    $t1, $a0, 0xe0
     or      $t0, $t1
     bnez    $t0, m_read_null # invalid address
-    m_read8_call16 PicoVideoRead
+    nop
+    j       PicoVideoRead8
+    nop
 
 m_read8_ram:
     lui     $t0, %hi(Pico)
index c85c78a..9f5a361 100644 (file)
@@ -218,7 +218,8 @@ PICO_INTERNAL int CheckDMA(void)
   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];\r
-  if(xfers <= xfers_can) {\r
+  if(xfers <= xfers_can)\r
+  {\r
     if(dma_op&2) Pico.video.status&=~2; // dma no longer busy\r
     else {\r
       burn = xfers * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division..\r
index 8c4674b..13cff62 100644 (file)
@@ -22,8 +22,7 @@ static u32 PicoReadPico8(u32 a)
   a&=0xffffff;
 
   if ((a&0xfffff0)==0xc00000) { // VDP
-    d=PicoVideoRead(a);
-    if ((a&1)==0) d>>=8;
+    d=PicoVideoRead8(a);
     goto end;
   }
 
index 962f9dc..9fecc0c 100644 (file)
 static int PicoFrameHints(void)
 {
   struct PicoVideo *pv=&Pico.video;
-  int lines, y, lines_vis = 224, line_sample, skip;
+  int lines, y, lines_vis = 224, line_sample, skip, vcnt_wrap;
   int hint; // Hint counter
 
-  Pico.m.scanline = 0;
+  pv->v_counter = Pico.m.scanline = 0;
 
   if ((PicoOpt&POPT_ALT_RENDERER) && !PicoSkipFrame && (pv->reg[1]&0x40)) { // fast rend., display enabled
     // draw a frame just after vblank in alternative render mode
@@ -53,7 +53,7 @@ static int PicoFrameHints(void)
 
   if (Pico.m.pal) {
     line_sample = 68;
-    if(pv->reg[1]&8) lines_vis = 240;
+    if (pv->reg[1]&8) lines_vis = 240;
   } else {
     line_sample = 93;
   }
@@ -75,7 +75,12 @@ static int PicoFrameHints(void)
 
   for (y = 0; y < lines_vis; y++)
   {
-    Pico.m.scanline = y;
+    pv->v_counter = Pico.m.scanline = y;
+    if ((pv->reg[12]&6) == 6) { // interlace mode 2
+      pv->v_counter <<= 1;
+      pv->v_counter |= pv->v_counter >> 8;
+      pv->v_counter &= 0xff;
+    }
 
     // VDP FIFO
     pv->lwrite_cnt -= 12;
@@ -138,6 +143,11 @@ static int PicoFrameHints(void)
 #endif
   }
 
+  // V-int line (224 or 240)
+  Pico.m.scanline = y;
+  pv->v_counter = 0xe0; // bad for 240 mode
+  if ((pv->reg[12]&6) == 6) pv->v_counter = 0xc1;
+
   if (!skip)
   {
     if (DrawScanline < y)
@@ -147,9 +157,6 @@ static int PicoFrameHints(void)
 #endif
   }
 
-  // V-int line (224 or 240)
-  Pico.m.scanline = y;
-
   // VDP FIFO
   pv->lwrite_cnt=0;
   Pico.video.status|=0x200;
@@ -168,7 +175,6 @@ static int PicoFrameHints(void)
     if (pv->reg[0]&0x10) SekInterrupt(4);
   }
 
-  // V-Interrupt:
   pv->status|=0x08; // go into vblank
   pv->pending_ints|=0x20;
 
@@ -212,10 +218,16 @@ static int PicoFrameHints(void)
 
   // PAL line count might actually be 313 according to Steve Snake, but that would complicate things.
   lines = Pico.m.pal ? 312 : 262;
+  vcnt_wrap = Pico.m.pal ? 0x103 : 0xEB; // based on Gens
 
   for (y++; y < lines; y++)
   {
-    Pico.m.scanline = y;
+    pv->v_counter = Pico.m.scanline = y;
+    if (y >= vcnt_wrap)
+      pv->v_counter -= Pico.m.pal ? 56 : 6;
+    if ((pv->reg[12]&6) == 6)
+      pv->v_counter = (pv->v_counter << 1) | 1;
+    pv->v_counter &= 0xff;
 
     PAD_DELAY
 #ifdef PICO_CD
index 664c2f2..4994ffc 100644 (file)
@@ -237,7 +237,8 @@ struct PicoVideo
   int status;                 // Status bits\r
   unsigned char pending_ints; // pending interrupts: ??VH????\r
   signed char lwrite_cnt;     // VDP write count during active display line\r
-  unsigned char pad[0x12];\r
+  unsigned short v_counter;   // V-counter\r
+  unsigned char pad[0x10];\r
 };\r
 \r
 struct PicoMisc\r
@@ -504,6 +505,7 @@ void ym2612_unpack_state(void);
 // VideoPort.c\r
 PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d);\r
 PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a);\r
+PICO_INTERNAL_ASM unsigned int PicoVideoRead8(unsigned int a);\r
 extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp);\r
 \r
 // Misc.c\r
index db7b2b7..7a38ea9 100644 (file)
@@ -449,24 +449,19 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
 {\r
   a&=0x1c;\r
 \r
-  if (a==0x00) // data port\r
-  {\r
-    return VideoRead();\r
-  }\r
-\r
   if (a==0x04) // control port\r
   {\r
     struct PicoVideo *pv=&Pico.video;\r
     unsigned int d;\r
     d=pv->status;\r
-    if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)\r
-    if (!(pv->reg[1]&0x40))        d|=0x0008; // set V-Blank if display is disabled\r
+    //if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)\r
     if (SekCyclesLeft < 84+4)      d|=0x0004; // H-Blank (Sonic3 vs)\r
 \r
-    d|=(pv->pending_ints&0x20)<<2; // V-int pending?\r
+    d |= ((pv->reg[1]&0x40)^0x40) >> 3;  // set V-Blank if display is disabled\r
+    d |= (pv->pending_ints&0x20)<<2;     // V-int pending?\r
     if (d&0x100) pv->status&=~0x100; // FIFO no longer full\r
 \r
-    pv->pending=0; // ctrl port reads clear write-pending flag (Charles MacDonald)\r
+    pv->pending = 0; // ctrl port reads clear write-pending flag (Charles MacDonald)\r
 \r
     elprintf(EL_SR, "SR read: %04x @ %06x", d, SekPc);\r
     return d;\r
@@ -489,32 +484,60 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
   // check: Sonic 3D Blast bonus, Cannon Fodder, Chase HQ II, 3 Ninjas kick back, Road Rash 3, Skitchin', Wheel of Fortune\r
   if ((a&0x1c)==0x08)\r
   {\r
-    unsigned int hc, d;\r
+    unsigned int d;\r
     int lineCycles;\r
     \r
     lineCycles = (488-SekCyclesLeft)&0x1ff;\r
-    d = Pico.m.scanline; // V-Counter\r
-\r
     if (Pico.video.reg[12]&1)\r
-         hc=hcounts_40[lineCycles];\r
-    else hc=hcounts_32[lineCycles];\r
+         d = hcounts_40[lineCycles];\r
+    else d = hcounts_32[lineCycles];\r
 \r
-    if (Pico.m.pal) {\r
-      if (d >= 0x103) d-=56; // based on Gens\r
-    } else {\r
-      if (d >= 0xEB)  d-=6;\r
-    }\r
+    elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc);\r
+    return d | (Pico.video.v_counter << 8);\r
+  }\r
 \r
-    if ((Pico.video.reg[12]&6) == 6) {\r
-      // interlace mode 2 (Combat Cars (UE) [!])\r
-      d <<= 1;\r
-      if (d&0xf00) d|= 1;\r
-    }\r
+  if (a==0x00) // data port\r
+  {\r
+    return VideoRead();\r
+  }\r
 \r
-    elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", hc, d, SekCyclesDone(), SekPc);\r
-    d&=0xff; d<<=8;\r
-    d|=hc;\r
-    return d;\r
+  return 0;\r
+}\r
+\r
+unsigned int PicoVideoRead8(unsigned int a)\r
+{\r
+  unsigned int d;\r
+  a&=0x1d;\r
+\r
+  switch (a)\r
+  {\r
+    case 0: return VideoRead() >> 8;\r
+    case 1: return VideoRead() & 0xff;\r
+    case 4: // control port/status reg\r
+      d = Pico.video.status >> 8;\r
+      if (d&1) Pico.video.status&=~0x100; // FIFO no longer full\r
+      Pico.video.pending = 0;\r
+      elprintf(EL_SR, "SR read (h): %02x @ %06x", d, SekPc);\r
+      return d;\r
+    case 5:\r
+      d = Pico.video.status & 0xff;\r
+      //if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)\r
+      d |= ((Pico.video.reg[1]&0x40)^0x40) >> 3;  // set V-Blank if display is disabled\r
+      d |= (Pico.video.pending_ints&0x20)<<2;     // V-int pending?\r
+      if (SekCyclesLeft < 84+4) d |= 4;    // H-Blank\r
+      Pico.video.pending = 0;\r
+      elprintf(EL_SR, "SR read (l): %02x @ %06x", d, SekPc);\r
+      return d;\r
+    case 8: // hv counter\r
+      elprintf(EL_HVCNT, "vcounter: %02x (%i) @ %06x", Pico.video.v_counter, SekCyclesDone(), SekPc);\r
+      return Pico.video.v_counter;\r
+    case 9:\r
+      d = (488-SekCyclesLeft)&0x1ff;\r
+      if (Pico.video.reg[12]&1)\r
+           d = hcounts_40[d];\r
+      else d = hcounts_32[d];\r
+      elprintf(EL_HVCNT, "hcounter: %02x (%i) @ %06x", d, SekCyclesDone(), SekPc);\r
+      return d;\r
   }\r
 \r
   return 0;\r
index 2b419b7..b404ae7 100644 (file)
@@ -501,10 +501,8 @@ u32 PicoReadM68k8(u32 a)
     case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:\r
     case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:\r
       // VDP\r
-      if ((a&0xe700e0)==0xc00000) {\r
-        d=PicoVideoRead(a);\r
-        if ((a&1)==0) d>>=8;\r
-      }\r
+      if ((a&0xe700e0)==0xc00000)\r
+        d=PicoVideoRead8(a);\r
       break;\r
     case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:\r
     case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:\r
index 1b9fe96..9aba56d 100644 (file)
@@ -126,6 +126,7 @@ m_s68k_decode_write_table:
 .extern z80Read8
 .extern OtherRead16
 .extern PicoVideoRead
+.extern PicoVideoRead8
 .extern Read_CDC_Host
 .extern m68k_reg_write8
 .extern OtherWrite16
@@ -611,13 +612,7 @@ m_m68k_read8_vdp:
     tst     r0, #0x70000
     tsteq   r0, #0x000e0
     bxne    lr              @ invalid read
-    stmfd   sp!,{r0,lr}
-    bic     r0, r0, #1
-    bl      PicoVideoRead               @ TODO: implement it in asm
-    ldmfd   sp!,{r1,lr}
-    tst     r1, #1
-    moveq   r0, r0, lsr #8
-    bx      lr
+    b       PicoVideoRead8
 
 
 m_m68k_read8_ram: