32x, fix soc code (sh2 sr register handling)
authorkub <derkub@gmail.com>
Tue, 20 Dec 2022 21:37:21 +0000 (21:37 +0000)
committerkub <derkub@gmail.com>
Tue, 20 Dec 2022 21:37:21 +0000 (21:37 +0000)
pico/32x/sh2soc.c

index 0336b87..852f394 100644 (file)
@@ -262,6 +262,7 @@ u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2)
   u8 *r = (void *)sh2->peri_regs;
   u32 d;
 
+  DRC_SAVE_SR(sh2);
   a &= 0x1ff;
   d = PREG8(r, a);
 
@@ -269,10 +270,9 @@ u32 REGPARM(2) sh2_peripheral_read8(u32 a, SH2 *sh2)
     a | ~0x1ff, d, sh2_pc(sh2));
   if ((a & 0x1c0) == 0x140) {
     // abused as comm area
-    DRC_SAVE_SR(sh2);
     p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
-    DRC_RESTORE_SR(sh2);
   }
+  DRC_RESTORE_SR(sh2);
   return d;
 }
 
@@ -281,6 +281,7 @@ u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2)
   u16 *r = (void *)sh2->peri_regs;
   u32 d;
 
+  DRC_SAVE_SR(sh2);
   a &= 0x1fe;
   d = r[MEM_BE2(a / 2)];
 
@@ -288,10 +289,9 @@ u32 REGPARM(2) sh2_peripheral_read16(u32 a, SH2 *sh2)
     a | ~0x1ff, d, sh2_pc(sh2));
   if ((a & 0x1c0) == 0x140) {
     // abused as comm area
-    DRC_SAVE_SR(sh2);
     p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
-    DRC_RESTORE_SR(sh2);
   }
+  DRC_RESTORE_SR(sh2);
   return d;
 }
 
@@ -299,6 +299,7 @@ u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2)
 {
   u32 d;
 
+  DRC_SAVE_SR(sh2);
   a &= 0x1fc;
   d = sh2->peri_regs[a / 4];
 
@@ -309,10 +310,9 @@ u32 REGPARM(2) sh2_peripheral_read32(u32 a, SH2 *sh2)
     sh2->poll_cnt = 0;
   else if ((a & 0x1c0) == 0x140) {
     // abused as comm area
-    DRC_SAVE_SR(sh2);
     p32x_sh2_poll_detect(a, sh2, SH2_STATE_CPOLL, 3);
-    DRC_RESTORE_SR(sh2);
   }
+  DRC_RESTORE_SR(sh2);
   return d;
 }
 
@@ -356,18 +356,18 @@ void REGPARM(3) sh2_peripheral_write8(u32 a, u32 d, SH2 *sh2)
   u8 *r = (void *)sh2->peri_regs;
   u8 old;
 
+  DRC_SAVE_SR(sh2);
   elprintf_sh2(sh2, EL_32XP, "peri w8  [%08x]       %02x @%06x",
     a, d, sh2_pc(sh2));
 
   a &= 0x1ff;
   old = PREG8(r, a);
+  PREG8(r, a) = d;
 
   switch (a) {
   case 0x002: // SCR - serial control
-    if (!(PREG8(r, a) & 0x20) && (d & 0x20)) { // TE being set
-      PREG8(r, a) = d;
+    if (!(old & 0x20) && (d & 0x20)) // TE being set
       sci_trigger(sh2, r);
-    }
     break;
   case 0x003: // TDR - transmit data
     break;
@@ -375,27 +375,31 @@ void REGPARM(3) sh2_peripheral_write8(u32 a, u32 d, SH2 *sh2)
     d = (old & (d | 0x06)) | (d & 1);
     PREG8(r, a) = d;
     sci_trigger(sh2, r);
-    return;
+    break;
   case 0x005: // RDR - receive data
     break;
   case 0x010: // TIER
     if (d & 0x8e)
       elprintf(EL_32XP|EL_ANOMALY, "TIER: %02x", d);
     d = (d & 0x8e) | 1;
+    PREG8(r, a) = d;
     break;
   case 0x017: // TOCR
     d |= 0xe0;
+    PREG8(r, a) = d;
     break;
+  default:
+    if ((a & 0x1c0) == 0x140)
+      p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
   }
-  PREG8(r, a) = d;
-
-  if ((a & 0x1c0) == 0x140)
-    p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
+  DRC_RESTORE_SR(sh2);
 }
 
 void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2)
 {
   u16 *r = (void *)sh2->peri_regs;
+
+  DRC_SAVE_SR(sh2);
   elprintf_sh2(sh2, EL_32XP, "peri w16 [%08x]     %04x @%06x",
     a, d, sh2_pc(sh2));
 
@@ -409,12 +413,12 @@ void REGPARM(3) sh2_peripheral_write16(u32 a, u32 d, SH2 *sh2)
     }
     if ((d & 0xff00) == 0x5a00) // WTCNT
       PREG8(r, 0x81) = d;
-    return;
+  } else {
+    r[MEM_BE2(a / 2)] = d;
+    if ((a & 0x1c0) == 0x140)
+      p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
   }
-
-  r[MEM_BE2(a / 2)] = d;
-  if ((a & 0x1c0) == 0x140)
-    p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
+  DRC_RESTORE_SR(sh2);
 }
 
 void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
@@ -423,6 +427,7 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
   u32 old;
   struct dmac *dmac;
 
+  DRC_SAVE_SR(sh2);
   elprintf_sh2(sh2, EL_32XP, "peri w32 [%08x] %08x @%06x",
     a, d, sh2_pc(sh2));
 
@@ -472,17 +477,17 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
       if (!(dmac->dmaor & DMA_DME))
         return;
 
-      DRC_SAVE_SR(sh2);
       if ((dmac->chan[0].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
         dmac_trigger(sh2, &dmac->chan[0]);
       if ((dmac->chan[1].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
         dmac_trigger(sh2, &dmac->chan[1]);
-      DRC_RESTORE_SR(sh2);
       break;
+    default:
+      if ((a & 0x1c0) == 0x140)
+        p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
   }
 
-  if ((a & 0x1c0) == 0x140)
-    p32x_sh2_poll_event(sh2, SH2_STATE_CPOLL, SekCyclesDone());
+  DRC_RESTORE_SR(sh2);
 }
 
 /* 32X specific */