core, fix 32x state changed by state load
authorkub <derkub@gmail.com>
Tue, 4 Mar 2025 19:02:27 +0000 (20:02 +0100)
committerkub <derkub@gmail.com>
Wed, 5 Mar 2025 22:20:23 +0000 (23:20 +0100)
cpu/sh2/compiler.c
pico/32x/32x.c
pico/pico_int.h
pico/state.c

index a5d5c87..e925638 100644 (file)
@@ -5678,7 +5678,7 @@ static void sh2_smc_rm_blocks(u32 a, int len, int tcache_id, int free)
 
   if (!removed) {
     if (len <= 4)
-      dbg(2, "rm_blocks called @%08x, no work?", _a);
+      dbg(2, "rm_blocks called @%08x, no work?", a);
     return;
   }
 
@@ -5902,6 +5902,9 @@ static void bcache_stats(void)
 
 void sh2_drc_flush_all(void)
 {
+  if (block_tables[0] == NULL)
+    return;
+
   backtrace();
   state_dump();
   block_stats();
index 8db3a6d..f7d58be 100644 (file)
@@ -120,13 +120,16 @@ void Pico32xStartup(void)
     sh2_init(&ssh2, 1, &msh2);
     ssh2.irq_callback = sh2_irq_cb;
   }
+
   PicoMemSetup32x();
   p32x_pwm_ctl_changed();
   p32x_timers_recalc();
 
+  Pico32x.regs[0] |= P32XS_ADEN;
+
   Pico32x.sh2_regs[0] = P32XS2_ADEN;
   if (Pico.m.ncart_in)
-    Pico32x.sh2_regs[0] |= P32XS_nCART;
+    Pico32x.sh2_regs[0] |= P32XS2_nCART;
 
   if (!Pico.m.pal)
     Pico32x.vdp_regs[0] |= P32XV_nPAL;
@@ -141,7 +144,9 @@ void Pico32xStartup(void)
 
 void Pico32xShutdown(void)
 {
+  elprintf(EL_STATUS|EL_32X, "32X shutdown");
   Pico32x.sh2_regs[0] &= ~P32XS2_ADEN;
+  Pico32x.regs[0] &= ~P32XS_ADEN;
 
   rendstatus_old = -1;
 
@@ -692,6 +697,11 @@ void Pico32xStateLoaded(int is_early)
   p32x_timers_recalc();
   p32x_pwm_state_loaded();
   p32x_run_events(SekCyclesDone());
+
+  // TODO wakeup CPUs for now. poll detection stuff must go to the save state!
+  p32x_m68k_poll_event(0, -1);
+  p32x_sh2_poll_event(msh2.poll_addr, &msh2, SH2_IDLE_STATES, msh2.m68krcycles_done);
+  p32x_sh2_poll_event(ssh2.poll_addr, &ssh2, SH2_IDLE_STATES, ssh2.m68krcycles_done);
 }
 
 void Pico32xPrepare(void)
index 2355c8e..02aa468 100644 (file)
@@ -585,11 +585,14 @@ typedef struct
 \r
 // 32X\r
 #define P32XS_FM    (1<<15)\r
-#define P32XS_nCART (1<< 8)\r
 #define P32XS_REN   (1<< 7)\r
 #define P32XS_nRES  (1<< 1)\r
 #define P32XS_ADEN  (1<< 0)\r
+\r
+#define P32XS2_FM   (1<<15)\r
+#define P32XS2_nCART (1<< 8)\r
 #define P32XS2_ADEN (1<< 9)\r
+\r
 #define P32XS_FULL  (1<< 7) // DREQ FIFO full\r
 #define P32XS_68S   (1<< 2)\r
 #define P32XS_DMA   (1<< 1)\r
index 8dc4881..9625621 100644 (file)
@@ -416,7 +416,8 @@ static int state_load(void *file)
   int len_check;\r
   int retval = -1;\r
   char header[8];\r
-  int ver, len, len_vdp = 0;\r
+  int ver, has_32x = 0;\r
+  int len, len_vdp = 0;\r
 \r
   memset(buff_m68k, 0, sizeof(buff_m68k));\r
   memset(buff_s68k, 0, sizeof(buff_s68k));\r
@@ -443,7 +444,10 @@ static int state_load(void *file)
     if (len < 0 || len > 1024*512) R_ERROR_RETURN("bad length");\r
     if (CHUNK_S68K <= chunk && chunk <= CHUNK_MISC_CD && !(PicoIn.AHW & PAHW_MCD))\r
       R_ERROR_RETURN("cd chunk in non CD state?");\r
-    if (CHUNK_32X_FIRST <= chunk && chunk <= CHUNK_32X_LAST && !(PicoIn.AHW & PAHW_32X))\r
+\r
+    // 32X only appears in PicoDrive after it has been enabled, so track this\r
+    has_32x |= CHUNK_32X_FIRST <= chunk && chunk <= CHUNK_32X_LAST;\r
+    if (has_32x && !(PicoIn.AHW & PAHW_32X))\r
       Pico32xStartup();\r
 \r
     switch (chunk)\r
@@ -590,6 +594,10 @@ breakswitch:
 readend:\r
   PicoVideoLoad(buff_vdp, len_vdp);\r
 \r
+  if (PicoIn.AHW & PAHW_32X)\r
+    if (!has_32x)\r
+      Pico32xShutdown(); // in case of loading a state with 32X disabled\r
+\r
   if (PicoIn.AHW & PAHW_SMS)\r
     PicoStateLoadedMS();\r
 \r