ALL: Huge upstream synch + PerRom DelaySI & CountPerOp parameters
[mupen64plus-pandora.git] / source / mupen64plus-core / src / main / savestates.c
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - savestates.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2012 CasualJames *
5 * Copyright (C) 2009 Olejl Tillin9 *
6 * Copyright (C) 2008 Richard42 Tillin9 *
7 * Copyright (C) 2002 Hacktarux *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
23 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25#include <stdlib.h>
26#include <string.h>
27#include <SDL_thread.h>
28
29#define M64P_CORE_PROTOTYPES 1
30#include "api/m64p_types.h"
31#include "api/callbacks.h"
32#include "api/m64p_config.h"
33#include "api/config.h"
34
35#include "savestates.h"
36#include "main.h"
37#include "rom.h"
38#include "util.h"
39#include "workqueue.h"
40
41#include "memory/memory.h"
42#include "memory/flashram.h"
43#include "memory/tlb.h"
44#include "r4300/macros.h"
45#include "r4300/r4300.h"
46#include "r4300/interupt.h"
47#include "osal/preproc.h"
48#include "osd/osd.h"
49#include "r4300/new_dynarec/new_dynarec.h"
50
51#ifdef LIBMINIZIP
52 #include <unzip.h>
53 #include <zip.h>
54#else
55 #include "main/zip/unzip.h"
56 #include "main/zip/zip.h"
57#endif
58
59static const char* savestate_magic = "M64+SAVE";
60static const int savestate_latest_version = 0x00010000; /* 1.0 */
61static const unsigned char pj64_magic[4] = { 0xC8, 0xA6, 0xD8, 0x23 };
62
63static savestates_job job = savestates_job_nothing;
64static savestates_type type = savestates_type_unknown;
65static char *fname = NULL;
66
67static unsigned int slot = 0;
68static int autoinc_save_slot = 0;
69
70static SDL_mutex *savestates_lock;
71
72struct savestate_work {
73 char *filepath;
74 char *data;
75 size_t size;
76 struct work_struct work;
77};
78
79/* Returns the malloc'd full path of the currently selected savestate. */
80static char *savestates_generate_path(savestates_type type)
81{
82 if(fname != NULL) /* A specific path was given. */
83 {
84 return strdup(fname);
85 }
86 else /* Use the selected savestate slot */
87 {
88 char *filename;
89 switch (type)
90 {
91 case savestates_type_m64p:
92 filename = formatstr("%s.st%d", ROM_SETTINGS.goodname, slot);
93 break;
94 case savestates_type_pj64_zip:
95 filename = formatstr("%s.pj%d.zip", ROM_PARAMS.headername, slot);
96 break;
97 case savestates_type_pj64_unc:
98 filename = formatstr("%s.pj%d", ROM_PARAMS.headername, slot);
99 break;
100 default:
101 filename = NULL;
102 break;
103 }
104
105 if (filename != NULL)
106 {
107 char *filepath = formatstr("%s%s", get_savestatepath(), filename);
108 free(filename);
109 return filepath;
110 }
111 else
112 return NULL;
113 }
114}
115
116void savestates_select_slot(unsigned int s)
117{
118 if(s>9||s==slot)
119 return;
120 slot = s;
121 ConfigSetParameter(g_CoreConfig, "CurrentSaveSlot", M64TYPE_INT, &s);
122 StateChanged(M64CORE_SAVESTATE_SLOT, slot);
123
124 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Selected state slot: %d", slot);
125}
126
127/* Returns the currently selected save slot. */
128unsigned int savestates_get_slot(void)
129{
130 return slot;
131}
132
133/* Sets save state slot autoincrement on or off. */
134void savestates_set_autoinc_slot(int b)
135{
136 autoinc_save_slot = b;
137}
138
139void savestates_inc_slot(void)
140{
141 if(++slot>9)
142 slot = 0;
143 StateChanged(M64CORE_SAVESTATE_SLOT, slot);
144}
145
146savestates_job savestates_get_job(void)
147{
148 return job;
149}
150
151void savestates_set_job(savestates_job j, savestates_type t, const char *fn)
152{
153 if (fname != NULL)
154 {
155 free(fname);
156 fname = NULL;
157 }
158
159 job = j;
160 type = t;
161 if (fn != NULL)
162 fname = strdup(fn);
163}
164
165static void savestates_clear_job(void)
166{
167 savestates_set_job(savestates_job_nothing, savestates_type_unknown, NULL);
168}
169
170#define GETARRAY(buff, type, count) \
171 (to_little_endian_buffer(buff, sizeof(type),count), \
172 buff += count*sizeof(type), \
173 (type *)(buff-count*sizeof(type)))
174#define COPYARRAY(dst, buff, type, count) \
175 memcpy(dst, GETARRAY(buff, type, count), sizeof(type)*count)
176#define GETDATA(buff, type) *GETARRAY(buff, type, 1)
177
178#define PUTARRAY(src, buff, type, count) \
179 memcpy(buff, src, sizeof(type)*count); \
180 to_little_endian_buffer(buff, sizeof(type), count); \
181 buff += count*sizeof(type);
182
183#define PUTDATA(buff, type, value) \
184 do { type x = value; PUTARRAY(&x, buff, type, 1); } while(0)
185
186static int savestates_load_m64p(char *filepath)
187{
188 unsigned char header[44];
189 gzFile f;
190 int version;
191 int i;
192
193 size_t savestateSize;
194 unsigned char *savestateData, *curr;
195 char queue[1024];
196
197 SDL_LockMutex(savestates_lock);
198
199 f = gzopen(filepath, "rb");
200 if(f==NULL)
201 {
202 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not open state file: %s", filepath);
203 SDL_UnlockMutex(savestates_lock);
204 return 0;
205 }
206
207 /* Read and check Mupen64Plus magic number. */
208 if (gzread(f, header, 44) != 44)
209 {
210 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read header from state file %s", filepath);
211 gzclose(f);
212 SDL_UnlockMutex(savestates_lock);
213 return 0;
214 }
215 curr = header;
216
217 if(strncmp((char *)curr, savestate_magic, 8)!=0)
218 {
219 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State file: %s is not a valid Mupen64plus savestate.", filepath);
220 gzclose(f);
221 SDL_UnlockMutex(savestates_lock);
222 return 0;
223 }
224 curr += 8;
225
226 version = *curr++;
227 version = (version << 8) | *curr++;
228 version = (version << 8) | *curr++;
229 version = (version << 8) | *curr++;
230 if(version != 0x00010000)
231 {
232 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State version (%08x) isn't compatible. Please update Mupen64Plus.", version);
233 gzclose(f);
234 SDL_UnlockMutex(savestates_lock);
235 return 0;
236 }
237
238 if(memcmp((char *)curr, ROM_SETTINGS.MD5, 32))
239 {
240 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State ROM MD5 does not match current ROM.");
241 gzclose(f);
242 SDL_UnlockMutex(savestates_lock);
243 return 0;
244 }
245 curr += 32;
246
247 /* Read the rest of the savestate */
248 savestateSize = 16788244;
249 savestateData = curr = (unsigned char *)malloc(savestateSize);
250 if (savestateData == NULL)
251 {
252 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Insufficient memory to load state.");
253 gzclose(f);
254 SDL_UnlockMutex(savestates_lock);
255 return 0;
256 }
257 if (gzread(f, savestateData, savestateSize) != savestateSize ||
258 (gzread(f, queue, sizeof(queue)) % 4) != 0)
259 {
260 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read Mupen64Plus savestate data from %s", filepath);
261 free(savestateData);
262 gzclose(f);
263 SDL_UnlockMutex(savestates_lock);
264 return 0;
265 }
266
267 gzclose(f);
268 SDL_UnlockMutex(savestates_lock);
269
270 // Parse savestate
271 rdram_register.rdram_config = GETDATA(curr, unsigned int);
272 rdram_register.rdram_device_id = GETDATA(curr, unsigned int);
273 rdram_register.rdram_delay = GETDATA(curr, unsigned int);
274 rdram_register.rdram_mode = GETDATA(curr, unsigned int);
275 rdram_register.rdram_ref_interval = GETDATA(curr, unsigned int);
276 rdram_register.rdram_ref_row = GETDATA(curr, unsigned int);
277 rdram_register.rdram_ras_interval = GETDATA(curr, unsigned int);
278 rdram_register.rdram_min_interval = GETDATA(curr, unsigned int);
279 rdram_register.rdram_addr_select = GETDATA(curr, unsigned int);
280 rdram_register.rdram_device_manuf = GETDATA(curr, unsigned int);
281
282 MI_register.w_mi_init_mode_reg = GETDATA(curr, unsigned int);
283 MI_register.mi_init_mode_reg = GETDATA(curr, unsigned int);
284 curr += 4; // Duplicate MI init mode flags from old implementation
285 MI_register.mi_version_reg = GETDATA(curr, unsigned int);
286 MI_register.mi_intr_reg = GETDATA(curr, unsigned int);
287 MI_register.mi_intr_mask_reg = GETDATA(curr, unsigned int);
288 MI_register.w_mi_intr_mask_reg = GETDATA(curr, unsigned int);
289 curr += 8; // Duplicated MI intr flags and padding from old implementation
290
291 pi_register.pi_dram_addr_reg = GETDATA(curr, unsigned int);
292 pi_register.pi_cart_addr_reg = GETDATA(curr, unsigned int);
293 pi_register.pi_rd_len_reg = GETDATA(curr, unsigned int);
294 pi_register.pi_wr_len_reg = GETDATA(curr, unsigned int);
295 pi_register.read_pi_status_reg = GETDATA(curr, unsigned int);
296 pi_register.pi_bsd_dom1_lat_reg = GETDATA(curr, unsigned int);
297 pi_register.pi_bsd_dom1_pwd_reg = GETDATA(curr, unsigned int);
298 pi_register.pi_bsd_dom1_pgs_reg = GETDATA(curr, unsigned int);
299 pi_register.pi_bsd_dom1_rls_reg = GETDATA(curr, unsigned int);
300 pi_register.pi_bsd_dom2_lat_reg = GETDATA(curr, unsigned int);
301 pi_register.pi_bsd_dom2_pwd_reg = GETDATA(curr, unsigned int);
302 pi_register.pi_bsd_dom2_pgs_reg = GETDATA(curr, unsigned int);
303 pi_register.pi_bsd_dom2_rls_reg = GETDATA(curr, unsigned int);
304
305 sp_register.sp_mem_addr_reg = GETDATA(curr, unsigned int);
306 sp_register.sp_dram_addr_reg = GETDATA(curr, unsigned int);
307 sp_register.sp_rd_len_reg = GETDATA(curr, unsigned int);
308 sp_register.sp_wr_len_reg = GETDATA(curr, unsigned int);
309 sp_register.w_sp_status_reg = GETDATA(curr, unsigned int);
310 sp_register.sp_status_reg = GETDATA(curr, unsigned int);
311 curr += 16; // Duplicated SP flags and padding from old implementation
312 sp_register.sp_dma_full_reg = GETDATA(curr, unsigned int);
313 sp_register.sp_dma_busy_reg = GETDATA(curr, unsigned int);
314 sp_register.sp_semaphore_reg = GETDATA(curr, unsigned int);
315
316 rsp_register.rsp_pc = GETDATA(curr, unsigned int);
317 rsp_register.rsp_ibist = GETDATA(curr, unsigned int);
318
319 si_register.si_dram_addr = GETDATA(curr, unsigned int);
320 si_register.si_pif_addr_rd64b = GETDATA(curr, unsigned int);
321 si_register.si_pif_addr_wr64b = GETDATA(curr, unsigned int);
322 si_register.si_stat = GETDATA(curr, unsigned int);
323
324 vi_register.vi_status = GETDATA(curr, unsigned int);
325 vi_register.vi_origin = GETDATA(curr, unsigned int);
326 vi_register.vi_width = GETDATA(curr, unsigned int);
327 vi_register.vi_v_intr = GETDATA(curr, unsigned int);
328 vi_register.vi_current = GETDATA(curr, unsigned int);
329 vi_register.vi_burst = GETDATA(curr, unsigned int);
330 vi_register.vi_v_sync = GETDATA(curr, unsigned int);
331 vi_register.vi_h_sync = GETDATA(curr, unsigned int);
332 vi_register.vi_leap = GETDATA(curr, unsigned int);
333 vi_register.vi_h_start = GETDATA(curr, unsigned int);
334 vi_register.vi_v_start = GETDATA(curr, unsigned int);
335 vi_register.vi_v_burst = GETDATA(curr, unsigned int);
336 vi_register.vi_x_scale = GETDATA(curr, unsigned int);
337 vi_register.vi_y_scale = GETDATA(curr, unsigned int);
338 vi_register.vi_delay = GETDATA(curr, unsigned int);
339 update_vi_status(vi_register.vi_status);
340 update_vi_width(vi_register.vi_width);
341
342 ri_register.ri_mode = GETDATA(curr, unsigned int);
343 ri_register.ri_config = GETDATA(curr, unsigned int);
344 ri_register.ri_current_load = GETDATA(curr, unsigned int);
345 ri_register.ri_select = GETDATA(curr, unsigned int);
346 ri_register.ri_refresh = GETDATA(curr, unsigned int);
347 ri_register.ri_latency = GETDATA(curr, unsigned int);
348 ri_register.ri_error = GETDATA(curr, unsigned int);
349 ri_register.ri_werror = GETDATA(curr, unsigned int);
350
351 ai_register.ai_dram_addr = GETDATA(curr, unsigned int);
352 ai_register.ai_len = GETDATA(curr, unsigned int);
353 ai_register.ai_control = GETDATA(curr, unsigned int);
354 ai_register.ai_status = GETDATA(curr, unsigned int);
355 ai_register.ai_dacrate = GETDATA(curr, unsigned int);
356 ai_register.ai_bitrate = GETDATA(curr, unsigned int);
357 ai_register.next_delay = GETDATA(curr, unsigned int);
358 ai_register.next_len = GETDATA(curr, unsigned int);
359 ai_register.current_delay = GETDATA(curr, unsigned int);
360 ai_register.current_len = GETDATA(curr, unsigned int);
361 update_ai_dacrate(ai_register.ai_dacrate);
362
363 dpc_register.dpc_start = GETDATA(curr, unsigned int);
364 dpc_register.dpc_end = GETDATA(curr, unsigned int);
365 dpc_register.dpc_current = GETDATA(curr, unsigned int);
366 dpc_register.w_dpc_status = GETDATA(curr, unsigned int);
367 dpc_register.dpc_status = GETDATA(curr, unsigned int);
368 curr += 12; // Duplicated DPC flags and padding from old implementation
369 dpc_register.dpc_clock = GETDATA(curr, unsigned int);
370 dpc_register.dpc_bufbusy = GETDATA(curr, unsigned int);
371 dpc_register.dpc_pipebusy = GETDATA(curr, unsigned int);
372 dpc_register.dpc_tmem = GETDATA(curr, unsigned int);
373
374 dps_register.dps_tbist = GETDATA(curr, unsigned int);
375 dps_register.dps_test_mode = GETDATA(curr, unsigned int);
376 dps_register.dps_buftest_addr = GETDATA(curr, unsigned int);
377 dps_register.dps_buftest_data = GETDATA(curr, unsigned int);
378
379 COPYARRAY(rdram, curr, unsigned int, 0x800000/4);
380 COPYARRAY(SP_DMEM, curr, unsigned int, 0x1000/4);
381 COPYARRAY(SP_IMEM, curr, unsigned int, 0x1000/4);
382 COPYARRAY(PIF_RAM, curr, unsigned char, 0x40);
383
384 flashram_info.use_flashram = GETDATA(curr, int);
385 flashram_info.mode = GETDATA(curr, int);
386 flashram_info.status = GETDATA(curr, unsigned long long);
387 flashram_info.erase_offset = GETDATA(curr, unsigned int);
388 flashram_info.write_pointer = GETDATA(curr, unsigned int);
389
390 COPYARRAY(tlb_LUT_r, curr, unsigned int, 0x100000);
391 COPYARRAY(tlb_LUT_w, curr, unsigned int, 0x100000);
392
393 llbit = GETDATA(curr, unsigned int);
394 COPYARRAY(reg, curr, long long int, 32);
395 COPYARRAY(reg_cop0, curr, unsigned int, 32);
396 set_fpr_pointers(Status); // Status is reg_cop0[12]
397 lo = GETDATA(curr, long long int);
398 hi = GETDATA(curr, long long int);
399 COPYARRAY(reg_cop1_fgr_64, curr, long long int, 32);
400 if ((Status & 0x04000000) == 0) // 32-bit FPR mode requires data shuffling because 64-bit layout is always stored in savestate file
401 shuffle_fpr_data(0x04000000, 0);
402 FCR0 = GETDATA(curr, int);
403 FCR31 = GETDATA(curr, int);
404
405 for (i = 0; i < 32; i++)
406 {
407 tlb_e[i].mask = GETDATA(curr, short);
408 curr += 2;
409 tlb_e[i].vpn2 = GETDATA(curr, int);
410 tlb_e[i].g = GETDATA(curr, char);
411 tlb_e[i].asid = GETDATA(curr, unsigned char);
412 curr += 2;
413 tlb_e[i].pfn_even = GETDATA(curr, int);
414 tlb_e[i].c_even = GETDATA(curr, char);
415 tlb_e[i].d_even = GETDATA(curr, char);
416 tlb_e[i].v_even = GETDATA(curr, char);
417 curr++;
418 tlb_e[i].pfn_odd = GETDATA(curr, int);
419 tlb_e[i].c_odd = GETDATA(curr, char);
420 tlb_e[i].d_odd = GETDATA(curr, char);
421 tlb_e[i].v_odd = GETDATA(curr, char);
422 tlb_e[i].r = GETDATA(curr, char);
423
424 tlb_e[i].start_even = GETDATA(curr, unsigned int);
425 tlb_e[i].end_even = GETDATA(curr, unsigned int);
426 tlb_e[i].phys_even = GETDATA(curr, unsigned int);
427 tlb_e[i].start_odd = GETDATA(curr, unsigned int);
428 tlb_e[i].end_odd = GETDATA(curr, unsigned int);
429 tlb_e[i].phys_odd = GETDATA(curr, unsigned int);
430 }
431
432#ifdef NEW_DYNAREC
433 if (r4300emu == CORE_DYNAREC) {
434 pcaddr = GETDATA(curr, unsigned int);
435 pending_exception = 1;
436 invalidate_all_pages();
437 } else {
438 if(r4300emu != CORE_PURE_INTERPRETER)
439 {
440 for (i = 0; i < 0x100000; i++)
441 invalid_code[i] = 1;
442 }
443 generic_jump_to(GETDATA(curr, unsigned int)); // PC
444 }
445#else
446 if(r4300emu != CORE_PURE_INTERPRETER)
447 {
448 for (i = 0; i < 0x100000; i++)
449 invalid_code[i] = 1;
450 }
451 generic_jump_to(GETDATA(curr, unsigned int)); // PC
452#endif
453
454 next_interupt = GETDATA(curr, unsigned int);
455 next_vi = GETDATA(curr, unsigned int);
456 vi_field = GETDATA(curr, unsigned int);
457
458 // assert(savestateData+savestateSize == curr)
459
460 to_little_endian_buffer(queue, 4, 256);
461 load_eventqueue_infos(queue);
462
463#ifdef NEW_DYNAREC
464 if (r4300emu == CORE_DYNAREC)
465 last_addr = pcaddr;
466 else
467 last_addr = PC->addr;
468#else
469 last_addr = PC->addr;
470#endif
471
472 free(savestateData);
473 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State loaded from: %s", namefrompath(filepath));
474 return 1;
475}
476
477static int savestates_load_pj64(char *filepath, void *handle,
478 int (*read_func)(void *, void *, size_t))
479{
480 char buffer[1024];
481 unsigned int vi_timer, SaveRDRAMSize;
482 int i;
483
484 unsigned char header[8];
485 unsigned char RomHeader[0x40];
486
487 size_t savestateSize;
488 unsigned char *savestateData, *curr;
489
490 /* Read and check Project64 magic number. */
491 if (!read_func(handle, header, 8))
492 {
493 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read header from Project64 savestate %s", filepath);
494 return 0;
495 }
496
497 curr = header;
498 if (memcmp(curr, pj64_magic, 4) != 0)
499 {
500 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State file: %s is not a valid Project64 savestate. Unrecognized file format.", filepath);
501 return 0;
502 }
503 curr += 4;
504
505 SaveRDRAMSize = GETDATA(curr, unsigned int);
506
507 /* Read the rest of the savestate into memory. */
508 savestateSize = SaveRDRAMSize + 0x2754;
509 savestateData = curr = (unsigned char *)malloc(savestateSize);
510 if (savestateData == NULL)
511 {
512 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Insufficient memory to load state.");
513 return 0;
514 }
515 if (!read_func(handle, savestateData, savestateSize))
516 {
517 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read savestate data from Project64 savestate %s", filepath);
518 free(savestateData);
519 return 0;
520 }
521
522 // check ROM header
523 COPYARRAY(RomHeader, curr, unsigned int, 0x40/4);
524 if(memcmp(RomHeader, rom, 0x40) != 0)
525 {
526 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State ROM header does not match current ROM.");
527 free(savestateData);
528 return 0;
529 }
530
531 // vi_timer
532 vi_timer = GETDATA(curr, unsigned int);
533
534 // Program Counter
535 last_addr = GETDATA(curr, unsigned int);
536
537 // GPR
538 COPYARRAY(reg, curr, long long int, 32);
539
540 // FPR
541 COPYARRAY(reg_cop1_fgr_64, curr, long long int, 32);
542
543 // CP0
544 COPYARRAY(reg_cop0, curr, unsigned int, 32);
545
546 set_fpr_pointers(Status); // Status is reg_cop0[12]
547 if ((Status & 0x04000000) == 0) // TODO not sure how pj64 handles this
548 shuffle_fpr_data(0x04000000, 0);
549
550 // Initialze the interupts
551 vi_timer += reg_cop0[9]; // Add current Count
552 next_interupt = (Compare < vi_timer) ? Compare : vi_timer;
553 next_vi = vi_timer;
554 vi_field = 0;
555 *((unsigned int*)&buffer[0]) = VI_INT;
556 *((unsigned int*)&buffer[4]) = vi_timer;
557 *((unsigned int*)&buffer[8]) = COMPARE_INT;
558 *((unsigned int*)&buffer[12]) = Compare;
559 *((unsigned int*)&buffer[16]) = 0xFFFFFFFF;
560
561 load_eventqueue_infos(buffer);
562
563 // FPCR
564 FCR0 = GETDATA(curr, int);
565 curr += 30 * 4; // FCR1...FCR30 not supported
566 FCR31 = GETDATA(curr, int);
567
568 // hi / lo
569 hi = GETDATA(curr, long long int);
570 lo = GETDATA(curr, long long int);
571
572 // rdram register
573 rdram_register.rdram_config = GETDATA(curr, unsigned int);
574 rdram_register.rdram_device_id = GETDATA(curr, unsigned int);
575 rdram_register.rdram_delay = GETDATA(curr, unsigned int);
576 rdram_register.rdram_mode = GETDATA(curr, unsigned int);
577 rdram_register.rdram_ref_interval = GETDATA(curr, unsigned int);
578 rdram_register.rdram_ref_row = GETDATA(curr, unsigned int);
579 rdram_register.rdram_ras_interval = GETDATA(curr, unsigned int);
580 rdram_register.rdram_min_interval = GETDATA(curr, unsigned int);
581 rdram_register.rdram_addr_select = GETDATA(curr, unsigned int);
582 rdram_register.rdram_device_manuf = GETDATA(curr, unsigned int);
583
584 // sp_register
585 sp_register.sp_mem_addr_reg = GETDATA(curr, unsigned int);
586 sp_register.sp_dram_addr_reg = GETDATA(curr, unsigned int);
587 sp_register.sp_rd_len_reg = GETDATA(curr, unsigned int);
588 sp_register.sp_wr_len_reg = GETDATA(curr, unsigned int);
589 sp_register.sp_status_reg = GETDATA(curr, unsigned int);
590 sp_register.sp_dma_full_reg = GETDATA(curr, unsigned int);
591 sp_register.sp_dma_busy_reg = GETDATA(curr, unsigned int);
592 sp_register.sp_semaphore_reg = GETDATA(curr, unsigned int);
593 rsp_register.rsp_pc = GETDATA(curr, unsigned int);
594 rsp_register.rsp_ibist = GETDATA(curr, unsigned int);
595
596 make_w_sp_status_reg();
597
598 // dpc_register
599 dpc_register.dpc_start = GETDATA(curr, unsigned int);
600 dpc_register.dpc_end = GETDATA(curr, unsigned int);
601 dpc_register.dpc_current = GETDATA(curr, unsigned int);
602 dpc_register.dpc_status = GETDATA(curr, unsigned int);
603 dpc_register.dpc_clock = GETDATA(curr, unsigned int);
604 dpc_register.dpc_bufbusy = GETDATA(curr, unsigned int);
605 dpc_register.dpc_pipebusy = GETDATA(curr, unsigned int);
606 dpc_register.dpc_tmem = GETDATA(curr, unsigned int);
607 (void)GETDATA(curr, unsigned int); // Dummy read
608 (void)GETDATA(curr, unsigned int); // Dummy read
609
610 make_w_dpc_status();
611
612 // mi_register
613 MI_register.mi_init_mode_reg = GETDATA(curr, unsigned int);
614 MI_register.mi_version_reg = GETDATA(curr, unsigned int);
615 MI_register.mi_intr_reg = GETDATA(curr, unsigned int);
616 MI_register.mi_intr_mask_reg = GETDATA(curr, unsigned int);
617
618 make_w_mi_init_mode_reg();
619 make_w_mi_intr_mask_reg();
620
621 // vi_register
622 vi_register.vi_status = GETDATA(curr, unsigned int);
623 vi_register.vi_origin = GETDATA(curr, unsigned int);
624 vi_register.vi_width = GETDATA(curr, unsigned int);
625 vi_register.vi_v_intr = GETDATA(curr, unsigned int);
626 vi_register.vi_current = GETDATA(curr, unsigned int);
627 vi_register.vi_burst = GETDATA(curr, unsigned int);
628 vi_register.vi_v_sync = GETDATA(curr, unsigned int);
629 vi_register.vi_h_sync = GETDATA(curr, unsigned int);
630 vi_register.vi_leap = GETDATA(curr, unsigned int);
631 vi_register.vi_h_start = GETDATA(curr, unsigned int);
632 vi_register.vi_v_start = GETDATA(curr, unsigned int);
633 vi_register.vi_v_burst = GETDATA(curr, unsigned int);
634 vi_register.vi_x_scale = GETDATA(curr, unsigned int);
635 vi_register.vi_y_scale = GETDATA(curr, unsigned int);
636 // TODO vi delay?
637 update_vi_status(vi_register.vi_status);
638 update_vi_width(vi_register.vi_width);
639
640 // ai_register
641 ai_register.ai_dram_addr = GETDATA(curr, unsigned int);
642 ai_register.ai_len = GETDATA(curr, unsigned int);
643 ai_register.ai_control = GETDATA(curr, unsigned int);
644 ai_register.ai_status = GETDATA(curr, unsigned int);
645 ai_register.ai_dacrate = GETDATA(curr, unsigned int);
646 ai_register.ai_bitrate = GETDATA(curr, unsigned int);
647 update_ai_dacrate(ai_register.ai_dacrate);
648
649 // pi_register
650 pi_register.pi_dram_addr_reg = GETDATA(curr, unsigned int);
651 pi_register.pi_cart_addr_reg = GETDATA(curr, unsigned int);
652 pi_register.pi_rd_len_reg = GETDATA(curr, unsigned int);
653 pi_register.pi_wr_len_reg = GETDATA(curr, unsigned int);
654 pi_register.read_pi_status_reg = GETDATA(curr, unsigned int);
655 pi_register.pi_bsd_dom1_lat_reg = GETDATA(curr, unsigned int);
656 pi_register.pi_bsd_dom1_pwd_reg = GETDATA(curr, unsigned int);
657 pi_register.pi_bsd_dom1_pgs_reg = GETDATA(curr, unsigned int);
658 pi_register.pi_bsd_dom1_rls_reg = GETDATA(curr, unsigned int);
659 pi_register.pi_bsd_dom2_lat_reg = GETDATA(curr, unsigned int);
660 pi_register.pi_bsd_dom2_pwd_reg = GETDATA(curr, unsigned int);
661 pi_register.pi_bsd_dom2_pgs_reg = GETDATA(curr, unsigned int);
662 pi_register.pi_bsd_dom2_rls_reg = GETDATA(curr, unsigned int);
663 read_func(handle, &pi_register, sizeof(PI_register));
664
665 // ri_register
666 ri_register.ri_mode = GETDATA(curr, unsigned int);
667 ri_register.ri_config = GETDATA(curr, unsigned int);
668 ri_register.ri_current_load = GETDATA(curr, unsigned int);
669 ri_register.ri_select = GETDATA(curr, unsigned int);
670 ri_register.ri_refresh = GETDATA(curr, unsigned int);
671 ri_register.ri_latency = GETDATA(curr, unsigned int);
672 ri_register.ri_error = GETDATA(curr, unsigned int);
673 ri_register.ri_werror = GETDATA(curr, unsigned int);
674
675 // si_register
676 si_register.si_dram_addr = GETDATA(curr, unsigned int);
677 si_register.si_pif_addr_rd64b = GETDATA(curr, unsigned int);
678 si_register.si_pif_addr_wr64b = GETDATA(curr, unsigned int);
679 si_register.si_stat = GETDATA(curr, unsigned int);
680
681 // tlb
682 memset(tlb_LUT_r, 0, 0x400000);
683 memset(tlb_LUT_w, 0, 0x400000);
684 for (i=0; i < 32; i++)
685 {
686 unsigned int MyPageMask, MyEntryHi, MyEntryLo0, MyEntryLo1;
687
688 (void)GETDATA(curr, unsigned int); // Dummy read - EntryDefined
689 MyPageMask = GETDATA(curr, unsigned int);
690 MyEntryHi = GETDATA(curr, unsigned int);
691 MyEntryLo0 = GETDATA(curr, unsigned int);
692 MyEntryLo1 = GETDATA(curr, unsigned int);
693
694 // This is copied from TLBWI instruction
695 tlb_e[i].g = (MyEntryLo0 & MyEntryLo1 & 1);
696 tlb_e[i].pfn_even = (MyEntryLo0 & 0x3FFFFFC0) >> 6;
697 tlb_e[i].pfn_odd = (MyEntryLo1 & 0x3FFFFFC0) >> 6;
698 tlb_e[i].c_even = (MyEntryLo0 & 0x38) >> 3;
699 tlb_e[i].c_odd = (MyEntryLo1 & 0x38) >> 3;
700 tlb_e[i].d_even = (MyEntryLo0 & 0x4) >> 2;
701 tlb_e[i].d_odd = (MyEntryLo1 & 0x4) >> 2;
702 tlb_e[i].v_even = (MyEntryLo0 & 0x2) >> 1;
703 tlb_e[i].v_odd = (MyEntryLo1 & 0x2) >> 1;
704 tlb_e[i].asid = (MyEntryHi & 0xFF);
705 tlb_e[i].vpn2 = (MyEntryHi & 0xFFFFE000) >> 13;
706 //tlb_e[i].r = (MyEntryHi & 0xC000000000000000LL) >> 62;
707 tlb_e[i].mask = (MyPageMask & 0x1FFE000) >> 13;
708
709 tlb_e[i].start_even = tlb_e[i].vpn2 << 13;
710 tlb_e[i].end_even = tlb_e[i].start_even+
711 (tlb_e[i].mask << 12) + 0xFFF;
712 tlb_e[i].phys_even = tlb_e[i].pfn_even << 12;
713
714 tlb_e[i].start_odd = tlb_e[i].end_even+1;
715 tlb_e[i].end_odd = tlb_e[i].start_odd+
716 (tlb_e[i].mask << 12) + 0xFFF;
717 tlb_e[i].phys_odd = tlb_e[i].pfn_odd << 12;
718
719 tlb_map(&tlb_e[i]);
720 }
721
722 // pif ram
723 COPYARRAY(PIF_RAM, curr, unsigned char, 0x40);
724
725 // RDRAM
726 memset(rdram, 0, 0x800000);
727 COPYARRAY(rdram, curr, unsigned int, SaveRDRAMSize/4);
728
729 // DMEM
730 COPYARRAY(SP_DMEM, curr, unsigned int, 0x1000/4);
731
732 // IMEM
733 COPYARRAY(SP_IMEM, curr, unsigned int, 0x1000/4);
734
735 // The following values should not matter because we don't have any AI interrupt
736 // ai_register.next_delay = 0; ai_register.next_len = 0;
737 // ai_register.current_delay = 0; ai_register.current_len = 0;
738
739 // The following is not available in PJ64 savestate. Keep the values as is.
740 // dps_register.dps_tbist = 0; dps_register.dps_test_mode = 0;
741 // dps_register.dps_buftest_addr = 0; dps_register.dps_buftest_data = 0; llbit = 0;
742
743 // No flashram info in pj64 savestate.
744 init_flashram();
745
746#ifdef NEW_DYNAREC
747 if (r4300emu == CORE_DYNAREC) {
748 pcaddr = GETDATA(curr, unsigned int);
749 pending_exception = 1;
750 invalidate_all_pages();
751 } else {
752 if(r4300emu != CORE_PURE_INTERPRETER)
753 {
754 for (i = 0; i < 0x100000; i++)
755 invalid_code[i] = 1;
756 }
757 generic_jump_to(last_addr);
758 }
759#else
760 if(r4300emu != CORE_PURE_INTERPRETER)
761 {
762 for (i = 0; i < 0x100000; i++)
763 invalid_code[i] = 1;
764 }
765 generic_jump_to(last_addr);
766#endif
767
768 // assert(savestateData+savestateSize == curr)
769
770 free(savestateData);
771 return 1;
772}
773
774static int read_data_from_zip(void *zip, void *buffer, size_t length)
775{
776 return unzReadCurrentFile((unzFile)zip, buffer, (unsigned)length) == length;
777}
778
779static int savestates_load_pj64_zip(char *filepath)
780{
781 char szFileName[256], szExtraField[256], szComment[256];
782 unzFile zipstatefile = NULL;
783 unz_file_info fileinfo;
784 int ret = 0;
785
786 /* Open the .zip file. */
787 zipstatefile = unzOpen(filepath);
788 if (zipstatefile == NULL ||
789 unzGoToFirstFile(zipstatefile) != UNZ_OK ||
790 unzGetCurrentFileInfo(zipstatefile, &fileinfo, szFileName, 255, szExtraField, 255, szComment, 255) != UNZ_OK ||
791 unzOpenCurrentFile(zipstatefile) != UNZ_OK)
792 {
793 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Zip error. Could not open state file: %s", filepath);
794 goto clean_and_exit;
795 }
796
797 if (!savestates_load_pj64(filepath, zipstatefile, read_data_from_zip))
798 goto clean_and_exit;
799
800 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State loaded from: %s", namefrompath(filepath));
801 ret = 1;
802
803 clean_and_exit:
804 if (zipstatefile != NULL)
805 unzClose(zipstatefile);
806 return ret;
807}
808
809static int read_data_from_file(void *file, void *buffer, size_t length)
810{
811 return fread(buffer, 1, length, file) == length;
812}
813
814static int savestates_load_pj64_unc(char *filepath)
815{
816 FILE *f;
817
818 /* Open the file. */
819 f = fopen(filepath, "rb");
820 if (f == NULL)
821 {
822 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not open state file: %s", filepath);
823 return 0;
824 }
825
826 if (!savestates_load_pj64(filepath, f, read_data_from_file))
827 {
828 fclose(f);
829 return 0;
830 }
831
832 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State loaded from: %s", namefrompath(filepath));
833 fclose(f);
834 return 1;
835}
836
837static savestates_type savestates_detect_type(char *filepath)
838{
839 unsigned char magic[4];
840 FILE *f = fopen(filepath, "rb");
841 if (f == NULL)
842 {
843 DebugMessage(M64MSG_STATUS, "Could not open state file %s\n", filepath);
844 return savestates_type_unknown;
845 }
846
847 if (fread(magic, 1, 4, f) != 4)
848 {
849 fclose(f);
850 DebugMessage(M64MSG_STATUS, "Could not read from state file %s\n", filepath);
851 return savestates_type_unknown;
852 }
853
854 fclose(f);
855
856 if (magic[0] == 0x1f && magic[1] == 0x8b) // GZIP header
857 return savestates_type_m64p;
858 else if (memcmp(magic, "PK\x03\x04", 4) == 0) // ZIP header
859 return savestates_type_pj64_zip;
860 else if (memcmp(magic, pj64_magic, 4) == 0) // PJ64 header
861 return savestates_type_pj64_unc;
862 else
863 {
864 DebugMessage(M64MSG_STATUS, "Unknown state file type %s\n", filepath);
865 return savestates_type_unknown;
866 }
867}
868
869int savestates_load(void)
870{
871 FILE *fPtr = NULL;
872 char *filepath = NULL;
873 int ret = 0;
874
875 if (fname == NULL) // For slots, autodetect the savestate type
876 {
877 // try M64P type first
878 type = savestates_type_m64p;
879 filepath = savestates_generate_path(type);
880 fPtr = fopen(filepath, "rb"); // can I open this?
881 if (fPtr == NULL)
882 {
883 free(filepath);
884 // try PJ64 zipped type second
885 type = savestates_type_pj64_zip;
886 filepath = savestates_generate_path(type);
887 fPtr = fopen(filepath, "rb"); // can I open this?
888 if (fPtr == NULL)
889 {
890 free(filepath);
891 // finally, try PJ64 uncompressed
892 type = savestates_type_pj64_unc;
893 filepath = savestates_generate_path(type);
894 fPtr = fopen(filepath, "rb"); // can I open this?
895 if (fPtr == NULL)
896 {
897 free(filepath);
898 filepath = NULL;
899 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "No Mupen64Plus/PJ64 state file found for slot %i", slot);
900 type = savestates_type_unknown;
901 }
902 }
903 }
904 }
905 else // filename of state file to load was set explicitly in 'fname'
906 {
907 // detect type if unknown
908 if (type == savestates_type_unknown)
909 {
910 type = savestates_detect_type(fname);
911 }
912 filepath = savestates_generate_path(type);
913 if (filepath != NULL)
914 fPtr = fopen(filepath, "rb"); // can I open this?
915 if (fPtr == NULL)
916 {
917 if (filepath != NULL)
918 free(filepath);
919 filepath = NULL;
920 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Failed to open savestate file %s", filepath);
921 }
922 }
923 if (fPtr != NULL)
924 fclose(fPtr);
925
926 if (filepath != NULL)
927 {
928 switch (type)
929 {
930 case savestates_type_m64p: ret = savestates_load_m64p(filepath); break;
931 case savestates_type_pj64_zip: ret = savestates_load_pj64_zip(filepath); break;
932 case savestates_type_pj64_unc: ret = savestates_load_pj64_unc(filepath); break;
933 default: ret = 0; break;
934 }
935 free(filepath);
936 filepath = NULL;
937 }
938
939 // deliver callback to indicate completion of state loading operation
940 StateChanged(M64CORE_STATE_LOADCOMPLETE, ret);
941
942 savestates_clear_job();
943
944 return ret;
945}
946
947static void savestates_save_m64p_work(struct work_struct *work)
948{
949 gzFile f;
950 struct savestate_work *save = container_of(work, struct savestate_work, work);
951
952 SDL_LockMutex(savestates_lock);
953
954 // Write the state to a GZIP file
955 f = gzopen(save->filepath, "wb");
956
957 if (f==NULL)
958 {
959 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not open state file: %s", save->filepath);
960 free(save->data);
961 return;
962 }
963
964 if (gzwrite(f, save->data, save->size) != save->size)
965 {
966 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not write data to state file: %s", save->filepath);
967 gzclose(f);
968 free(save->data);
969 return;
970 }
971
972 gzclose(f);
973 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Saved state to: %s", namefrompath(save->filepath));
974 free(save->data);
975 free(save->filepath);
976 free(save);
977
978 SDL_UnlockMutex(savestates_lock);
979}
980
981static int savestates_save_m64p(char *filepath)
982{
983 unsigned char outbuf[4];
984 int i;
985
986 char queue[1024];
987 int queuelength;
988
989 struct savestate_work *save;
990 char *curr;
991
992 save = malloc(sizeof(*save));
993 if (!save) {
994 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Insufficient memory to save state.");
995 return 0;
996 }
997
998 save->filepath = strdup(filepath);
999
1000 if(autoinc_save_slot)
1001 savestates_inc_slot();
1002
1003 queuelength = save_eventqueue_infos(queue);
1004
1005 // Allocate memory for the save state data
1006 save->size = 16788288 + queuelength;
1007 save->data = curr = malloc(save->size);
1008 if (save->data == NULL)
1009 {
1010 free(save->filepath);
1011 free(save);
1012 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Insufficient memory to save state.");
1013 return 0;
1014 }
1015
1016 // Write the save state data to memory
1017 PUTARRAY(savestate_magic, curr, unsigned char, 8);
1018
1019 outbuf[0] = (savestate_latest_version >> 24) & 0xff;
1020 outbuf[1] = (savestate_latest_version >> 16) & 0xff;
1021 outbuf[2] = (savestate_latest_version >> 8) & 0xff;
1022 outbuf[3] = (savestate_latest_version >> 0) & 0xff;
1023 PUTARRAY(outbuf, curr, unsigned char, 4);
1024
1025 PUTARRAY(ROM_SETTINGS.MD5, curr, char, 32);
1026
1027 PUTDATA(curr, unsigned int, rdram_register.rdram_config);
1028 PUTDATA(curr, unsigned int, rdram_register.rdram_device_id);
1029 PUTDATA(curr, unsigned int, rdram_register.rdram_delay);
1030 PUTDATA(curr, unsigned int, rdram_register.rdram_mode);
1031 PUTDATA(curr, unsigned int, rdram_register.rdram_ref_interval);
1032 PUTDATA(curr, unsigned int, rdram_register.rdram_ref_row);
1033 PUTDATA(curr, unsigned int, rdram_register.rdram_ras_interval);
1034 PUTDATA(curr, unsigned int, rdram_register.rdram_min_interval);
1035 PUTDATA(curr, unsigned int, rdram_register.rdram_addr_select);
1036 PUTDATA(curr, unsigned int, rdram_register.rdram_device_manuf);
1037
1038 PUTDATA(curr, unsigned int, MI_register.w_mi_init_mode_reg);
1039 PUTDATA(curr, unsigned int, MI_register.mi_init_mode_reg);
1040 PUTDATA(curr, unsigned char, MI_register.mi_init_mode_reg & 0x7F);
1041 PUTDATA(curr, unsigned char, (MI_register.mi_init_mode_reg & 0x80) != 0);
1042 PUTDATA(curr, unsigned char, (MI_register.mi_init_mode_reg & 0x100) != 0);
1043 PUTDATA(curr, unsigned char, (MI_register.mi_init_mode_reg & 0x200) != 0);
1044 PUTDATA(curr, unsigned int, MI_register.mi_version_reg);
1045 PUTDATA(curr, unsigned int, MI_register.mi_intr_reg);
1046 PUTDATA(curr, unsigned int, MI_register.mi_intr_mask_reg);
1047 PUTDATA(curr, unsigned int, MI_register.w_mi_intr_mask_reg);
1048 PUTDATA(curr, unsigned char, (MI_register.mi_intr_mask_reg & 0x1) != 0);
1049 PUTDATA(curr, unsigned char, (MI_register.mi_intr_mask_reg & 0x2) != 0);
1050 PUTDATA(curr, unsigned char, (MI_register.mi_intr_mask_reg & 0x4) != 0);
1051 PUTDATA(curr, unsigned char, (MI_register.mi_intr_mask_reg & 0x8) != 0);
1052 PUTDATA(curr, unsigned char, (MI_register.mi_intr_mask_reg & 0x10) != 0);
1053 PUTDATA(curr, unsigned char, (MI_register.mi_intr_mask_reg & 0x20) != 0);
1054 PUTDATA(curr, unsigned short, 0); // Padding from old implementation
1055
1056 PUTDATA(curr, unsigned int, pi_register.pi_dram_addr_reg);
1057 PUTDATA(curr, unsigned int, pi_register.pi_cart_addr_reg);
1058 PUTDATA(curr, unsigned int, pi_register.pi_rd_len_reg);
1059 PUTDATA(curr, unsigned int, pi_register.pi_wr_len_reg);
1060 PUTDATA(curr, unsigned int, pi_register.read_pi_status_reg);
1061 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_lat_reg);
1062 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_pwd_reg);
1063 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_pgs_reg);
1064 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_rls_reg);
1065 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_lat_reg);
1066 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_pwd_reg);
1067 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_pgs_reg);
1068 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_rls_reg);
1069
1070 PUTDATA(curr, unsigned int, sp_register.sp_mem_addr_reg);
1071 PUTDATA(curr, unsigned int, sp_register.sp_dram_addr_reg);
1072 PUTDATA(curr, unsigned int, sp_register.sp_rd_len_reg);
1073 PUTDATA(curr, unsigned int, sp_register.sp_wr_len_reg);
1074 PUTDATA(curr, unsigned int, sp_register.w_sp_status_reg);
1075 PUTDATA(curr, unsigned int, sp_register.sp_status_reg);
1076 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x1) != 0);
1077 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x2) != 0);
1078 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x4) != 0);
1079 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x8) != 0);
1080 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x10) != 0);
1081 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x20) != 0);
1082 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x40) != 0);
1083 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x80) != 0);
1084 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x100) != 0);
1085 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x200) != 0);
1086 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x400) != 0);
1087 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x800) != 0);
1088 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x1000) != 0);
1089 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x2000) != 0);
1090 PUTDATA(curr, unsigned char, (sp_register.sp_status_reg & 0x4000) != 0);
1091 PUTDATA(curr, unsigned char, 0);
1092 PUTDATA(curr, unsigned int, sp_register.sp_dma_full_reg);
1093 PUTDATA(curr, unsigned int, sp_register.sp_dma_busy_reg);
1094 PUTDATA(curr, unsigned int, sp_register.sp_semaphore_reg);
1095
1096 PUTDATA(curr, unsigned int, rsp_register.rsp_pc);
1097 PUTDATA(curr, unsigned int, rsp_register.rsp_ibist);
1098
1099 PUTDATA(curr, unsigned int, si_register.si_dram_addr);
1100 PUTDATA(curr, unsigned int, si_register.si_pif_addr_rd64b);
1101 PUTDATA(curr, unsigned int, si_register.si_pif_addr_wr64b);
1102 PUTDATA(curr, unsigned int, si_register.si_stat);
1103
1104 PUTDATA(curr, unsigned int, vi_register.vi_status);
1105 PUTDATA(curr, unsigned int, vi_register.vi_origin);
1106 PUTDATA(curr, unsigned int, vi_register.vi_width);
1107 PUTDATA(curr, unsigned int, vi_register.vi_v_intr);
1108 PUTDATA(curr, unsigned int, vi_register.vi_current);
1109 PUTDATA(curr, unsigned int, vi_register.vi_burst);
1110 PUTDATA(curr, unsigned int, vi_register.vi_v_sync);
1111 PUTDATA(curr, unsigned int, vi_register.vi_h_sync);
1112 PUTDATA(curr, unsigned int, vi_register.vi_leap);
1113 PUTDATA(curr, unsigned int, vi_register.vi_h_start);
1114 PUTDATA(curr, unsigned int, vi_register.vi_v_start);
1115 PUTDATA(curr, unsigned int, vi_register.vi_v_burst);
1116 PUTDATA(curr, unsigned int, vi_register.vi_x_scale);
1117 PUTDATA(curr, unsigned int, vi_register.vi_y_scale);
1118 PUTDATA(curr, unsigned int, vi_register.vi_delay);
1119
1120 PUTDATA(curr, unsigned int, ri_register.ri_mode);
1121 PUTDATA(curr, unsigned int, ri_register.ri_config);
1122 PUTDATA(curr, unsigned int, ri_register.ri_current_load);
1123 PUTDATA(curr, unsigned int, ri_register.ri_select);
1124 PUTDATA(curr, unsigned int, ri_register.ri_refresh);
1125 PUTDATA(curr, unsigned int, ri_register.ri_latency);
1126 PUTDATA(curr, unsigned int, ri_register.ri_error);
1127 PUTDATA(curr, unsigned int, ri_register.ri_werror);
1128
1129 PUTDATA(curr, unsigned int, ai_register.ai_dram_addr);
1130 PUTDATA(curr, unsigned int, ai_register.ai_len);
1131 PUTDATA(curr, unsigned int, ai_register.ai_control);
1132 PUTDATA(curr, unsigned int, ai_register.ai_status);
1133 PUTDATA(curr, unsigned int, ai_register.ai_dacrate);
1134 PUTDATA(curr, unsigned int, ai_register.ai_bitrate);
1135 PUTDATA(curr, unsigned int, ai_register.next_delay);
1136 PUTDATA(curr, unsigned int, ai_register.next_len);
1137 PUTDATA(curr, unsigned int, ai_register.current_delay);
1138 PUTDATA(curr, unsigned int, ai_register.current_len);
1139
1140 PUTDATA(curr, unsigned int, dpc_register.dpc_start);
1141 PUTDATA(curr, unsigned int, dpc_register.dpc_end);
1142 PUTDATA(curr, unsigned int, dpc_register.dpc_current);
1143 PUTDATA(curr, unsigned int, dpc_register.w_dpc_status);
1144 PUTDATA(curr, unsigned int, dpc_register.dpc_status);
1145 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x1) != 0);
1146 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x2) != 0);
1147 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x4) != 0);
1148 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x8) != 0);
1149 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x10) != 0);
1150 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x20) != 0);
1151 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x40) != 0);
1152 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x80) != 0);
1153 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x100) != 0);
1154 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x200) != 0);
1155 PUTDATA(curr, unsigned char, (dpc_register.dpc_status & 0x400) != 0);
1156 PUTDATA(curr, unsigned char, 0);
1157 PUTDATA(curr, unsigned int, dpc_register.dpc_clock);
1158 PUTDATA(curr, unsigned int, dpc_register.dpc_bufbusy);
1159 PUTDATA(curr, unsigned int, dpc_register.dpc_pipebusy);
1160 PUTDATA(curr, unsigned int, dpc_register.dpc_tmem);
1161
1162 PUTDATA(curr, unsigned int, dps_register.dps_tbist);
1163 PUTDATA(curr, unsigned int, dps_register.dps_test_mode);
1164 PUTDATA(curr, unsigned int, dps_register.dps_buftest_addr);
1165 PUTDATA(curr, unsigned int, dps_register.dps_buftest_data);
1166
1167 PUTARRAY(rdram, curr, unsigned int, 0x800000/4);
1168 PUTARRAY(SP_DMEM, curr, unsigned int, 0x1000/4);
1169 PUTARRAY(SP_IMEM, curr, unsigned int, 0x1000/4);
1170 PUTARRAY(PIF_RAM, curr, unsigned char, 0x40);
1171
1172 PUTDATA(curr, int, flashram_info.use_flashram);
1173 PUTDATA(curr, int, flashram_info.mode);
1174 PUTDATA(curr, unsigned long long, flashram_info.status);
1175 PUTDATA(curr, unsigned int, flashram_info.erase_offset);
1176 PUTDATA(curr, unsigned int, flashram_info.write_pointer);
1177
1178 PUTARRAY(tlb_LUT_r, curr, unsigned int, 0x100000);
1179 PUTARRAY(tlb_LUT_w, curr, unsigned int, 0x100000);
1180
1181 PUTDATA(curr, unsigned int, llbit);
1182 PUTARRAY(reg, curr, long long int, 32);
1183 PUTARRAY(reg_cop0, curr, unsigned int, 32);
1184 PUTDATA(curr, long long int, lo);
1185 PUTDATA(curr, long long int, hi);
1186
1187 if ((Status & 0x04000000) == 0) // FR bit == 0 means 32-bit (MIPS I) FGR mode
1188 shuffle_fpr_data(0, 0x04000000); // shuffle data into 64-bit register format for storage
1189 PUTARRAY(reg_cop1_fgr_64, curr, long long int, 32);
1190 if ((Status & 0x04000000) == 0)
1191 shuffle_fpr_data(0x04000000, 0); // put it back in 32-bit mode
1192
1193 PUTDATA(curr, int, FCR0);
1194 PUTDATA(curr, int, FCR31);
1195 for (i = 0; i < 32; i++)
1196 {
1197 PUTDATA(curr, short, tlb_e[i].mask);
1198 PUTDATA(curr, short, 0);
1199 PUTDATA(curr, int, tlb_e[i].vpn2);
1200 PUTDATA(curr, char, tlb_e[i].g);
1201 PUTDATA(curr, unsigned char, tlb_e[i].asid);
1202 PUTDATA(curr, short, 0);
1203 PUTDATA(curr, int, tlb_e[i].pfn_even);
1204 PUTDATA(curr, char, tlb_e[i].c_even);
1205 PUTDATA(curr, char, tlb_e[i].d_even);
1206 PUTDATA(curr, char, tlb_e[i].v_even);
1207 PUTDATA(curr, char, 0);
1208 PUTDATA(curr, int, tlb_e[i].pfn_odd);
1209 PUTDATA(curr, char, tlb_e[i].c_odd);
1210 PUTDATA(curr, char, tlb_e[i].d_odd);
1211 PUTDATA(curr, char, tlb_e[i].v_odd);
1212 PUTDATA(curr, char, tlb_e[i].r);
1213
1214 PUTDATA(curr, unsigned int, tlb_e[i].start_even);
1215 PUTDATA(curr, unsigned int, tlb_e[i].end_even);
1216 PUTDATA(curr, unsigned int, tlb_e[i].phys_even);
1217 PUTDATA(curr, unsigned int, tlb_e[i].start_odd);
1218 PUTDATA(curr, unsigned int, tlb_e[i].end_odd);
1219 PUTDATA(curr, unsigned int, tlb_e[i].phys_odd);
1220 }
1221#ifdef NEW_DYNAREC
1222 if (r4300emu == CORE_DYNAREC)
1223 PUTDATA(curr, unsigned int, pcaddr);
1224 else
1225 PUTDATA(curr, unsigned int, PC->addr);
1226#else
1227 PUTDATA(curr, unsigned int, PC->addr);
1228#endif
1229
1230 PUTDATA(curr, unsigned int, next_interupt);
1231 PUTDATA(curr, unsigned int, next_vi);
1232 PUTDATA(curr, unsigned int, vi_field);
1233
1234 to_little_endian_buffer(queue, 4, queuelength/4);
1235 PUTARRAY(queue, curr, char, queuelength);
1236
1237 // assert(curr == save->data + save->size)
1238
1239 init_work(&save->work, savestates_save_m64p_work);
1240 queue_work(&save->work);
1241
1242 return 1;
1243}
1244
1245static int savestates_save_pj64(char *filepath, void *handle,
1246 int (*write_func)(void *, const void *, size_t))
1247{
1248 unsigned int i;
1249 unsigned int SaveRDRAMSize = 0x800000;
1250
1251 size_t savestateSize;
1252 unsigned char *savestateData, *curr;
1253
1254 // Allocate memory for the save state data
1255 savestateSize = 8 + SaveRDRAMSize + 0x2754;
1256 savestateData = curr = (unsigned char *)malloc(savestateSize);
1257 if (savestateData == NULL)
1258 {
1259 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Insufficient memory to save state.");
1260 return 0;
1261 }
1262
1263 // Write the save state data in memory
1264 PUTARRAY(pj64_magic, curr, unsigned char, 4);
1265 PUTDATA(curr, unsigned int, SaveRDRAMSize);
1266 PUTARRAY(rom, curr, unsigned int, 0x40/4);
1267 PUTDATA(curr, unsigned int, get_event(VI_INT) - reg_cop0[9]); // vi_timer
1268#ifdef NEW_DYNAREC
1269 if (r4300emu == CORE_DYNAREC)
1270 PUTDATA(curr, unsigned int, pcaddr);
1271 else
1272 PUTDATA(curr, unsigned int, PC->addr);
1273#else
1274 PUTDATA(curr, unsigned int, PC->addr);
1275#endif
1276 PUTARRAY(reg, curr, long long int, 32);
1277 if ((Status & 0x04000000) == 0) // TODO not sure how pj64 handles this
1278 shuffle_fpr_data(0x04000000, 0);
1279 PUTARRAY(reg_cop1_fgr_64, curr, long long int, 32);
1280 if ((Status & 0x04000000) == 0) // TODO not sure how pj64 handles this
1281 shuffle_fpr_data(0x04000000, 0);
1282 PUTARRAY(reg_cop0, curr, unsigned int, 32);
1283 PUTDATA(curr, int, FCR0);
1284 for (i = 0; i < 30; i++)
1285 PUTDATA(curr, int, 0); // FCR1-30 not implemented
1286 PUTDATA(curr, int, FCR31);
1287 PUTDATA(curr, long long int, hi);
1288 PUTDATA(curr, long long int, lo);
1289
1290 PUTDATA(curr, unsigned int, rdram_register.rdram_config);
1291 PUTDATA(curr, unsigned int, rdram_register.rdram_device_id);
1292 PUTDATA(curr, unsigned int, rdram_register.rdram_delay);
1293 PUTDATA(curr, unsigned int, rdram_register.rdram_mode);
1294 PUTDATA(curr, unsigned int, rdram_register.rdram_ref_interval);
1295 PUTDATA(curr, unsigned int, rdram_register.rdram_ref_row);
1296 PUTDATA(curr, unsigned int, rdram_register.rdram_ras_interval);
1297 PUTDATA(curr, unsigned int, rdram_register.rdram_min_interval);
1298 PUTDATA(curr, unsigned int, rdram_register.rdram_addr_select);
1299 PUTDATA(curr, unsigned int, rdram_register.rdram_device_manuf);
1300
1301 PUTDATA(curr, unsigned int, sp_register.sp_mem_addr_reg);
1302 PUTDATA(curr, unsigned int, sp_register.sp_dram_addr_reg);
1303 PUTDATA(curr, unsigned int, sp_register.sp_rd_len_reg);
1304 PUTDATA(curr, unsigned int, sp_register.sp_wr_len_reg);
1305 PUTDATA(curr, unsigned int, sp_register.sp_status_reg);
1306 PUTDATA(curr, unsigned int, sp_register.sp_dma_full_reg);
1307 PUTDATA(curr, unsigned int, sp_register.sp_dma_busy_reg);
1308 PUTDATA(curr, unsigned int, sp_register.sp_semaphore_reg);
1309
1310 PUTDATA(curr, unsigned int, rsp_register.rsp_pc);
1311 PUTDATA(curr, unsigned int, rsp_register.rsp_ibist);
1312
1313 PUTDATA(curr, unsigned int, dpc_register.dpc_start);
1314 PUTDATA(curr, unsigned int, dpc_register.dpc_end);
1315 PUTDATA(curr, unsigned int, dpc_register.dpc_current);
1316 PUTDATA(curr, unsigned int, dpc_register.dpc_status);
1317 PUTDATA(curr, unsigned int, dpc_register.dpc_clock);
1318 PUTDATA(curr, unsigned int, dpc_register.dpc_bufbusy);
1319 PUTDATA(curr, unsigned int, dpc_register.dpc_pipebusy);
1320 PUTDATA(curr, unsigned int, dpc_register.dpc_tmem);
1321 PUTDATA(curr, unsigned int, 0); // ?
1322 PUTDATA(curr, unsigned int, 0); // ?
1323
1324 PUTDATA(curr, unsigned int, MI_register.mi_init_mode_reg); //TODO Secial handling in pj64
1325 PUTDATA(curr, unsigned int, MI_register.mi_version_reg);
1326 PUTDATA(curr, unsigned int, MI_register.mi_intr_reg);
1327 PUTDATA(curr, unsigned int, MI_register.mi_intr_mask_reg);
1328
1329 PUTDATA(curr, unsigned int, vi_register.vi_status);
1330 PUTDATA(curr, unsigned int, vi_register.vi_origin);
1331 PUTDATA(curr, unsigned int, vi_register.vi_width);
1332 PUTDATA(curr, unsigned int, vi_register.vi_v_intr);
1333 PUTDATA(curr, unsigned int, vi_register.vi_current);
1334 PUTDATA(curr, unsigned int, vi_register.vi_burst);
1335 PUTDATA(curr, unsigned int, vi_register.vi_v_sync);
1336 PUTDATA(curr, unsigned int, vi_register.vi_h_sync);
1337 PUTDATA(curr, unsigned int, vi_register.vi_leap);
1338 PUTDATA(curr, unsigned int, vi_register.vi_h_start);
1339 PUTDATA(curr, unsigned int, vi_register.vi_v_start);
1340 PUTDATA(curr, unsigned int, vi_register.vi_v_burst);
1341 PUTDATA(curr, unsigned int, vi_register.vi_x_scale);
1342 PUTDATA(curr, unsigned int, vi_register.vi_y_scale);
1343
1344 PUTDATA(curr, unsigned int, ai_register.ai_dram_addr);
1345 PUTDATA(curr, unsigned int, ai_register.ai_len);
1346 PUTDATA(curr, unsigned int, ai_register.ai_control);
1347 PUTDATA(curr, unsigned int, ai_register.ai_status);
1348 PUTDATA(curr, unsigned int, ai_register.ai_dacrate);
1349 PUTDATA(curr, unsigned int, ai_register.ai_bitrate);
1350
1351 PUTDATA(curr, unsigned int, pi_register.pi_dram_addr_reg);
1352 PUTDATA(curr, unsigned int, pi_register.pi_cart_addr_reg);
1353 PUTDATA(curr, unsigned int, pi_register.pi_rd_len_reg);
1354 PUTDATA(curr, unsigned int, pi_register.pi_wr_len_reg);
1355 PUTDATA(curr, unsigned int, pi_register.read_pi_status_reg);
1356 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_lat_reg);
1357 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_pwd_reg);
1358 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_pgs_reg);
1359 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom1_rls_reg);
1360 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_lat_reg);
1361 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_pwd_reg);
1362 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_pgs_reg);
1363 PUTDATA(curr, unsigned int, pi_register.pi_bsd_dom2_rls_reg);
1364
1365 PUTDATA(curr, unsigned int, ri_register.ri_mode);
1366 PUTDATA(curr, unsigned int, ri_register.ri_config);
1367 PUTDATA(curr, unsigned int, ri_register.ri_current_load);
1368 PUTDATA(curr, unsigned int, ri_register.ri_select);
1369 PUTDATA(curr, unsigned int, ri_register.ri_refresh);
1370 PUTDATA(curr, unsigned int, ri_register.ri_latency);
1371 PUTDATA(curr, unsigned int, ri_register.ri_error);
1372 PUTDATA(curr, unsigned int, ri_register.ri_werror);
1373
1374 PUTDATA(curr, unsigned int, si_register.si_dram_addr);
1375 PUTDATA(curr, unsigned int, si_register.si_pif_addr_rd64b);
1376 PUTDATA(curr, unsigned int, si_register.si_pif_addr_wr64b);
1377 PUTDATA(curr, unsigned int, si_register.si_stat);
1378
1379 for (i=0; i < 32;i++)
1380 {
1381 // From TLBR
1382 unsigned int EntryDefined, MyPageMask, MyEntryHi, MyEntryLo0, MyEntryLo1;
1383 EntryDefined = tlb_e[i].v_even || tlb_e[i].v_odd;
1384 MyPageMask = tlb_e[i].mask << 13;
1385 MyEntryHi = ((tlb_e[i].vpn2 << 13) | tlb_e[i].asid);
1386 MyEntryLo0 = (tlb_e[i].pfn_even << 6) | (tlb_e[i].c_even << 3)
1387 | (tlb_e[i].d_even << 2) | (tlb_e[i].v_even << 1)
1388 | tlb_e[i].g;
1389 MyEntryLo1 = (tlb_e[i].pfn_odd << 6) | (tlb_e[i].c_odd << 3)
1390 | (tlb_e[i].d_odd << 2) | (tlb_e[i].v_odd << 1)
1391 | tlb_e[i].g;
1392
1393 PUTDATA(curr, unsigned int, EntryDefined);
1394 PUTDATA(curr, unsigned int, MyPageMask);
1395 PUTDATA(curr, unsigned int, MyEntryHi);
1396 PUTDATA(curr, unsigned int, MyEntryLo0);
1397 PUTDATA(curr, unsigned int, MyEntryLo1);
1398 }
1399
1400 PUTARRAY(PIF_RAM, curr, unsigned char, 0x40);
1401
1402 PUTARRAY(rdram, curr, unsigned int, SaveRDRAMSize/4);
1403 PUTARRAY(SP_DMEM, curr, unsigned int, 0x1000/4);
1404 PUTARRAY(SP_IMEM, curr, unsigned int, 0x1000/4);
1405
1406 // Write the save state data to the output
1407 if (!write_func(handle, savestateData, savestateSize))
1408 {
1409 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Couldn't write data to Project64 state file %s.", filepath);
1410 free(savestateData);
1411 return 0;
1412 }
1413
1414 // assert(savestateData+savestateSize == curr)
1415 free(savestateData);
1416 return 1;
1417}
1418
1419static int write_data_to_zip(void *zip, const void *buffer, size_t length)
1420{
1421 return zipWriteInFileInZip((zipFile)zip, buffer, (unsigned)length) == ZIP_OK;
1422}
1423
1424static int savestates_save_pj64_zip(char *filepath)
1425{
1426 int retval;
1427 zipFile zipfile = NULL;
1428
1429 zipfile = zipOpen(filepath, APPEND_STATUS_CREATE);
1430 if(zipfile == NULL)
1431 {
1432 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not create PJ64 state file: %s", filepath);
1433 goto clean_and_exit;
1434 }
1435
1436 retval = zipOpenNewFileInZip(zipfile, namefrompath(filepath), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
1437 if(retval != ZIP_OK)
1438 {
1439 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Zip error. Could not create state file: %s", filepath);
1440 goto clean_and_exit;
1441 }
1442
1443 if (!savestates_save_pj64(filepath, zipfile, write_data_to_zip))
1444 goto clean_and_exit;
1445
1446 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Saved state to: %s", namefrompath(filepath));
1447
1448 clean_and_exit:
1449 if (zipfile != NULL)
1450 {
1451 zipCloseFileInZip(zipfile); // This may fail, but we don't care
1452 zipClose(zipfile, "");
1453 }
1454 return 1;
1455}
1456
1457static int write_data_to_file(void *file, const void *buffer, size_t length)
1458{
1459 return fwrite(buffer, 1, length, (FILE *)file) == length;
1460}
1461
1462static int savestates_save_pj64_unc(char *filepath)
1463{
1464 FILE *f;
1465
1466 f = fopen(filepath, "wb");
1467 if (f == NULL)
1468 {
1469 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not create PJ64 state file: %s", filepath);
1470 return 0;
1471 }
1472
1473 if (!savestates_save_pj64(filepath, f, write_data_to_file))
1474 {
1475 fclose(f);
1476 return 0;
1477 }
1478
1479 main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Saved state to: %s", namefrompath(filepath));
1480 fclose(f);
1481 return 1;
1482}
1483
1484int savestates_save(void)
1485{
1486 char *filepath;
1487 int ret = 0;
1488
1489 /* Can only save PJ64 savestates on VI / COMPARE interrupt.
1490 Otherwise try again in a little while. */
1491 if ((type == savestates_type_pj64_zip ||
1492 type == savestates_type_pj64_unc) &&
1493 get_next_event_type() > COMPARE_INT)
1494 return 0;
1495
1496 if (fname != NULL && type == savestates_type_unknown)
1497 type = savestates_type_m64p;
1498 else if (fname == NULL) // Always save slots in M64P format
1499 type = savestates_type_m64p;
1500
1501 filepath = savestates_generate_path(type);
1502 if (filepath != NULL)
1503 {
1504 switch (type)
1505 {
1506 case savestates_type_m64p: ret = savestates_save_m64p(filepath); break;
1507 case savestates_type_pj64_zip: ret = savestates_save_pj64_zip(filepath); break;
1508 case savestates_type_pj64_unc: ret = savestates_save_pj64_unc(filepath); break;
1509 default: ret = 0; break;
1510 }
1511 free(filepath);
1512 }
1513
1514 // deliver callback to indicate completion of state saving operation
1515 StateChanged(M64CORE_STATE_SAVECOMPLETE, ret);
1516
1517 savestates_clear_job();
1518 return ret;
1519}
1520
1521void savestates_init(void)
1522{
1523 savestates_lock = SDL_CreateMutex();
1524 if (!savestates_lock) {
1525 DebugMessage(M64MSG_ERROR, "Could not create savestates list lock");
1526 return;
1527 }
1528}
1529
1530void savestates_deinit(void)
1531{
1532 SDL_DestroyMutex(savestates_lock);
1533 savestates_clear_job();
1534}