CHUNK_BRAM,\r
CHUNK_GA_REGS,\r
CHUNK_PCM,\r
- CHUNK_CDC,\r
- CHUNK_CDD, // 20\r
- CHUNK_SCD,\r
- CHUNK_RC,\r
+ CHUNK_CDC, // old\r
+ CHUNK_CDD, // 20 old\r
+ CHUNK_SCD, // old\r
+ CHUNK_RC, // old\r
CHUNK_MISC_CD,\r
//\r
CHUNK_IOPORTS, // versions < 1.70 did not save that..\r
CHUNK_32X_EVT,\r
CHUNK_32X_FIRST = CHUNK_MSH2,\r
CHUNK_32X_LAST = CHUNK_32X_EVT,\r
+ // add new stuff here\r
+ CHUNK_CD_EVT = 50,\r
+ CHUNK_CD_GFX,\r
+ CHUNK_CD_CDC,\r
+ CHUNK_CD_CDD,\r
//\r
CHUNK_DEFAULT_COUNT,\r
- CHUNK_CARTHW_ = CHUNK_CARTHW, // defined in PicoInt\r
+ CHUNK_CARTHW_ = CHUNK_CARTHW, // 64 (defined in PicoInt)\r
} chunk_name_e;\r
\r
-static const char * const chunk_names[] = {\r
+static const char * const chunk_names[CHUNK_DEFAULT_COUNT] = {\r
"INVALID!",\r
"M68K state",\r
"RAM",\r
return (bwritten == len + 4 + 1);\r
}\r
\r
+#define CHUNK_LIMIT_W 18772 // sizeof(cdc)\r
+\r
#define CHECKED_WRITE(name,len,data) { \\r
- if (PicoStateProgressCB && name < CHUNK_DEFAULT_COUNT) { \\r
+ if (PicoStateProgressCB && name < CHUNK_DEFAULT_COUNT && chunk_names[name]) { \\r
strncpy(sbuff + 9, chunk_names[name], sizeof(sbuff) - 9); \\r
PicoStateProgressCB(sbuff); \\r
} \\r
- if (!write_chunk(name, len, data, file)) return 1; \\r
+ if (data == buf2 && len > CHUNK_LIMIT_W) \\r
+ goto out; \\r
+ if (!write_chunk(name, len, data, file)) \\r
+ goto out; \\r
}\r
\r
#define CHECKED_WRITE_BUFF(name,buff) { \\r
- if (PicoStateProgressCB && name < CHUNK_DEFAULT_COUNT) { \\r
+ if (PicoStateProgressCB && name < CHUNK_DEFAULT_COUNT && chunk_names[name]) { \\r
strncpy(sbuff + 9, chunk_names[name], sizeof(sbuff) - 9); \\r
PicoStateProgressCB(sbuff); \\r
} \\r
- if (!write_chunk(name, sizeof(buff), &buff, file)) return 1; \\r
+ if (!write_chunk(name, sizeof(buff), &buff, file)) \\r
+ goto out; \\r
}\r
\r
static int state_save(void *file)\r
char sbuff[32] = "Saving.. ";\r
unsigned char buff[0x60], buff_z80[Z80_STATE_SIZE];\r
void *ym2612_regs = YM2612GetRegs();\r
- int ver = 0x0170; // not really used..\r
+ void *buf2 = NULL;\r
+ int ver = 0x0191; // not really used..\r
+ int retval = -1;\r
+ int len;\r
\r
areaWrite("PicoSEXT", 1, 8, file);\r
areaWrite(&ver, 1, 4, file);\r
\r
if (PicoAHW & PAHW_MCD)\r
{\r
+ buf2 = malloc(CHUNK_LIMIT_W);\r
+ if (buf2 == NULL)\r
+ return -1;\r
+\r
memset(buff, 0, sizeof(buff));\r
SekPackCpu(buff, 1);\r
if (Pico_mcd->s68k_regs[3] & 4) // 1M mode?\r
CHECKED_WRITE_BUFF(CHUNK_BRAM, Pico_mcd->bram);\r
CHECKED_WRITE_BUFF(CHUNK_GA_REGS, Pico_mcd->s68k_regs); // GA regs, not CPU regs\r
CHECKED_WRITE_BUFF(CHUNK_PCM, Pico_mcd->pcm);\r
- CHECKED_WRITE_BUFF(CHUNK_CDD, Pico_mcd->cdd);\r
- CHECKED_WRITE_BUFF(CHUNK_CDC, Pico_mcd->cdc);\r
- CHECKED_WRITE_BUFF(CHUNK_SCD, Pico_mcd->scd);\r
- CHECKED_WRITE_BUFF(CHUNK_RC, Pico_mcd->rot_comp);\r
CHECKED_WRITE_BUFF(CHUNK_MISC_CD, Pico_mcd->m);\r
+ memset(buff, 0, 0x40);\r
+ memcpy(buff, pcd_event_times, sizeof(pcd_event_times));\r
+ CHECKED_WRITE(CHUNK_CD_EVT, 0x40, buff);\r
+\r
+ len = gfx_context_save(buf2);\r
+ CHECKED_WRITE(CHUNK_CD_GFX, len, buf2);\r
+ len = cdc_context_save(buf2);\r
+ CHECKED_WRITE(CHUNK_CD_CDC, len, buf2);\r
+ len = cdd_context_save(buf2);\r
+ CHECKED_WRITE(CHUNK_CD_CDD, len, buf2);\r
\r
if (Pico_mcd->s68k_regs[3] & 4) // convert back\r
wram_2M_to_1M(Pico_mcd->word_ram2M);\r
CHECKED_WRITE_BUFF(CHUNK_32XPAL, Pico32xMem->pal);\r
\r
memset(buff, 0, 0x40);\r
- memcpy(buff, event_times, sizeof(event_times));\r
+ memcpy(buff, p32x_event_times, sizeof(p32x_event_times));\r
CHECKED_WRITE(CHUNK_32X_EVT, 0x40, buff);\r
}\r
#endif\r
CHECKED_WRITE(chwc->chunk, chwc->size, chwc->ptr);\r
}\r
\r
- return 0;\r
+ retval = 0;\r
+\r
+out:\r
+ if (buf2 != NULL)\r
+ free(buf2);\r
+ return retval;\r
}\r
\r
static int g_read_offs = 0;\r
#define R_ERROR_RETURN(error) \\r
{ \\r
elprintf(EL_STATUS, "load_state @ %x: " error, g_read_offs); \\r
- return 1; \\r
+ goto out; \\r
}\r
\r
// when is eof really set?\r
if (areaRead(data, 1, len, file) != len) { \\r
if (len == 1 && areaEof(file)) goto readend; \\r
R_ERROR_RETURN("areaRead: premature EOF\n"); \\r
- return 1; \\r
} \\r
g_read_offs += len; \\r
}\r
\r
#define CHECKED_READ_BUFF(buff) CHECKED_READ2(sizeof(buff), &buff);\r
\r
+#define CHUNK_LIMIT_R 0x10960 // sizeof(old_cdc)\r
+\r
+#define CHECKED_READ_LIM(data) { \\r
+ if (len > CHUNK_LIMIT_R) \\r
+ R_ERROR_RETURN("chunk size over limit."); \\r
+ CHECKED_READ(len, data); \\r
+}\r
+\r
static int state_load(void *file)\r
{\r
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[0x40];\r
+ unsigned char *buf = NULL;\r
unsigned char chunk;\r
void *ym2612_regs;\r
+ int len_check;\r
+ int retval = -1;\r
char header[8];\r
int ver, len;\r
\r
memset(buff_s68k, 0, sizeof(buff_s68k));\r
memset(buff_z80, 0, sizeof(buff_z80));\r
\r
+ buf = malloc(CHUNK_LIMIT_R);\r
+ if (buf == NULL)\r
+ return -1;\r
+\r
g_read_offs = 0;\r
CHECKED_READ(8, header);\r
if (strncmp(header, "PicoSMCD", 8) && strncmp(header, "PicoSEXT", 8))\r
R_ERROR_RETURN("bad header");\r
CHECKED_READ(4, &ver);\r
\r
+ memset(pcd_event_times, 0, sizeof(pcd_event_times));\r
+ memset(p32x_event_times, 0, sizeof(p32x_event_times));\r
+\r
while (!areaEof(file))\r
{\r
+ len_check = 0;\r
CHECKED_READ(1, &chunk);\r
CHECKED_READ(4, &len);\r
if (len < 0 || len > 1024*512) R_ERROR_RETURN("bad length");\r
case CHUNK_BRAM: CHECKED_READ_BUFF(Pico_mcd->bram); break;\r
case CHUNK_GA_REGS: CHECKED_READ_BUFF(Pico_mcd->s68k_regs); break;\r
case CHUNK_PCM: CHECKED_READ_BUFF(Pico_mcd->pcm); break;\r
- case CHUNK_CDD: CHECKED_READ_BUFF(Pico_mcd->cdd); break;\r
- case CHUNK_CDC: CHECKED_READ_BUFF(Pico_mcd->cdc); break;\r
- case CHUNK_SCD: CHECKED_READ_BUFF(Pico_mcd->scd); break;\r
- case CHUNK_RC: CHECKED_READ_BUFF(Pico_mcd->rot_comp); break;\r
case CHUNK_MISC_CD: CHECKED_READ_BUFF(Pico_mcd->m); break;\r
\r
+ case CHUNK_CD_EVT:\r
+ CHECKED_READ2(0x40, buf);\r
+ memcpy(pcd_event_times, buf, sizeof(pcd_event_times));\r
+ break;\r
+\r
+ case CHUNK_CD_GFX:\r
+ CHECKED_READ_LIM(buf);\r
+ len_check = gfx_context_load(buf);\r
+ break;\r
+\r
+ case CHUNK_CD_CDC:\r
+ CHECKED_READ_LIM(buf);\r
+ len_check = cdc_context_load(buf);\r
+ break;\r
+\r
+ case CHUNK_CD_CDD:\r
+ CHECKED_READ_LIM(buf);\r
+ len_check = cdd_context_load(buf);\r
+ break;\r
+\r
+ // old, to be removed:\r
+ case CHUNK_CDC:\r
+ CHECKED_READ_LIM(buf);\r
+ cdc_context_load_old(buf);\r
+ break;\r
+\r
+ case CHUNK_SCD:\r
+ CHECKED_READ_LIM(buf);\r
+ cdd_context_load_old(buf);\r
+ break;\r
+\r
// 32x stuff\r
#ifndef NO_32X\r
case CHUNK_MSH2:\r
case CHUNK_32XPAL: CHECKED_READ_BUFF(Pico32xMem->pal); break;\r
\r
case CHUNK_32X_EVT:\r
- CHECKED_READ_BUFF(buff);\r
- memcpy(event_times, buff, sizeof(event_times));\r
+ CHECKED_READ2(0x40, buf);\r
+ memcpy(p32x_event_times, buf, sizeof(p32x_event_times));\r
break;\r
#endif\r
default:\r
areaSeek(file, len, SEEK_CUR);\r
break;\r
}\r
-breakswitch:;\r
+breakswitch:\r
+ if (len_check != 0 && len_check != len)\r
+ elprintf(EL_STATUS, "load_state: chunk %d has bad len %d/%d",\r
+ len, len_check);\r
}\r
\r
readend:\r
if (PicoAHW & PAHW_SMS)\r
PicoStateLoadedMS();\r
\r
- if (PicoAHW & PAHW_MCD)\r
- {\r
- PicoMemStateLoaded();\r
-\r
- if (!(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))\r
- cdda_start_play();\r
- }\r
-\r
if (PicoAHW & PAHW_32X)\r
Pico32xStateLoaded(1);\r
\r
z80_unpack(buff_z80);\r
\r
// due to dep from 68k cycles..\r
+ SekCycleAim = SekCycleCnt;\r
if (PicoAHW & PAHW_32X)\r
Pico32xStateLoaded(0);\r
+ if (PicoAHW & PAHW_MCD)\r
+ {\r
+ SekCycleAimS68k = SekCycleCntS68k;\r
+ pcd_state_loaded();\r
+ }\r
\r
- return 0;\r
+ retval = 0;\r
+\r
+out:\r
+ free(buf);\r
+ return retval;\r
}\r
\r
static int state_load_gfx(void *file)\r
}\r
}\r
\r
+out:\r
readend:\r
return 0;\r
}\r