handle dbra wait loops, update cyclone
[picodrive.git] / pico / 32x / memory.c
index 08e48e8..722698e 100644 (file)
@@ -65,7 +65,7 @@ static int m68k_poll_detect(u32 a, u32 cycles, u32 flags)
   int ret = 0;
 
   if (a - 2 <= m68k_poll.addr && m68k_poll.addr <= a + 2
-    && cycles - m68k_poll.cycles <= 64)
+    && cycles - m68k_poll.cycles <= 64 && !SekNotPolling)
   {
     if (m68k_poll.cnt++ > POLL_THRESHOLD) {
       if (!(Pico32x.emu_flags & flags)) {
@@ -79,6 +79,7 @@ static int m68k_poll_detect(u32 a, u32 cycles, u32 flags)
   else {
     m68k_poll.cnt = 0;
     m68k_poll.addr = a;
+    SekNotPolling = 0;
   }
   m68k_poll.cycles = cycles;
 
@@ -186,15 +187,9 @@ static u32 p32x_reg_read16(u32 a)
     return sh2_comm_faker(a);
 #else
   if ((a & 0x30) == 0x20) {
-    static u32 dr2 = 0;
-    unsigned int cycles = SekCyclesDoneT();
+    unsigned int cycles = SekCyclesDone();
     int comreg = 1 << (a & 0x0f) / 2;
 
-    // evil X-Men proto polls in a dbra loop and expects it to expire..
-    if (SekDar(2) != dr2)
-      m68k_poll.cnt = 0;
-    dr2 = SekDar(2);
-
     if (cycles - msh2.m68krcycles_done > 244
         || (Pico32x.comm_dirty_68k & comreg))
       p32x_sync_sh2s(cycles);
@@ -205,20 +200,19 @@ static u32 p32x_reg_read16(u32 a)
       SekSetStop(1);
       SekEndRun(16);
     }
-    dr2 = SekDar(2);
     goto out;
   }
 #endif
 
   if (a == 2) { // INTM, INTS
-    unsigned int cycles = SekCyclesDoneT();
+    unsigned int cycles = SekCyclesDone();
     if (cycles - msh2.m68krcycles_done > 64)
       p32x_sync_sh2s(cycles);
     goto out;
   }
 
   if ((a & 0x30) == 0x30)
-    return p32x_pwm_read16(a, NULL, SekCyclesDoneT());
+    return p32x_pwm_read16(a, NULL, SekCyclesDone());
 
 out:
   return Pico32x.regs[a / 2];
@@ -241,7 +235,7 @@ static void dreq0_write(u16 *r, u32 d)
       r[6 / 2] &= ~P32XS_68S;
 
     if ((Pico32x.dmac0_fifo_ptr & 3) == 0) {
-      p32x_sync_sh2s(SekCyclesDoneT());
+      p32x_sync_sh2s(SekCyclesDone());
       p32x_dreq0_trigger();
     }
   }
@@ -272,7 +266,7 @@ static void p32x_reg_write8(u32 a, u32 d)
       return;
     case 0x03: // irq ctl
       if ((d ^ r[0x02 / 2]) & 3) {
-        int cycles = SekCyclesDoneT();
+        int cycles = SekCyclesDone();
         p32x_sync_sh2s(cycles);
         r[0x02 / 2] = d & 3;
         p32x_update_cmd_irq(NULL, cycles);
@@ -383,12 +377,12 @@ static void p32x_reg_write8(u32 a, u32 d)
     case 0x3f:
       return;
     pwm_write:
-      p32x_pwm_write16(a & ~1, d, NULL, SekCyclesDoneT());
+      p32x_pwm_write16(a & ~1, d, NULL, SekCyclesDone());
       return;
   }
 
   if ((a & 0x30) == 0x20) {
-    int cycles = SekCyclesDoneT();
+    int cycles = SekCyclesDone();
     int comreg;
     
     if (REG8IN16(r, a) == d)
@@ -448,13 +442,13 @@ static void p32x_reg_write16(u32 a, u32 d)
     case 0x30: // PWM control
       d = (r[a / 2] & ~0x0f) | (d & 0x0f);
       r[a / 2] = d;
-      p32x_pwm_write16(a, d, NULL, SekCyclesDoneT());
+      p32x_pwm_write16(a, d, NULL, SekCyclesDone());
       return;
   }
 
   // comm port
   if ((a & 0x30) == 0x20) {
-    int cycles = SekCyclesDoneT();
+    int cycles = SekCyclesDone();
     int comreg;
     
     if (r[a / 2] == d)
@@ -475,7 +469,7 @@ static void p32x_reg_write16(u32 a, u32 d)
   }
   // PWM
   else if ((a & 0x30) == 0x30) {
-    p32x_pwm_write16(a, d, NULL, SekCyclesDoneT());
+    p32x_pwm_write16(a, d, NULL, SekCyclesDone());
     return;
   }
 
@@ -571,7 +565,7 @@ static void p32x_vdp_write16(u32 a, u32 d, SH2 *sh2)
 static u32 p32x_sh2reg_read16(u32 a, SH2 *sh2)
 {
   u16 *r = Pico32x.regs;
-  a &= 0xfe; // ?
+  a &= 0x3e;
 
   switch (a) {
     case 0x00: // adapter/irq ctl
@@ -628,7 +622,7 @@ static void p32x_sh2reg_write8(u32 a, u32 d, SH2 *sh2)
   u16 *r = Pico32x.regs;
   u32 old;
 
-  a &= 0xff;
+  a &= 0x3f;
   sh2->poll_addr = 0;
 
   switch (a) {
@@ -724,7 +718,7 @@ static void p32x_sh2reg_write8(u32 a, u32 d, SH2 *sh2)
 
 static void p32x_sh2reg_write16(u32 a, u32 d, SH2 *sh2)
 {
-  a &= 0xfe;
+  a &= 0x3e;
 
   sh2->poll_addr = 0;
 
@@ -1194,13 +1188,13 @@ static u32 sh2_read8_cs0(u32 a, SH2 *sh2)
 
   sh2_burn_cycles(sh2, 1*2);
 
-  // 0x3ff00 is veridied
-  if ((a & 0x3ff00) == 0x4000) {
+  // 0x3ffc0 is veridied
+  if ((a & 0x3ffc0) == 0x4000) {
     d = p32x_sh2reg_read16(a, sh2);
     goto out_16to8;
   }
 
-  if ((a & 0x3ff00) == 0x4100) {
+  if ((a & 0x3fff0) == 0x4100) {
     d = p32x_vdp_read16(a);
     sh2_poll_detect(sh2, a, SH2_STATE_VPOLL, 7);
     goto out_16to8;
@@ -1208,9 +1202,9 @@ static u32 sh2_read8_cs0(u32 a, SH2 *sh2)
 
   // TODO: mirroring?
   if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
-    return Pico32xMem->sh2_rom_m[a ^ 1];
+    return Pico32xMem->sh2_rom_m.b[a ^ 1];
   if (sh2->is_slave  && a < sizeof(Pico32xMem->sh2_rom_s))
-    return Pico32xMem->sh2_rom_s[a ^ 1];
+    return Pico32xMem->sh2_rom_s.b[a ^ 1];
 
   if ((a & 0x3fe00) == 0x4200) {
     d = Pico32xMem->pal[(a & 0x1ff) / 2];
@@ -1249,23 +1243,23 @@ static u32 sh2_read16_cs0(u32 a, SH2 *sh2)
 
   sh2_burn_cycles(sh2, 1*2);
 
-  if ((a & 0x3ff00) == 0x4000) {
+  if ((a & 0x3ffc0) == 0x4000) {
     d = p32x_sh2reg_read16(a, sh2);
     if (!(EL_LOGMASK & EL_PWM) && (a & 0x30) == 0x30) // hide PWM
       return d;
     goto out;
   }
 
-  if ((a & 0x3ff00) == 0x4100) {
+  if ((a & 0x3fff0) == 0x4100) {
     d = p32x_vdp_read16(a);
     sh2_poll_detect(sh2, a, SH2_STATE_VPOLL, 7);
     goto out;
   }
 
   if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
-    return *(u16 *)(Pico32xMem->sh2_rom_m + a);
+    return Pico32xMem->sh2_rom_m.w[a / 2];
   if (sh2->is_slave  && a < sizeof(Pico32xMem->sh2_rom_s))
-    return *(u16 *)(Pico32xMem->sh2_rom_s + a);
+    return Pico32xMem->sh2_rom_s.w[a / 2];
 
   if ((a & 0x3fe00) == 0x4200) {
     d = Pico32xMem->pal[(a & 0x1ff) / 2];
@@ -1303,14 +1297,14 @@ static void REGPARM(3) sh2_write8_cs0(u32 a, u32 d, SH2 *sh2)
     a, d & 0xff, sh2_pc(sh2));
 
   if (Pico32x.regs[0] & P32XS_FM) {
-    if ((a & 0x3ff00) == 0x4100) {
+    if ((a & 0x3fff0) == 0x4100) {
       sh2->poll_addr = 0;
       p32x_vdp_write8(a, d);
       return;
     }
   }
 
-  if ((a & 0x3ff00) == 0x4000) {
+  if ((a & 0x3ffc0) == 0x4000) {
     p32x_sh2reg_write8(a, d, sh2);
     return;
   }
@@ -1374,7 +1368,7 @@ static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
       a, d & 0xffff, sh2_pc(sh2));
 
   if (Pico32x.regs[0] & P32XS_FM) {
-    if ((a & 0x3ff00) == 0x4100) {
+    if ((a & 0x3fff0) == 0x4100) {
       sh2->poll_addr = 0;
       p32x_vdp_write16(a, d, sh2);
       return;
@@ -1387,7 +1381,7 @@ static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
     }
   }
 
-  if ((a & 0x3ff00) == 0x4000) {
+  if ((a & 0x3ffc0) == 0x4000) {
     p32x_sh2reg_write16(a, d, sh2);
     return;
   }
@@ -1619,17 +1613,17 @@ static void get_bios(void)
   // MSH2
   if (p32x_bios_m != NULL) {
     elprintf(EL_STATUS|EL_32X, "32x: using supplied master SH2 BIOS");
-    Byteswap(Pico32xMem->sh2_rom_m, p32x_bios_m, sizeof(Pico32xMem->sh2_rom_m));
+    Byteswap(&Pico32xMem->sh2_rom_m, p32x_bios_m, sizeof(Pico32xMem->sh2_rom_m));
   }
   else {
-    pl = (u32 *)Pico32xMem->sh2_rom_m;
+    pl = (u32 *)&Pico32xMem->sh2_rom_m;
 
     // fill exception vector table to our trap address
     for (i = 0; i < 128; i++)
       pl[i] = HWSWAP(0x200);
 
     // startup code
-    memcpy(Pico32xMem->sh2_rom_m + 0x200, msh2_code, sizeof(msh2_code));
+    memcpy(&Pico32xMem->sh2_rom_m.b[0x200], msh2_code, sizeof(msh2_code));
 
     // reset SP
     pl[1] = pl[3] = HWSWAP(0x6040000);
@@ -1640,17 +1634,17 @@ static void get_bios(void)
   // SSH2
   if (p32x_bios_s != NULL) {
     elprintf(EL_STATUS|EL_32X, "32x: using supplied slave SH2 BIOS");
-    Byteswap(Pico32xMem->sh2_rom_s, p32x_bios_s, sizeof(Pico32xMem->sh2_rom_s));
+    Byteswap(&Pico32xMem->sh2_rom_s, p32x_bios_s, sizeof(Pico32xMem->sh2_rom_s));
   }
   else {
-    pl = (u32 *)Pico32xMem->sh2_rom_s;
+    pl = (u32 *)&Pico32xMem->sh2_rom_s;
 
     // fill exception vector table to our trap address
     for (i = 0; i < 128; i++)
       pl[i] = HWSWAP(0x200);
 
     // startup code
-    memcpy(Pico32xMem->sh2_rom_s + 0x200, ssh2_code, sizeof(ssh2_code));
+    memcpy(&Pico32xMem->sh2_rom_s.b[0x200], ssh2_code, sizeof(ssh2_code));
 
     // reset SP
     pl[1] = pl[3] = HWSWAP(0x603f800);