core, save state fixes
authorkub <derkub@gmail.com>
Tue, 4 Mar 2025 00:16:48 +0000 (01:16 +0100)
committerkub <derkub@gmail.com>
Tue, 4 Mar 2025 00:16:48 +0000 (01:16 +0100)
pico/carthw/carthw.c
pico/memory.c
pico/pico.c
pico/pico_int.h
pico/sek.c
pico/state.c
pico/videoport.c
pico/z80if.c

index 629262a..c9cf30c 100644 (file)
@@ -75,7 +75,7 @@ static void carthw_ssf2_statef(void)
   int i, reg;
   for (i = 1; i < 8; i++) {
     reg = carthw_ssf2_banks[i];
-    carthw_ssf2_banks[i] = i;
+    carthw_ssf2_banks[i] = ~reg;
     carthw_ssf2_write8(0xa130f1 | (i << 1), reg);
   }
 }
index 0a65f16..cba8c52 100644 (file)
@@ -1440,6 +1440,8 @@ void ym2612_unpack_state(void)
   Pico.t.ym2612_busy = cycles_68k_to_z80(busy);\r
   tac = (1024 - ym2612.OPN.ST.TA) << 16;\r
   tbc = (256  - ym2612.OPN.ST.TB) << 16;\r
+  Pico.t.timer_a_step = TIMER_A_TICK_ZCYCLES * tac;\r
+  Pico.t.timer_a_step = TIMER_B_TICK_ZCYCLES * tbc;\r
   if (ym2612.OPN.ST.mode & 1)\r
     Pico.t.timer_a_next_oflow = (int)((double)(tac - tat) / (double)tac * Pico.t.timer_a_step);\r
   else\r
index 1d93d60..ee3d143 100644 (file)
@@ -238,6 +238,8 @@ void PicoLoopPrepare(void)
     Pico.t.vcnt_wrap = 0xEB;\r
     Pico.t.vcnt_adj = 6;\r
   }\r
+\r
+  Pico.t.m68c_line_start = Pico.t.m68c_aim; // for VDP slot calculation\r
   PicoVideoFIFOMode(Pico.video.reg[1]&0x40, Pico.video.reg[12]&1);\r
 \r
   Pico.m.dirtyPal = 1;\r
index 6a26343..2355c8e 100644 (file)
@@ -972,8 +972,8 @@ int PicoVideoFIFOWrite(int count, int byte_p, unsigned sr_mask, unsigned sr_flag
 void PicoVideoInit(void);\r
 void PicoVideoReset(void);\r
 void PicoVideoSync(int skip);\r
-void PicoVideoSave(void);\r
-void PicoVideoLoad(void);\r
+int PicoVideoSave(void *buf);\r
+void PicoVideoLoad(void *buf, int len);\r
 void PicoVideoCacheSAT(int load);\r
 \r
 // misc.c\r
index 348d857..c894a7c 100644 (file)
@@ -219,9 +219,10 @@ PICO_INTERNAL void SekPackCpu(unsigned char *cpu, int is_sub)
     *(u32 *)(cpu+0x50) = SekCycleCntS68k;\r
     *(s16 *)(cpu+0x4e) = SekCycleCntS68k - SekCycleAimS68k;\r
   } else {\r
-    *(u32 *)(cpu+0x50) = Pico.t.m68c_cnt + Pico.t.z80_buscycles +\r
-                          ((Pico.t.refresh_delay + (1<<14)/2) >> 14);\r
+    *(u32 *)(cpu+0x50) = Pico.t.m68c_cnt;\r
     *(s16 *)(cpu+0x4e) = Pico.t.m68c_cnt - Pico.t.m68c_aim;\r
+    *(u16 *)(cpu+0x54) = Pico.t.refresh_delay;\r
+    *(u16 *)(cpu+0x56) = Pico.t.z80_buscycles;\r
   }\r
 }\r
 \r
@@ -265,8 +266,8 @@ PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub)
   } else {\r
     Pico.t.m68c_cnt = *(u32 *)(cpu+0x50);\r
     Pico.t.m68c_aim = Pico.t.m68c_cnt - *(s16 *)(cpu+0x4e);\r
-    Pico.t.z80_buscycles = 0;\r
-    Pico.t.refresh_delay = 0;\r
+    Pico.t.refresh_delay = *(u16 *)(cpu+0x54);\r
+    Pico.t.z80_buscycles = *(u16 *)(cpu+0x56);\r
   }\r
 }\r
 \r
index e02bed2..61e5597 100644 (file)
@@ -137,6 +137,7 @@ typedef enum {
   CHUNK_PICO_PCM,\r
   CHUNK_PICO,\r
   CHUNK_CD_MSD,\r
+  CHUNK_VDP,\r
   //\r
   CHUNK_DEFAULT_COUNT,\r
   CHUNK_CARTHW_ = CHUNK_CARTHW,  // 64 (defined in PicoInt)\r
@@ -280,7 +281,8 @@ static int state_save(void *file)
   CHECKED_WRITE_BUFF(CHUNK_CRAM,  PicoMem.cram);\r
 \r
   CHECKED_WRITE_BUFF(CHUNK_MISC,  Pico.m);\r
-  PicoVideoSave();\r
+  len = PicoVideoSave(buf2);\r
+  CHECKED_WRITE(CHUNK_VDP, len, buf2);\r
   CHECKED_WRITE_BUFF(CHUNK_VIDEO, Pico.video);\r
 \r
   if (PicoIn.AHW & PAHW_MCD)\r
@@ -407,13 +409,14 @@ static int state_load(void *file)
   unsigned char buff_m68k[0x60], buff_s68k[0x60];\r
   unsigned char buff_z80[Z80_STATE_SIZE];\r
   unsigned char buff_sh2[SH2_STATE_SIZE];\r
+  unsigned char buff_vdp[0x200];\r
   unsigned char *buf = NULL;\r
   unsigned char chunk;\r
   void *ym_regs;\r
   int len_check;\r
   int retval = -1;\r
   char header[8];\r
-  int ver, len;\r
+  int ver, len, len_vdp = 0;\r
 \r
   memset(buff_m68k, 0, sizeof(buff_m68k));\r
   memset(buff_s68k, 0, sizeof(buff_s68k));\r
@@ -459,10 +462,8 @@ static int state_load(void *file)
       case CHUNK_CRAM:    CHECKED_READ_BUFF(PicoMem.cram); break;\r
       case CHUNK_VSRAM:   CHECKED_READ_BUFF(PicoMem.vsram); break;\r
       case CHUNK_MISC:    CHECKED_READ_BUFF(Pico.m); break;\r
-      case CHUNK_VIDEO:\r
-        CHECKED_READ_BUFF(Pico.video);\r
-        PicoVideoLoad();\r
-        break;\r
+      case CHUNK_VIDEO:   CHECKED_READ_BUFF(Pico.video); break;\r
+      case CHUNK_VDP:     CHECKED_READ2((len_vdp = len), buff_vdp); break;\r
 \r
       case CHUNK_IOPORTS: CHECKED_READ_BUFF(PicoMem.ioports); break;\r
       case CHUNK_PSG:     CHECKED_READ2(28*4, sn76496_regs); break;\r
@@ -587,6 +588,8 @@ breakswitch:
   }\r
 \r
 readend:\r
+  PicoVideoLoad(buff_vdp, len_vdp);\r
+\r
   if (PicoIn.AHW & PAHW_SMS)\r
     PicoStateLoadedMS();\r
 \r
index 3004e1c..4fe54d2 100644 (file)
@@ -189,7 +189,7 @@ int (*PicoDmaHook)(u32 source, int len, unsigned short **base, u32 *mask) = NULL
  */\r
 \r
 // NB code assumes fifo_* arrays have size 2^n\r
-static struct VdpFIFO { // XXX this must go into save file!\r
+static struct VdpFIFO {\r
   // last transferred FIFO data, ...x = index  XXX currently only CPU\r
   u16 fifo_data[4], fifo_dx;\r
 \r
@@ -1225,29 +1225,46 @@ void PicoVideoCacheSAT(int load)
   Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES;\r
 }\r
 \r
-void PicoVideoSave(void)\r
+#include <stddef.h>\r
+\r
+int PicoVideoSave(void *buf)\r
 {\r
   struct VdpFIFO *vf = &VdpFIFO;\r
   struct PicoVideo *pv = &Pico.video;\r
-  int l, x;\r
-\r
-  // account for all outstanding xfers XXX kludge, entry attr's not saved\r
-  pv->fifo_cnt = pv->fifo_bgcnt = 0;\r
-  for (l = vf->fifo_ql, x = vf->fifo_qx + l-1; l > 0; l--, x--) {\r
-    int cnt = (vf->fifo_queue[x&7] >> 3);\r
-    if (vf->fifo_queue[x&7] & FQ_BGDMA)\r
-      pv->fifo_bgcnt += cnt;\r
-    else\r
-      pv->fifo_cnt += cnt;\r
-  }\r
+  u8 *bp = buf;\r
+  int i;\r
+\r
+  // FIFO stuff\r
+  memcpy(bp, &VdpFIFO, offsetof(struct VdpFIFO, fifo_slot));\r
+  bp += offsetof(struct VdpFIFO, fifo_slot);\r
+\r
+  // SAT Cache\r
+  for (i = 0; i < 80; i++, bp += sizeof(u32))\r
+    memcpy(bp, VdpSATCache+2*i, sizeof(u32));\r
+\r
+  return bp - (u8 *)buf;\r
 }\r
 \r
-void PicoVideoLoad(void)\r
+void PicoVideoLoad(void *buf, int len)\r
 {\r
   struct VdpFIFO *vf = &VdpFIFO;\r
   struct PicoVideo *pv = &Pico.video;\r
   int b = pv->type == 1;\r
 \r
+  SATaddr = ((pv->reg[5]&0x7f) << 9) | ((pv->reg[6]&0x20) << 11);\r
+  SATmask = ~0x1ff;\r
+  if (pv->reg[12]&1)\r
+    SATaddr &= ~0x200, SATmask &= ~0x200; // H40, zero lowest SAT bit\r
+\r
+  if (len) {\r
+    int i;\r
+    if (len >= offsetof(struct VdpFIFO, fifo_slot))\r
+      memcpy(&VdpFIFO, buf, offsetof(struct VdpFIFO, fifo_slot));\r
+    for (i = 0; i < 80; i++)\r
+      memcpy(VdpSATCache+2*i, buf + offsetof(struct VdpFIFO, fifo_slot) + 4*i, sizeof(u32));\r
+    return;\r
+  }\r
+\r
   // convert former dma_xfers (why was this in PicoMisc anyway?)\r
   if (Pico.m.dma_xfers) {\r
     pv->fifo_cnt = Pico.m.dma_xfers << b;\r
index 474854d..b730bfa 100644 (file)
@@ -157,7 +157,8 @@ struct z80_state {
   u8 irq_pending;   // irq line level, 1 if active
   u8 irq_vector[3]; // up to 3 byte vector for irq mode0 handling
   u16 cyc;
-  u8 reserved[6];
+  u16 busdelay;
+  u8 reserved[4];
 };
 
 void z80_pack(void *data)
@@ -165,7 +166,8 @@ void z80_pack(void *data)
   struct z80_state *s = data;
   memset(data, 0, Z80_STATE_SIZE);
   memcpy(s->magic, "Z80a", 4);
-  s->cyc = Pico.t.z80c_cnt + ((Pico.t.z80_busdelay + (1<<8)/2) >> 8);
+  s->cyc = Pico.t.z80c_cnt;
+  s->busdelay = Pico.t.z80_busdelay;
 #if defined(_USE_DRZ80)
   #define DRR8(n)   (drZ80.Z80##n >> 24)
   #define DRR16(n)  (drZ80.Z80##n >> 16)
@@ -202,7 +204,7 @@ void z80_pack(void *data)
     s->a.b = CZ80.BC2.B.H; s->a.c = CZ80.BC2.B.L;
     s->a.d = CZ80.DE2.B.H; s->a.e = CZ80.DE2.B.L;
     s->a.h = CZ80.HL2.B.H; s->a.l = CZ80.HL2.B.L;
-    s->i  = zI;   s->r  = zR;
+    s->i  = zI;   s->r  = (zR & 0x7f) | zR2;
     s->ix = zIX;  s->iy = zIY;
     s->sp = Cz80_Get_Reg(&CZ80, CZ80_SP);
     s->pc = Cz80_Get_Reg(&CZ80, CZ80_PC);
@@ -224,7 +226,7 @@ int z80_unpack(const void *data)
     return 0;
   }
   Pico.t.z80c_cnt = s->cyc;
-  Pico.t.z80_busdelay = 0;
+  Pico.t.z80_busdelay = s->busdelay;
 
 #if defined(_USE_DRZ80)
   #define DRW8(n, v)       drZ80.Z80##n = (u32)(v) << 24
@@ -271,7 +273,7 @@ int z80_unpack(const void *data)
     CZ80.BC2.B.H = s->a.b; CZ80.BC2.B.L = s->a.c;
     CZ80.DE2.B.H = s->a.d; CZ80.DE2.B.L = s->a.e;
     CZ80.HL2.B.H = s->a.h; CZ80.HL2.B.L = s->a.l;
-    zI  = s->i;   zR  = s->r;
+    zI  = s->i;   zR  = s->r; zR2 = s->r & 0x80;
     zIX = s->ix;  zIY = s->iy;
     Cz80_Set_Reg(&CZ80, CZ80_SP, s->sp);
     Cz80_Set_Reg(&CZ80, CZ80_PC, s->pc);