nonacc mode removal, function return value audit
[picodrive.git] / Pico / Misc.c
index 887e90c..944e4c8 100644 (file)
@@ -85,141 +85,97 @@ const unsigned char hcounts_32[] = {
 0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,\r
 };\r
 \r
-// vcounter values for PicoFrameSimple \r
-const unsigned short vcounts[] = {\r
-  0,  0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,\r
-  8,  8,  9,  9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,\r
- 16, 17, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 24, 24,\r
- 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 31, 31, 32, 32, 33,\r
- 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41,\r
- 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49,\r
- 50, 50, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58,\r
- 58, 59, 59, 60, 60, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66,\r
- 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 73, 74, 74, 75,\r
- 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 83, 83,\r
- 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91,\r
- 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99,100,\r
-100,101,101,102,102,103,104,104,105,105,106,106,107,107,108,108,\r
-109,109,110,110,111,111,112,112,113,114,114,115,115,116,116,117,\r
-117,118,118,119,119,120,120,121,121,122,122,123,124,124,125,125,\r
-126,126,127,127,128,128,129,129,130,130,131,131,132,132,133,133,\r
-134,135,135,136,136,137,137,138,138,139,139,140,140,141,141,142,\r
-142,143,143,144,145,145,146,146,147,147,148,148,149,149,150,150,\r
-151,151,152,152,153,153,154,155,155,156,156,157,157,158,158,159,\r
-159,160,160,161,161,162,162,163,163,164,164,165,166,166,167,167,\r
-168,168,169,169,170,170,171,171,172,172,173,173,174,174,175,176,\r
-176,177,177,178,178,179,179,180,180,181,181,182,182,183,183,184,\r
-184,185,186,186,187,187,188,188,189,189,190,190,191,191,192,192,\r
-193,193,194,194,195,195,196,197,197,198,198,199,199,200,200,201,\r
-201,202,202,203,203,204,204,205,205,206,207,207,208,208,209,209,\r
-210,210,211,211,212,212,213,213,214,214,215,215,216,217,217,218,\r
-218,219,219,220,220,221,221,222,222,223,223,224,224,225,225,226,\r
-226,227,228,228,229,229,230,230,231,231,232,232,233,233,234,234,\r
-235,235,236,236,237,238,238,239,239,240,240,241,241,242,242,243,\r
-243,244,244,245,245,246,246,247,248,248,249,249,250,250,251,251,\r
-252,252,253,253,254,254,255,255,256,256,257,257,258,259,259,260,\r
-260,261,261,262,262,263,263,264,264,265,265,266,266,267,267,268,\r
-269,269,270,270,271,271,272,272,273,273,274,274,275,275,276,276,\r
-277,277,278,279,279,280,280,281,281,282,282,283,283,284,284,285,\r
-285,286,286,287,287,288,288,289,290,290,291,291,292,292,293,293,\r
-294,294,295,295,296,296,297,297,298,298,299,300,300,301,301,302,\r
-302,303,303,304,304,305,305,306,306,307,307,308,308,309,310,310,\r
-311,311,311,311,\r
-};\r
-\r
 \r
 // rarely used EEPROM SRAM code\r
 // known games which use this:\r
 // Wonder Boy in Monster World, Megaman - The Wily Wars (X24C01, 128 bytes)\r
-// NFL Quarterback Club*, Frank Thomas Big Hurt Baseball (X24C04?)\r
-// College Slam, Blockbuster World Video Game Championship II, NBA Jam (X24C04?)\r
-// HardBall '95\r
 \r
-// the above sports games use addr 0x200000 for SCL line (handled in Memory.c)\r
+// (see Genesis Plus for Wii/GC code and docs for info,\r
+//  full game list and better code).\r
 \r
 unsigned int lastSSRamWrite = 0xffff0000;\r
 \r
-// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=type(1==uses 0x200000 for SCL and 2K bytes),\r
+// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),\r
 //                      d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)\r
-void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
+PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
 {\r
-  unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.sram_addr, scyc = Pico.m.sram_cycle, ssa = Pico.m.sram_slave;\r
+  unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;\r
 \r
-  //dprintf("[%02x]", d);\r
-  sreg |= saddr&0xc000; // we store word count in add reg: dw?a aaaa ...  (d=word count detected, w=words(0==use 2 words, else 1))\r
+  elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1,\r
+    (d&2)>>1, d&1, SekCyclesDoneT()-lastSSRamWrite);\r
   saddr&=0x1fff;\r
 \r
   if(sreg & d & 2) {\r
     // SCL was and is still high..\r
     if((sreg & 1) && !(d&1)) {\r
       // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter\r
-      //dprintf("-start-");\r
-         if(!(sreg&0x8000) && scyc >= 9) {\r
-           if(scyc != 28) sreg |= 0x4000; // 1 word\r
-        //dprintf("detected word count: %i", scyc==28 ? 2 : 1);\r
-               sreg |= 0x8000;\r
-         }\r
+      elprintf(EL_EEPROM, "eeprom: -start-");\r
       //saddr = 0;\r
       scyc = 0;\r
       sreg |= 8;\r
     } else if(!(sreg & 1) && (d&1)) {\r
       // SDA went high == stop command\r
-      //dprintf("-stop-");\r
+      elprintf(EL_EEPROM, "eeprom: -stop-");\r
       sreg &= ~8;\r
     }\r
   }\r
-  else if((sreg & 8) && !(sreg & 2) && (d&2)) {\r
+  else if((sreg & 8) && !(sreg & 2) && (d&2))\r
+  {\r
     // we are started and SCL went high - next cycle\r
     scyc++; // pre-increment\r
-       if(sreg & 0x20) {\r
+    if(SRam.eeprom_type) {\r
       // X24C02+\r
-         if((ssa&1) && scyc == 18) {\r
-           scyc = 9;\r
-               saddr++; // next address in read mode\r
-               if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask\r
-         }\r
-         else if((sreg&0x4000) && scyc == 27) scyc = 18;\r
-         else if(scyc == 36) scyc = 27;\r
-       } else {\r
-         // X24C01\r
+      if((ssa&1) && scyc == 18) {\r
+        scyc = 9;\r
+        saddr++; // next address in read mode\r
+        /*if(SRam.eeprom_type==2) saddr&=0xff; else*/ saddr&=0x1fff; // mask\r
+      }\r
+      else if(SRam.eeprom_type == 2 && scyc == 27) scyc = 18;\r
+      else if(scyc == 36) scyc = 27;\r
+    } else {\r
+      // X24C01\r
       if(scyc == 18) {\r
         scyc = 9;  // wrap\r
         if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode\r
-         }\r
-       }\r
-       //dprintf("scyc: %i", scyc);\r
+      }\r
+    }\r
+    elprintf(EL_EEPROM, "eeprom: scyc: %i", scyc);\r
   }\r
-  else if((sreg & 8) && (sreg & 2) && !(d&2)) {\r
+  else if((sreg & 8) && (sreg & 2) && !(d&2))\r
+  {\r
     // we are started and SCL went low (falling edge)\r
-    if(sreg & 0x20) {\r
-         // X24C02+\r
-         if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles\r
-         else if( (!(sreg&0x4000) && scyc > 27) || ((sreg&0x4000) && scyc > 18) ) {\r
+    if(SRam.eeprom_type) {\r
+      // X24C02+\r
+      if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles\r
+      else if( (SRam.eeprom_type == 3 && scyc > 27) || (SRam.eeprom_type == 2 && scyc > 18) ) {\r
         if(!(ssa&1)) {\r
           // data write\r
           unsigned char *pm=SRam.data+saddr;\r
           *pm <<= 1; *pm |= d&1;\r
           if(scyc == 26 || scyc == 35) {\r
             saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented\r
-            //dprintf("w done: %02x; addr inc: %x", *pm, saddr);\r
+            elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr, *pm);\r
           }\r
           SRam.changed = 1;\r
         }\r
       } else if(scyc > 9) {\r
         if(!(ssa&1)) {\r
           // we latch another addr bit\r
-                 saddr<<=1;\r
-                 if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask\r
-                 saddr|=d&1;\r
-          //if(scyc==17||scyc==26) dprintf("addr reg done: %x", saddr);\r
-               }\r
+          saddr<<=1;\r
+          if(SRam.eeprom_type == 2) saddr&=0xff; else saddr&=0x1fff; // mask\r
+          saddr|=d&1;\r
+          if(scyc==17||scyc==26) {\r
+            elprintf(EL_EEPROM, "eeprom: addr reg done: %x", saddr);\r
+            if(scyc==17&&SRam.eeprom_type==2) { saddr&=0xff; saddr|=(ssa<<7)&0x700; } // add device bits too\r
+          }\r
+        }\r
       } else {\r
-           // slave address\r
-               ssa<<=1; ssa|=d&1;\r
-        //if(scyc==8) dprintf("slave done: %x", ssa);\r
+        // slave address\r
+        ssa<<=1; ssa|=d&1;\r
+        if(scyc==8) elprintf(EL_EEPROM, "eeprom: slave done: %x", ssa);\r
       }\r
-       } else {\r
-         // X24C01\r
+    } else {\r
+      // X24C01\r
       if(scyc == 9); // ACK cycle, do nothing\r
       else if(scyc > 9) {\r
         if(!(saddr&1)) {\r
@@ -228,78 +184,157 @@ void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
           *pm <<= 1; *pm |= d&1;\r
           if(scyc == 17) {\r
             saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented\r
-            //dprintf("addr inc: %x", saddr>>1);\r
+            elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr>>1, *pm);\r
           }\r
           SRam.changed = 1;\r
         }\r
       } else {\r
         // we latch another addr bit\r
         saddr<<=1; saddr|=d&1; saddr&=0xff;\r
-        //if(scyc==8) dprintf("addr done: %x", saddr>>1);\r
+        if(scyc==8) elprintf(EL_EEPROM, "eeprom: addr done: %x", saddr>>1);\r
       }\r
-       }\r
+    }\r
   }\r
 \r
   sreg &= ~3; sreg |= d&3; // remember SCL and SDA\r
-  Pico.m.sram_reg  = (unsigned char)  sreg;\r
-  Pico.m.sram_addr = (unsigned short)(saddr|(sreg&0xc000));\r
-  Pico.m.sram_cycle= (unsigned char)  scyc;\r
-  Pico.m.sram_slave= (unsigned char)  ssa;\r
+  Pico.m.sram_reg    = (unsigned char) sreg;\r
+  Pico.m.eeprom_cycle= (unsigned char) scyc;\r
+  Pico.m.eeprom_slave= (unsigned char) ssa;\r
+  Pico.m.eeprom_addr = (unsigned short)saddr;\r
 }\r
 \r
-unsigned int SRAMReadEEPROM()\r
+PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)\r
 {\r
-  unsigned int shift, d=0;\r
-  unsigned int sreg, saddr, scyc, ssa;\r
+  unsigned int shift, d;\r
+  unsigned int sreg, saddr, scyc, ssa, interval;\r
 \r
   // flush last pending write\r
   SRAMWriteEEPROM(Pico.m.sram_reg>>6);\r
 \r
-  sreg = Pico.m.sram_reg; saddr = Pico.m.sram_addr&0x1fff; scyc = Pico.m.sram_cycle; ssa = Pico.m.sram_slave;\r
-//  if(!(sreg & 2) && (sreg&0x80)) scyc++; // take care of raising edge now to compensate lag\r
+  sreg = Pico.m.sram_reg; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;\r
+  interval = SekCyclesDoneT()-lastSSRamWrite;\r
+  d = (sreg>>6)&1; // use SDA as "open bus"\r
+\r
+  // NBA Jam is nasty enough to read <before> raising the SCL and starting the new cycle.\r
+  // this is probably valid because data changes occur while SCL is low and data can be read\r
+  // before it's actual cycle begins.\r
+  if (!(sreg&0x80) && interval >= 24) {\r
+    elprintf(EL_EEPROM, "eeprom: early read, cycles=%i", interval);\r
+    scyc++;\r
+  }\r
 \r
-  if(SekCyclesDoneT()-lastSSRamWrite < 46) {\r
-    // data was just written, there was no time to respond (used by sports games)\r
-    d = (sreg>>6)&1;\r
-  } else if((sreg & 8) && scyc > 9 && scyc != 18 && scyc != 27) {\r
+  if (!(sreg & 8)); // not started, use open bus\r
+  else if (scyc == 9 || scyc == 18 || scyc == 27) {\r
+    elprintf(EL_EEPROM, "eeprom: r ack");\r
+    d = 0;\r
+  } else if (scyc > 9 && scyc < 18) {\r
     // started and first command word received\r
     shift = 17-scyc;\r
-    if(sreg & 0x20) {\r
-         // X24C02+\r
-      if(ssa&1) {\r
-        //dprintf("read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg);\r
-           d = (SRam.data[saddr]>>shift)&1;\r
-         }\r
-       } else {\r
-         // X24C01\r
-      if(saddr&1) {\r
-               d = (SRam.data[saddr>>1]>>shift)&1;\r
-         }\r
-       }\r
+    if (SRam.eeprom_type) {\r
+      // X24C02+\r
+      if (ssa&1) {\r
+        elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg);\r
+       if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr]);\r
+        d = (SRam.data[saddr]>>shift)&1;\r
+      }\r
+    } else {\r
+      // X24C01\r
+      if (saddr&1) {\r
+        elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr>>1, scyc, sreg);\r
+       if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr>>1]);\r
+        d = (SRam.data[saddr>>1]>>shift)&1;\r
+      }\r
+    }\r
   }\r
-  //else dprintf("r ack");\r
 \r
-  return d;\r
+  return (d << SRam.eeprom_bit_out);\r
 }\r
 \r
-void SRAMUpdPending(unsigned int a, unsigned int d)\r
+PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)\r
 {\r
-  unsigned int sreg = Pico.m.sram_reg;\r
+  unsigned int d1, sreg = Pico.m.sram_reg;\r
 \r
-  if(!(a&1)) sreg|=0x20;\r
-\r
-  if(sreg&0x20) { // address through 0x200000\r
-    if(!(a&1)) {\r
-      sreg&=~0x80;\r
-      sreg|=d<<7;\r
-    } else {\r
-      sreg&=~0x40;\r
-      sreg|=(d<<6)&0x40;\r
-    }\r
-  } else {\r
-    sreg&=~0xc0;\r
-    sreg|=d<<6;\r
+  if (!((SRam.eeprom_abits^a)&1))\r
+  {\r
+    // SCL\r
+    sreg &= ~0x80;\r
+    d1 = (d >> SRam.eeprom_bit_cl) & 1;\r
+    sreg |= d1<<7;\r
+  }\r
+  if (!(((SRam.eeprom_abits>>1)^a)&1))\r
+  {\r
+    // SDA in\r
+    sreg &= ~0x40;\r
+    d1 = (d >> SRam.eeprom_bit_in) & 1;\r
+    sreg |= d1<<6;\r
   }\r
 \r
   Pico.m.sram_reg = (unsigned char) sreg;\r
 }\r
+\r
+\r
+#ifndef _ASM_MISC_C\r
+typedef struct\r
+{\r
+       int b0;\r
+       int b1;\r
+       int b2;\r
+       int b3;\r
+       int b4;\r
+       int b5;\r
+       int b6;\r
+       int b7;\r
+} intblock;\r
+\r
+PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count)\r
+{\r
+       if ((((int)dest | (int)src) & 3) == 0)\r
+       {\r
+               if (count >= 32) {\r
+                       memcpy32((int *)dest, (int *)src, count/2);\r
+                       count&=1;\r
+               } else {\r
+                       for (; count >= 2; count -= 2, dest+=2, src+=2)\r
+                               *(int *)dest = *(int *)src;\r
+               }\r
+       }\r
+       while (count--)\r
+               *dest++ = *src++;\r
+}\r
+\r
+\r
+PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count)\r
+{\r
+       unsigned char *src_ = src;\r
+\r
+       for (; count; count--, src_ += 2)\r
+               *dest++ = (src_[0] << 8) | src_[1];\r
+}\r
+\r
+#ifndef _ASM_MISC_C_AMIPS\r
+PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)\r
+{\r
+       intblock *bd = (intblock *) dest, *bs = (intblock *) src;\r
+\r
+       for (; count >= sizeof(*bd)/4; count -= sizeof(*bd)/4)\r
+               *bd++ = *bs++;\r
+\r
+       dest = (int *)bd; src = (int *)bs;\r
+       while (count--)\r
+               *dest++ = *src++;\r
+}\r
+\r
+\r
+PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)\r
+{\r
+       for (; count >= 8; count -= 8, dest += 8)\r
+               dest[0] = dest[1] = dest[2] = dest[3] =\r
+               dest[4] = dest[5] = dest[6] = dest[7] = c;\r
+\r
+       while (count--)\r
+               *dest++ = c;\r
+}\r
+void memset32_uncached(int *dest, int c, int count) { memset32(dest, c, count); }\r
+#endif\r
+#endif\r
+\r