partial gmv implementation
authornotaz <notasas@gmail.com>
Mon, 25 Dec 2006 15:17:54 +0000 (15:17 +0000)
committernotaz <notasas@gmail.com>
Mon, 25 Dec 2006 15:17:54 +0000 (15:17 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@6 be3aeb3a-fb24-0410-a615-afba39da0efa

Pico/Memory.c
Pico/Pico.c
Pico/PicoInt.h
Pico/Sek.c
Pico/VideoPort.c
platform/gp2x/emu.c
platform/gp2x/menu.c
platform/linux/port_config.h

index d3b931c..3104eb4 100644 (file)
@@ -267,13 +267,16 @@ u32 OtherRead16(u32 a, int realsize)
   }\r
   // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers\r
   if (a==0xa11100) {\r
-    extern int z80stopCycle; // TODO: tidy\r
     d=Pico.m.z80Run&1;\r
+#if 0\r
     if (!d) {\r
+      // do we need this?\r
+      extern int z80stopCycle; // TODO: tidy\r
       int stop_before = SekCyclesDone() - z80stopCycle;\r
-      if (stop_before > 0 && stop_before <= 16*2) // Gens uses 16 here\r
+      if (stop_before > 0 && stop_before <= 16) // Gens uses 16 here\r
         d = 1; // bus not yet available\r
     }\r
+#endif\r
     d=(d<<8)|0x8000|Pico.m.rotate++;\r
     dprintf("get_zrun: %04x [%i|%i] @%06x", d, Pico.m.scanline, SekCyclesDone(), SekPc);\r
     goto end; }\r
@@ -569,7 +572,9 @@ static void CPU_CALL PicoWrite8(u32 a,u8 d)
   //  dprintf("w8 : %06x,   %02x @%06x", a&0xffffff, d, SekPc);\r
 \r
 \r
-  if ((a&0xe00000)==0xe00000) { u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram\r
+  if ((a&0xe00000)==0xe00000) {\r
+         if((a&0xffff)==0xf62a) dprintf("(f62a) = %02x [%i|%i] @ %x", d, Pico.m.scanline, SekCyclesDone(), SekPc);\r
+          u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram\r
 \r
   a&=0xffffff;\r
   OtherWrite8(a,d,8);\r
index 240c505..5ab8483 100644 (file)
@@ -194,22 +194,32 @@ static int dma_timings[] = {
 9,    18,  17,   9  // ...\r
 };\r
 \r
-static void CheckDMA(void)\r
+static int dma_bsycles[] = {\r
+(488<<8)/83,  (488<<8)/167, (488<<8)/166, (488<<8)/83,\r
+(488<<8)/102, (488<<8)/205, (488<<8)/204, (488<<8)/102,\r
+(488<<8)/8,   (488<<8)/16,  (488<<8)/15,  (488<<8)/8,\r
+(488<<8)/9,   (488<<8)/18,  (488<<8)/17,  (488<<8)/9\r
+};\r
+\r
+//static\r
+int CheckDMA(void)\r
 {\r
   int burn = 0, bytes_can = 0, dma_op = Pico.video.reg[0x17]>>6; // see gens for 00 and 01 modes\r
   int bytes = Pico.m.dma_bytes;\r
+  int dma_op1;\r
 \r
-  if(dma_op & 2) bytes_can = dma_op;\r
-  else if(Pico.video.type!=1) bytes_can  = 1; // setting dma_timings offset here according to Gens\r
-  if(Pico.video.reg[12] & 1)  bytes_can += 4; // 40 cell mode?\r
-  if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) { dma_op|=4; bytes_can += 8; } // active display?\r
-  bytes_can = dma_timings[bytes_can];\r
+  if(!(dma_op&2)) dma_op = (Pico.video.type==1) ? 0 : 1; // setting dma_timings offset here according to Gens\r
+  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
+  bytes_can = dma_timings[dma_op];\r
 \r
   if(bytes <= bytes_can) {\r
     if(dma_op&2) Pico.video.status&=~2; // dma no longer busy\r
     else {\r
-      if(dma_op&4) burn = bytes*(((488<<8)/18 ))>>8; // have to be approximate because can't afford division..\r
-      else         burn = bytes*(((488<<8)/205))>>8;\r
+      burn = bytes * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division..\r
+      //SekCycleCnt-=Pico.m.dma_endcycles;\r
+      //Pico.m.dma_endcycles = 0;\r
     }\r
     Pico.m.dma_bytes = 0;\r
   } else {\r
@@ -217,8 +227,10 @@ static void CheckDMA(void)
     Pico.m.dma_bytes -= bytes_can;\r
   }\r
 \r
-  SekCycleCnt+=burn;\r
-  dprintf("~Dma %i op=%i can=%i burn=%i [%i|%i]", Pico.m.dma_bytes, dma_op, bytes_can, burn, Pico.m.scanline, SekCyclesDone());\r
+  //SekCycleCnt+=burn;\r
+  dprintf("~Dma %i op=%i can=%i burn=%i [%i|%i]", Pico.m.dma_bytes, dma_op1, bytes_can, burn, Pico.m.scanline, SekCyclesDone());\r
+  //dprintf("~aim: %i, cnt: %i", SekCycleAim, SekCycleCnt);\r
+  return burn;\r
 }\r
 \r
 static __inline void SekRun(int cyc)\r
@@ -250,7 +262,9 @@ static __inline void SekRun(int cyc)
                Pico.m.scanline, SekCyclesDone());\r
   }\r
 #endif\r
+  //dprintf("aim: %i, cnt: %i", SekCycleAim, SekCycleCnt);\r
   if((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return;\r
+  //dprintf("cyc_do: %i", cyc_do);\r
 #if   defined(EMU_C68K) && defined(EMU_M68K)\r
   // this means we do run-compare Cyclone vs Musashi\r
   SekCycleCnt+=CM_compareRun(cyc_do);\r
@@ -390,12 +404,14 @@ static int PicoFrameHints(void)
     // V-Interrupt:\r
     if (y == lines_vis)\r
     {\r
-      //dprintf("vint: @ %06x [%i|%i]", SekPc, y, SekCycleCnt);\r
-      pv->status|=0x88; // V-Int happened, go into vblank\r
+      dprintf("vint: @ %06x [%i|%i], aim=%i cnt=%i", SekPc, y, SekCycleCnt, SekCycleAim, SekCycleCnt);\r
+      pv->status|=0x08; // go into vblank\r
       if(!Pico.m.dma_bytes||(Pico.video.reg[0x17]&0x80)) {\r
         // there must be a gap between H and V ints, also after vblank bit set (Mazin Saga, Bram Stoker's Dracula)\r
-        SekRun(128); SekCycleAim-=128;\r
+        SekRun(128); SekCycleAim-=128; // 128; ?\r
       }\r
+      dprintf("[%i|%i], aim=%i cnt=%i @ %x", y, SekCycleCnt, SekCycleAim, SekCycleCnt, SekPc);\r
+      pv->status|=0x80; // V-Int happened\r
       pv->pending_ints|=0x20;\r
       if(pv->reg[1]&0x20) SekInterrupt(6);\r
       if(Pico.m.z80Run && (PicoOpt&4)) // ?\r
@@ -421,7 +437,7 @@ static int PicoFrameHints(void)
       getSamples(y);\r
 \r
     // Run scanline:\r
-    if(Pico.m.dma_bytes) CheckDMA();\r
+    if(Pico.m.dma_bytes) SekCycleCnt+=CheckDMA();\r
     SekRun(cycles_68k);\r
     if((PicoOpt&4) && Pico.m.z80Run) {\r
       Pico.m.z80Run|=2;\r
index 4242452..dd1d417 100644 (file)
@@ -124,7 +124,8 @@ struct PicoMisc
   unsigned char sram_slave;  // EEPROM slave word for X24C02 and better SRAMs\r
   unsigned char prot_bytes[2]; // simple protection fakeing\r
   unsigned short dma_bytes;  //\r
-  unsigned char pad1[6];\r
+  unsigned char pad[2];\r
+  unsigned int  frame_count; // mainly for movies\r
 };\r
 \r
 // some assembly stuff depend on these, do not touch!\r
@@ -209,6 +210,7 @@ void PicoWriteCD32(unsigned int a, unsigned int d);
 extern struct Pico Pico;\r
 extern struct PicoSRAM SRam;\r
 extern int emustatus;\r
+int CheckDMA(void);\r
 \r
 // cd/Pico.c\r
 int  PicoInitMCD(void);\r
index df98d9d..b3b35a3 100644 (file)
@@ -81,8 +81,8 @@ static int SekUnrecognizedOpcode()
 #ifdef EMU_M68K\r
 static int SekIntAckM68K(int level)\r
 {\r
-  if     (level == 4) { Pico.video.pending_ints  =  0;    } // dprintf("hack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
-  else if(level == 6) { Pico.video.pending_ints &= ~0x20; } // dprintf("vack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
+  if     (level == 4) { Pico.video.pending_ints  =  0;    dprintf("hack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
+  else if(level == 6) { Pico.video.pending_ints &= ~0x20; dprintf("vack: [%i|%i]", Pico.m.scanline, SekCyclesDone()); }\r
   CPU_INT_LEVEL = 0;\r
   return M68K_INT_ACK_AUTOVECTOR;\r
 }\r
index 5d972f5..7f3d009 100644 (file)
@@ -58,6 +58,7 @@ static unsigned int VideoRead()
   return d;\r
 }\r
 \r
+#if 0\r
 // calculate the number of cycles 68k->VDP dma operation would take\r
 static int DmaSlowBurn(int len)\r
 {\r
@@ -75,6 +76,7 @@ static int DmaSlowBurn(int len)
 \r
   return burn;\r
 }\r
+#endif\r
 \r
 static int GetDmaLength()\r
 {\r
@@ -93,14 +95,15 @@ static void DmaSlow(int len)
   u16 *pd=0, *pdend, *r;\r
   unsigned int a=Pico.video.addr, a2, d;\r
   unsigned char inc=Pico.video.reg[0xf];\r
-  unsigned int source, burn;\r
+  unsigned int source; // , burn;\r
 \r
   source =Pico.video.reg[0x15]<<1;\r
   source|=Pico.video.reg[0x16]<<9;\r
   source|=Pico.video.reg[0x17]<<17;\r
 \r
-  dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i]", Pico.video.type, source, a, len, inc,\r
-           (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), Pico.m.scanline, SekCyclesDone());\r
+  dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i] @ %x",\r
+    Pico.video.type, source, a, len, inc, (Pico.video.status&8)||!(Pico.video.reg[1]&0x40),\r
+    Pico.m.scanline, SekCyclesDone(), SekPc);\r
 \r
   if ((source&0xe00000)==0xe00000) { pd=(u16 *)(Pico.ram+(source&0xfffe)); pdend=(u16 *)(Pico.ram+0x10000); } // Ram\r
   else if(source<Pico.romsize)     { pd=(u16 *)(Pico.rom+(source&~1)); pdend=(u16 *)(Pico.rom+Pico.romsize); } // Rom\r
@@ -116,8 +119,12 @@ static void DmaSlow(int len)
 #else\r
   Pico.m.dma_bytes += len;\r
 #endif\r
-  if(!(Pico.video.status&8))\r
-    SekEndRun(0);\r
+  //if(!(Pico.video.status&8))\r
+//    SekEndRun(0);\r
+       //Pico.m.dma_endcycles  = 0;//SekCyclesLeft;\r
+       //Pico.m.dma_endcycles -= Pico.m.dma_endcycles>>3; // hack\r
+       SekSetCyclesLeft(SekCyclesLeft - CheckDMA());\r
+//    CheckDMA();\r
 //  dprintf("DmaSlow burn: %i @ %06x", burn, SekPc);\r
 \r
   switch (Pico.video.type)\r
@@ -138,8 +145,6 @@ static void DmaSlow(int len)
       break;\r
 \r
     case 3: // cram\r
-      dprintf("DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%i|%i]", Pico.video.type, source, a, len, inc,\r
-               (Pico.video.status&8)||!(Pico.video.reg[1]&0x40), Pico.m.scanline, SekCyclesDone());\r
       Pico.m.dirtyPal = 1;\r
       r = Pico.cram;\r
       for(a2=a&0x7f; len; len--)\r
@@ -314,8 +319,8 @@ void PicoVideoWrite(unsigned int a,unsigned short d)
       {\r
         // Register write:\r
         int num=(d>>8)&0x1f;\r
-        //if(num==00) dprintf("hint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[0]&0x10)>>4, (d&0x10)>>4, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc);\r
-        //if(num==01) dprintf("vint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[1]&0x20)>>5, (d&0x20)>>5, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc);\r
+        if(num==00) dprintf("hint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[0]&0x10)>>4, (d&0x10)>>4, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc);\r
+        if(num==01) dprintf("vint_onoff: %i->%i [%i|%i] pend=%i @ %06x", (pvid->reg[1]&0x20)>>5, (d&0x20)>>5, Pico.m.scanline, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc);\r
         //if(num==01) dprintf("set_blank: %i @ %06x [%i|%i]", !((d&0x40)>>6), SekPc, Pico.m.scanline, SekCyclesDone());\r
         //if(num==05) dprintf("spr_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone());\r
         //if(num==10) dprintf("hint_set: %i @ %06x [%i|%i]", (unsigned char)d, SekPc, Pico.m.scanline, SekCyclesDone());\r
index 14eadeb..d84b053 100644 (file)
@@ -55,7 +55,6 @@ static int combo_keys = 0, combo_acts = 0;    // keys and actions which need button
 static int gp2x_old_gamma = 100;\r
 static unsigned char *movie_data = NULL;\r
 static int movie_size = 0;\r
-int frame_count = 0;\r
 unsigned char *framebuff = 0;  // temporary buffer for alt renderer\r
 int state_slot = 0;\r
 \r
@@ -246,7 +245,7 @@ int emu_ReloadRom(void)
        if(currentConfig.EmuOpt & 1)\r
                emu_SaveLoadGame(1, 1);\r
 \r
-       frame_count = 0;\r
+       Pico.m.frame_count = 0;\r
 \r
        return 1;\r
 }\r
@@ -713,7 +712,7 @@ static void updateKeys(void)
 \r
        if(movie_data)\r
        {\r
-               int offs = frame_count*3 + 0x40;\r
+               int offs = Pico.m.frame_count*3 + 0x40;\r
                if (offs+3 > movie_size) {\r
                        free(movie_data);\r
                        movie_data = 0;\r
@@ -736,8 +735,6 @@ static void updateKeys(void)
                        PicoPad[1] |= (~movie_data[offs+2] & 0xA0) << 4; // ! MZYX\r
                        if(!(movie_data[offs+2] & 0x10)) PicoPad[1] |= 0x0400; // X\r
                        if(!(movie_data[offs+2] & 0x40)) PicoPad[1] |= 0x0100; // Z\r
-                       if ((PicoPad[0] & 0x80) || (PicoPad[1] & 0x80))\r
-                               printf("%d: start\n", frame_count);\r
                }\r
        }\r
        else\r
@@ -745,7 +742,7 @@ static void updateKeys(void)
                PicoPad[0] = (unsigned short) allActions[0];\r
                PicoPad[1] = (unsigned short) allActions[1];\r
        }\r
-       frame_count++;\r
+       Pico.m.frame_count++;\r
 \r
        events = (allActions[0] | allActions[1]) >> 16;\r
 \r
@@ -995,21 +992,59 @@ void emu_Loop(void)
                updateKeys();\r
                PicoFrame();\r
 \r
+#if 0\r
+if (Pico.m.frame_count == 31563) {\r
+       FILE *f;\r
+       f = fopen("ram_p.bin", "wb");\r
+       if (!f) { printf("!f\n"); exit(1); }\r
+       fwrite(Pico.ram, 1, 0x10000, f);\r
+       fclose(f);\r
+       exit(0);\r
+}\r
+#endif\r
 #if 0\r
                // debug\r
                {\r
-                       static unsigned char oldscr[320*240*2];\r
+                       #define BYTE unsigned char\r
+                       #define WORD unsigned short\r
+                       struct\r
+                       {\r
+                               BYTE IDLength;        /* 00h  Size of Image ID field */\r
+                               BYTE ColorMapType;    /* 01h  Color map type */\r
+                               BYTE ImageType;       /* 02h  Image type code */\r
+                               WORD CMapStart;       /* 03h  Color map origin */\r
+                               WORD CMapLength;      /* 05h  Color map length */\r
+                               BYTE CMapDepth;       /* 07h  Depth of color map entries */\r
+                               WORD XOffset;         /* 08h  X origin of image */\r
+                               WORD YOffset;         /* 0Ah  Y origin of image */\r
+                               WORD Width;           /* 0Ch  Width of image */\r
+                               WORD Height;          /* 0Eh  Height of image */\r
+                               BYTE PixelDepth;      /* 10h  Image pixel size */\r
+                               BYTE ImageDescriptor; /* 11h  Image descriptor byte */\r
+                       } __attribute__((packed)) TGAHEAD;\r
+                       static unsigned short oldscr[320*240];\r
                        FILE *f; char name[128]; int i;\r
-                       for (i = 0; i < 320*240*2; i++)\r
-                               if(oldscr[i] != ((unsigned char *)gp2x_screen)[i]) break;\r
-                       if (i < 320*240*2)\r
+\r
+                       memset(&TGAHEAD, 0, sizeof(TGAHEAD));\r
+                       TGAHEAD.ImageType = 2;\r
+                       TGAHEAD.Width = 320;\r
+                       TGAHEAD.Height = 240;\r
+                       TGAHEAD.PixelDepth = 16;\r
+                       TGAHEAD.ImageDescriptor = 2<<4; // image starts at top-left\r
+\r
+                       #define CONV(X) (((X>>1)&0x7fe0)|(X&0x1f)) // 555?\r
+\r
+                       for (i = 0; i < 320*240; i++)\r
+                               if(oldscr[i] != CONV(((unsigned short *)gp2x_screen)[i])) break;\r
+                       if (i < 320*240)\r
                        {\r
-                               for (i = 0; i < 320*240*2; i++)\r
-                                       oldscr[i] = ((unsigned char *)gp2x_screen)[i];\r
-                               sprintf(name, "%05i.raw", frame_count);\r
+                               for (i = 0; i < 320*240; i++)\r
+                                       oldscr[i] = CONV(((unsigned short *)gp2x_screen)[i]);\r
+                               sprintf(name, "%05i.tga", Pico.m.frame_count);\r
                                f = fopen(name, "wb");\r
                                if (!f) { printf("!f\n"); exit(1); }\r
-                               fwrite(gp2x_screen, 1, 320*240*2, f);\r
+                               fwrite(&TGAHEAD, 1, sizeof(TGAHEAD), f);\r
+                               fwrite(oldscr, 1, 320*240*2, f);\r
                                fclose(f);\r
                        }\r
                }\r
index 6336126..588e0c9 100644 (file)
@@ -603,7 +603,7 @@ static void draw_amenu_options(int menu_sel)
 \r
 static void amenu_loop_options(void)\r
 {\r
-       int menu_sel = 0, menu_sel_max = 11;\r
+       int menu_sel = 0, menu_sel_max = 10;\r
        unsigned long inp = 0;\r
 \r
        for(;;)\r
index b679bab..be76af4 100644 (file)
@@ -12,9 +12,7 @@
 // pico.c
 #define CAN_HANDLE_240_LINES   1
 
-extern int frame_count;
-
-#define dprintf(f,...) printf("%05i: " f "\n",frame_count,##__VA_ARGS__)
+#define dprintf(f,...) printf("%05i: " f "\n",Pico.m.frame_count,##__VA_ARGS__)
 //#define dprintf(x...)
 
 #endif //PORT_CONFIG_H