From: kub Date: Tue, 4 Mar 2025 00:16:48 +0000 (+0100) Subject: core, save state fixes X-Git-Tag: v2.04~30 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4b5888a9efbb9f65e4ce0416b187fa2cbf7c4fa;p=picodrive.git core, save state fixes --- diff --git a/pico/carthw/carthw.c b/pico/carthw/carthw.c index 629262a1..c9cf30c1 100644 --- a/pico/carthw/carthw.c +++ b/pico/carthw/carthw.c @@ -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); } } diff --git a/pico/memory.c b/pico/memory.c index 0a65f16a..cba8c52a 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -1440,6 +1440,8 @@ void ym2612_unpack_state(void) Pico.t.ym2612_busy = cycles_68k_to_z80(busy); tac = (1024 - ym2612.OPN.ST.TA) << 16; tbc = (256 - ym2612.OPN.ST.TB) << 16; + Pico.t.timer_a_step = TIMER_A_TICK_ZCYCLES * tac; + Pico.t.timer_a_step = TIMER_B_TICK_ZCYCLES * tbc; if (ym2612.OPN.ST.mode & 1) Pico.t.timer_a_next_oflow = (int)((double)(tac - tat) / (double)tac * Pico.t.timer_a_step); else diff --git a/pico/pico.c b/pico/pico.c index 1d93d60d..ee3d1438 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -238,6 +238,8 @@ void PicoLoopPrepare(void) Pico.t.vcnt_wrap = 0xEB; Pico.t.vcnt_adj = 6; } + + Pico.t.m68c_line_start = Pico.t.m68c_aim; // for VDP slot calculation PicoVideoFIFOMode(Pico.video.reg[1]&0x40, Pico.video.reg[12]&1); Pico.m.dirtyPal = 1; diff --git a/pico/pico_int.h b/pico/pico_int.h index 6a26343e..2355c8ee 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -972,8 +972,8 @@ int PicoVideoFIFOWrite(int count, int byte_p, unsigned sr_mask, unsigned sr_flag void PicoVideoInit(void); void PicoVideoReset(void); void PicoVideoSync(int skip); -void PicoVideoSave(void); -void PicoVideoLoad(void); +int PicoVideoSave(void *buf); +void PicoVideoLoad(void *buf, int len); void PicoVideoCacheSAT(int load); // misc.c diff --git a/pico/sek.c b/pico/sek.c index 348d8577..c894a7ca 100644 --- a/pico/sek.c +++ b/pico/sek.c @@ -219,9 +219,10 @@ PICO_INTERNAL void SekPackCpu(unsigned char *cpu, int is_sub) *(u32 *)(cpu+0x50) = SekCycleCntS68k; *(s16 *)(cpu+0x4e) = SekCycleCntS68k - SekCycleAimS68k; } else { - *(u32 *)(cpu+0x50) = Pico.t.m68c_cnt + Pico.t.z80_buscycles + - ((Pico.t.refresh_delay + (1<<14)/2) >> 14); + *(u32 *)(cpu+0x50) = Pico.t.m68c_cnt; *(s16 *)(cpu+0x4e) = Pico.t.m68c_cnt - Pico.t.m68c_aim; + *(u16 *)(cpu+0x54) = Pico.t.refresh_delay; + *(u16 *)(cpu+0x56) = Pico.t.z80_buscycles; } } @@ -265,8 +266,8 @@ PICO_INTERNAL void SekUnpackCpu(const unsigned char *cpu, int is_sub) } else { Pico.t.m68c_cnt = *(u32 *)(cpu+0x50); Pico.t.m68c_aim = Pico.t.m68c_cnt - *(s16 *)(cpu+0x4e); - Pico.t.z80_buscycles = 0; - Pico.t.refresh_delay = 0; + Pico.t.refresh_delay = *(u16 *)(cpu+0x54); + Pico.t.z80_buscycles = *(u16 *)(cpu+0x56); } } diff --git a/pico/state.c b/pico/state.c index e02bed25..61e55975 100644 --- a/pico/state.c +++ b/pico/state.c @@ -137,6 +137,7 @@ typedef enum { CHUNK_PICO_PCM, CHUNK_PICO, CHUNK_CD_MSD, + CHUNK_VDP, // CHUNK_DEFAULT_COUNT, CHUNK_CARTHW_ = CHUNK_CARTHW, // 64 (defined in PicoInt) @@ -280,7 +281,8 @@ static int state_save(void *file) CHECKED_WRITE_BUFF(CHUNK_CRAM, PicoMem.cram); CHECKED_WRITE_BUFF(CHUNK_MISC, Pico.m); - PicoVideoSave(); + len = PicoVideoSave(buf2); + CHECKED_WRITE(CHUNK_VDP, len, buf2); CHECKED_WRITE_BUFF(CHUNK_VIDEO, Pico.video); if (PicoIn.AHW & PAHW_MCD) @@ -407,13 +409,14 @@ static int state_load(void *file) unsigned char buff_m68k[0x60], buff_s68k[0x60]; unsigned char buff_z80[Z80_STATE_SIZE]; unsigned char buff_sh2[SH2_STATE_SIZE]; + unsigned char buff_vdp[0x200]; unsigned char *buf = NULL; unsigned char chunk; void *ym_regs; int len_check; int retval = -1; char header[8]; - int ver, len; + int ver, len, len_vdp = 0; memset(buff_m68k, 0, sizeof(buff_m68k)); memset(buff_s68k, 0, sizeof(buff_s68k)); @@ -459,10 +462,8 @@ static int state_load(void *file) case CHUNK_CRAM: CHECKED_READ_BUFF(PicoMem.cram); break; case CHUNK_VSRAM: CHECKED_READ_BUFF(PicoMem.vsram); break; case CHUNK_MISC: CHECKED_READ_BUFF(Pico.m); break; - case CHUNK_VIDEO: - CHECKED_READ_BUFF(Pico.video); - PicoVideoLoad(); - break; + case CHUNK_VIDEO: CHECKED_READ_BUFF(Pico.video); break; + case CHUNK_VDP: CHECKED_READ2((len_vdp = len), buff_vdp); break; case CHUNK_IOPORTS: CHECKED_READ_BUFF(PicoMem.ioports); break; case CHUNK_PSG: CHECKED_READ2(28*4, sn76496_regs); break; @@ -587,6 +588,8 @@ breakswitch: } readend: + PicoVideoLoad(buff_vdp, len_vdp); + if (PicoIn.AHW & PAHW_SMS) PicoStateLoadedMS(); diff --git a/pico/videoport.c b/pico/videoport.c index 3004e1c6..4fe54d2a 100644 --- a/pico/videoport.c +++ b/pico/videoport.c @@ -189,7 +189,7 @@ int (*PicoDmaHook)(u32 source, int len, unsigned short **base, u32 *mask) = NULL */ // NB code assumes fifo_* arrays have size 2^n -static struct VdpFIFO { // XXX this must go into save file! +static struct VdpFIFO { // last transferred FIFO data, ...x = index XXX currently only CPU u16 fifo_data[4], fifo_dx; @@ -1225,29 +1225,46 @@ void PicoVideoCacheSAT(int load) Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES; } -void PicoVideoSave(void) +#include + +int PicoVideoSave(void *buf) { struct VdpFIFO *vf = &VdpFIFO; struct PicoVideo *pv = &Pico.video; - int l, x; - - // account for all outstanding xfers XXX kludge, entry attr's not saved - pv->fifo_cnt = pv->fifo_bgcnt = 0; - for (l = vf->fifo_ql, x = vf->fifo_qx + l-1; l > 0; l--, x--) { - int cnt = (vf->fifo_queue[x&7] >> 3); - if (vf->fifo_queue[x&7] & FQ_BGDMA) - pv->fifo_bgcnt += cnt; - else - pv->fifo_cnt += cnt; - } + u8 *bp = buf; + int i; + + // FIFO stuff + memcpy(bp, &VdpFIFO, offsetof(struct VdpFIFO, fifo_slot)); + bp += offsetof(struct VdpFIFO, fifo_slot); + + // SAT Cache + for (i = 0; i < 80; i++, bp += sizeof(u32)) + memcpy(bp, VdpSATCache+2*i, sizeof(u32)); + + return bp - (u8 *)buf; } -void PicoVideoLoad(void) +void PicoVideoLoad(void *buf, int len) { struct VdpFIFO *vf = &VdpFIFO; struct PicoVideo *pv = &Pico.video; int b = pv->type == 1; + SATaddr = ((pv->reg[5]&0x7f) << 9) | ((pv->reg[6]&0x20) << 11); + SATmask = ~0x1ff; + if (pv->reg[12]&1) + SATaddr &= ~0x200, SATmask &= ~0x200; // H40, zero lowest SAT bit + + if (len) { + int i; + if (len >= offsetof(struct VdpFIFO, fifo_slot)) + memcpy(&VdpFIFO, buf, offsetof(struct VdpFIFO, fifo_slot)); + for (i = 0; i < 80; i++) + memcpy(VdpSATCache+2*i, buf + offsetof(struct VdpFIFO, fifo_slot) + 4*i, sizeof(u32)); + return; + } + // convert former dma_xfers (why was this in PicoMisc anyway?) if (Pico.m.dma_xfers) { pv->fifo_cnt = Pico.m.dma_xfers << b; diff --git a/pico/z80if.c b/pico/z80if.c index 474854dc..b730bfa7 100644 --- a/pico/z80if.c +++ b/pico/z80if.c @@ -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);