improved debug
[fceu.git] / state.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 /*  TODO: Add (better) file io error checking */
22 /*  TODO: Change save state file format. */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #ifdef GP2X
28 #include <unistd.h>
29 #endif
30
31 #include "types.h"
32 #include "x6502.h"
33 #include "version.h"
34 #include "fce.h"
35 #include "sound.h"
36 #define INESPRIV                // Take this out when old save state support is removed in a future version.
37 #include "ines.h"
38 #include "svga.h"
39 #include "endian.h"
40 #include "fds.h"
41 #include "general.h"
42 #include "state.h"
43 #include "memory.h"
44 #include "ppu.h"
45
46 static SFORMAT SFMDATA[64];
47 static int SFEXINDEX;
48 static int stateversion;
49
50 #define RLSB            0x80000000
51
52 #define SFCPUELEMENTS 7
53
54 SFORMAT SFCPU[SFCPUELEMENTS]={
55  { &X.PC, 2|RLSB, "PC\0"},
56  { &X.A, 1, "A\0\0"},
57  { &X.P, 1, "P\0\0"},
58  { &X.X, 1, "X\0\0"},
59  { &X.Y, 1, "Y\0\0"},
60  { &X.S, 1, "S\0\0"},
61  { RAM, 0x800, "RAM"}
62 };
63
64 #define SFCPUCELEMENTS 6
65 SFORMAT SFCPUC[SFCPUCELEMENTS]={
66  { &X.jammed, 1, "JAMM"},
67  { &X.IRQlow, 1, "IRQL"},
68  { &X.tcount, 4|RLSB, "ICoa"},
69  { &X.count,  4|RLSB, "ICou"},
70  { &timestamp, 4|RLSB, "TIME"},
71  { &timestampbase, 8|RLSB, "TMEB"}
72 };
73
74 static uint16 TempAddrT,RefreshAddrT;
75
76 #define SFPPUELEMENTS 10
77 SFORMAT SFPPU[SFPPUELEMENTS]={
78  { NTARAM, 0x800, "NTAR"},
79  { PALRAM, 0x20, "PRAM"},
80  { SPRAM, 0x100, "SPRA"},
81  { PPU, 0x4, "PPUR"},
82  { &XOffset, 1, "XOFF"},
83  { &vtoggle, 1, "VTOG"},
84  { &RefreshAddrT, 2|RLSB, "RADD"},
85  { &TempAddrT, 2|RLSB, "TADD"},
86  { &VRAMBuffer, 1, "VBUF"},
87  { &PPUGenLatch, 1, "PGEN"},
88 };
89
90 // Is this chunk necessary?  I'll fix it later.
91 //#define SFCTLRELEMENTS 2
92 //SFORMAT SFCTLR[SFCTLRELEMENTS]={
93 // { &joy_readbit, 1, "J1RB"},
94 // { &joy2_readbit, 1, "J2RB"}
95 //};
96
97 #define SFSNDELEMENTS 18
98 SFORMAT SFSND[SFSNDELEMENTS]={
99  { &fhcnt, 4|RLSB,"FHCN"},
100  { &fcnt, 1, "FCNT"},
101  { PSG, 14, "PSG"},
102  { &PSG[0x15], 1, "P15"},
103  { &PSG[0x17], 1, "P17"},
104  { decvolume, 3, "DECV"},
105  { &sqnon, 1, "SQNO"},
106  { &nreg, 2|RLSB, "NREG"},
107  { &trimode, 1, "TRIM"},
108  { &tricoop, 1, "TRIC"},
109  { sweepon, 2, "SWEE"},
110  { &curfreq[0], 4|RLSB,"CRF1"},
111  { &curfreq[1], 4|RLSB,"CRF2"},
112  { SweepCount, 2,"SWCT"},
113  { DecCountTo1, 3,"DCT1"},
114  { &PCMBitIndex, 1,"PBIN"},
115  { &PCMAddressIndex, 4|RLSB, "PAIN"},
116  { &PCMSizeIndex, 4|RLSB, "PSIN"}
117 };
118
119
120 int WriteStateChunk(FILE *st, int type, SFORMAT *sf, int count)
121 {
122  int bsize;
123  int x;
124
125  fputc(type,st);
126
127  for(x=bsize=0;x<count;x++)
128   bsize+=sf[x].s&(~RLSB);
129  bsize+=count<<3;
130  write32(bsize,st);
131  for(x=0;x<count;x++)
132  {
133   fwrite(sf[x].desc,1,4,st);
134   write32(sf[x].s&(~RLSB),st);
135   #ifdef LSB_FIRST
136   fwrite((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
137   #else
138   {
139   int z;
140   if(sf[x].s&RLSB)
141   {
142    for(z=(sf[x].s&(~RLSB))-1;z>=0;z--)
143    {
144     fputc(*(uint8*)sf[x].v,st);
145    }
146   }
147   else
148    fwrite((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
149   }
150   #endif
151  }
152  return (bsize+5);
153 }
154
155 int ReadStateChunk(FILE *st, SFORMAT *sf, int count, int size)
156 {
157  uint8 tmpyo[16];
158  int bsize;
159  int x;
160
161  for(x=bsize=0;x<count;x++)
162   bsize+=sf[x].s&(~RLSB);
163  if(stateversion>=53)
164   bsize+=count<<3;
165  else
166  {
167   if(bsize!=size)
168   {
169    fseek(st,size,SEEK_CUR);
170    return 0;
171   }
172  }
173
174  if(stateversion<56)
175   memcpy(tmpyo,mapbyte3,16);
176
177  if(stateversion>=53)
178  {
179   int temp;
180   temp=ftell(st);
181
182   while(ftell(st)<temp+size)
183   {
184    int tsize;
185    char toa[4];
186
187    if(fread(toa,1,4,st)<=0)
188     return 0;
189    read32(&tsize,st);
190
191    for(x=0;x<count;x++)
192    {
193     if(!memcmp(toa,sf[x].desc,4))
194     {
195      if(tsize!=(sf[x].s&(~RLSB)))
196       goto nkayo;
197      #ifndef LSB_FIRST
198      if(sf[x].s&RLSB)
199      {
200       int z;
201        for(z=(sf[x].s&(~RLSB))-1;z>=0;z--)
202         *(uint8*)sf[x].v=fgetc(st);
203      }
204      else
205      #endif
206      {
207        fread((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
208      }
209      goto bloo;
210     }
211    }
212   nkayo:
213   fseek(st,tsize,SEEK_CUR);
214   bloo:;
215   } // while(...)
216  }  // >=53
217  else
218  {
219   for(x=0;x<count;x++)
220   {
221    #ifdef LSB_FIRST
222    fread((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
223    #else
224    int z;
225    if(sf[x].s&RLSB)
226     for(z=(sf[x].s&(~RLSB))-1;z>=0;z--)
227     {
228      *(uint8*)sf[x].v=fgetc(st);
229     }
230    else
231     fread((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
232    #endif
233   }
234  }
235  if(stateversion<56)
236  {
237   for(x=0;x<16;x++)
238    #ifdef LSB_FIRST
239    mapbyte1[x]=mapbyte1[x<<1];
240    #else
241    mapbyte1[x]=mapbyte1[(x<<1)+1];
242    #endif
243   memcpy(mapbyte3,tmpyo,16);
244  }
245  return 1;
246 }
247
248 int ReadStateChunks(FILE *st)
249 {
250  int t;
251  uint32 size;
252  int ret=1;
253
254 for(;;)
255  {
256   t=fgetc(st);
257   if(t==EOF) break;
258   if(!read32(&size,st)) break;
259   switch(t)
260   {
261    case 1:if(!ReadStateChunk(st,SFCPU,SFCPUELEMENTS,size)) ret=0;
262 #ifdef ASM_6502
263           asmcpu_unpack();
264 #endif
265           break;
266    case 2:if(!ReadStateChunk(st,SFCPUC,SFCPUCELEMENTS,size)) ret=0;
267           else
268           {
269            X.mooPI=X.P; // Quick and dirty hack.
270           }
271           break;
272    case 3:if(!ReadStateChunk(st,SFPPU,SFPPUELEMENTS,size)) ret=0;break;
273 //   case 4:if(!ReadStateChunk(st,SFCTLR,SFCTLRELEMENTS,size)) ret=0;break;
274    case 5:if(!ReadStateChunk(st,SFSND,SFSNDELEMENTS,size)) ret=0;break;
275    case 0x10:if(!ReadStateChunk(st,SFMDATA,SFEXINDEX,size)) ret=0;break;
276    default: if(fseek(st,size,SEEK_CUR)<0) goto endo;break;
277   }
278  }
279  endo:
280  return ret;
281 }
282
283
284 int CurrentState=0;
285 extern int geniestage;
286 void SaveState(void)
287 {
288         FILE *st=NULL;
289
290         TempAddrT=TempAddr;
291         RefreshAddrT=RefreshAddr;
292
293         if(geniestage==1)
294         {
295          FCEU_DispMessage("Cannot save FCS in GG screen.");
296          return;
297         }
298
299          st=fopen(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"wb");
300
301          if(st!=NULL)
302          {
303           static uint32 totalsize;
304           static uint8 header[16]="FCS";
305           memset(header+4,0,13);
306           header[3]=VERSION_NUMERIC;
307           fwrite(header,1,16,st);
308
309 #ifdef ASM_6502
310           asmcpu_pack();
311 #endif
312           totalsize=WriteStateChunk(st,1,SFCPU,SFCPUELEMENTS);
313           totalsize+=WriteStateChunk(st,2,SFCPUC,SFCPUCELEMENTS);
314           totalsize+=WriteStateChunk(st,3,SFPPU,SFPPUELEMENTS);
315         //  totalsize+=WriteStateChunk(st,4,SFCTLR,SFCTLRELEMENTS);
316           totalsize+=WriteStateChunk(st,5,SFSND,SFSNDELEMENTS);
317           totalsize+=WriteStateChunk(st,0x10,SFMDATA,SFEXINDEX);
318
319           fseek(st,4,SEEK_SET);
320           write32(totalsize,st);
321           SaveStateStatus[CurrentState]=1;
322           fclose(st);
323 #ifdef GP2X
324           sync();
325 #endif
326           FCEU_DispMessage("State %d saved.",CurrentState);
327          }
328          else
329           FCEU_DispMessage("State %d save error.",CurrentState);
330 }
331
332 static int LoadStateOld(FILE *st);
333 int FCEUSS_LoadFP(FILE *st, int make_backup)
334 {
335         int x;
336         if(st!=NULL)
337         {
338          uint8 header[16];
339
340          fread(&header,1,16,st);
341          if(memcmp(header,"FCS",3))
342          {
343           fseek(st,0,SEEK_SET);
344           if(!LoadStateOld(st))
345            goto lerror;
346           goto okload;
347          }
348          stateversion=header[3];
349          if(stateversion<53)
350          FixOldSaveStateSFreq();
351          x=ReadStateChunks(st);
352          if(GameStateRestore) GameStateRestore(header[3]);
353          if(x)
354          {
355           okload:
356           TempAddr=TempAddrT;
357           RefreshAddr=RefreshAddrT;
358
359           SaveStateStatus[CurrentState]=1;
360           FCEU_DispMessage("State %d loaded.",CurrentState);
361           SaveStateStatus[CurrentState]=1;
362          }
363          else
364          {
365           SaveStateStatus[CurrentState]=1;
366           FCEU_DispMessage("Error(s) reading state %d!",CurrentState);
367          }
368         }
369         else
370         {
371          lerror:
372          FCEU_DispMessage("State %d load error.",CurrentState);
373          SaveStateStatus[CurrentState]=0;
374          return 0;
375         }
376         return 1;
377 }
378
379 void LoadState(void)
380 {
381         FILE *st=NULL;
382
383         if(geniestage==1)
384         {
385          FCEU_DispMessage("Cannot load FCS in GG screen.");
386          return;
387         }
388
389         st=fopen(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"rb");
390         if (st)
391         {
392          FCEUSS_LoadFP(st, 0);
393          fclose(st);
394         }
395 }
396
397 char SaveStateStatus[10];
398 void CheckStates(void)
399 {
400         FILE *st=NULL;
401         int ssel;
402
403         if(SaveStateStatus[0]==(char)-1)
404          for(ssel=0;ssel<10;ssel++)
405          {
406           st=fopen(FCEU_MakeFName(FCEUMKF_STATE,ssel,0),"rb");
407           if(st)
408           {
409            SaveStateStatus[ssel]=1;
410            fclose(st);
411           }
412           else
413            SaveStateStatus[ssel]=0;
414          }
415 }
416
417 void SaveStateRefresh(void)
418 {
419  SaveStateStatus[0]=-1;
420 }
421
422 void ResetExState(void)
423 {
424  int x;
425  for(x=0;x<SFEXINDEX;x++)
426   free(SFMDATA[x].desc);
427  SFEXINDEX=0;
428 }
429
430 void AddExState(void *v, uint32 s, int type, char *desc)
431 {
432  SFMDATA[SFEXINDEX].desc=FCEU_malloc(5);
433  if(SFMDATA[SFEXINDEX].desc)
434  {
435   strcpy(SFMDATA[SFEXINDEX].desc,desc);
436   SFMDATA[SFEXINDEX].v=v;
437   SFMDATA[SFEXINDEX].s=s;
438   if(type) SFMDATA[SFEXINDEX].s|=RLSB;
439   if(SFEXINDEX<63) SFEXINDEX++;
440  }
441 }
442
443 /* Old state loading code follows */
444
445 uint8 *StateBuffer;
446 unsigned int intostate;
447
448 static void afread(void *ptr, size_t _size, size_t _nelem)
449 {
450         memcpy(ptr,StateBuffer+intostate,_size*_nelem);
451         intostate+=_size*_nelem;
452 }
453
454
455 static void areadlower8of16(int8 *d)
456 {
457 #ifdef LSB_FIRST
458         *d=StateBuffer[intostate++];
459 #else
460         d[1]=StateBuffer[intostate++];
461 #endif
462 }
463
464
465 static void areadupper8of16(int8 *d)
466 {
467 #ifdef LSB_FIRST
468         d[1]=StateBuffer[intostate++];
469 #else
470         *d=StateBuffer[intostate++];
471 #endif
472 }
473
474
475 static void aread16(int8 *d)
476 {
477 #ifdef LSB_FIRST
478         *d=StateBuffer[intostate++];
479         d[1]=StateBuffer[intostate++];
480 #else
481         d[1]=StateBuffer[intostate++];
482         *d=StateBuffer[intostate++];
483 #endif
484 }
485
486
487 static void aread32(int8 *d)
488 {
489 #ifdef LSB_FIRST
490         *d=StateBuffer[intostate++];
491         d[1]=StateBuffer[intostate++];
492         d[2]=StateBuffer[intostate++];
493         d[3]=StateBuffer[intostate++];
494 #else
495         d[3]=StateBuffer[intostate++];
496         d[2]=StateBuffer[intostate++];
497         d[1]=StateBuffer[intostate++];
498         *d=StateBuffer[intostate++];
499 #endif
500 }
501
502 static int LoadStateOld(FILE *st)
503 {
504         int x;
505         int32 nada;
506         uint8 version;
507         nada=0;
508
509         StateBuffer=FCEU_malloc(59999);
510         if(StateBuffer==NULL)
511          return 0;
512         if(!fread(StateBuffer,59999,1,st))
513         {
514             fclose(st);
515             free(StateBuffer);
516             return 0;
517         }
518
519         intostate=0;
520
521         {
522          uint8 a[2];
523          afread(&a[0],1,1);
524          afread(&a[1],1,1);
525          X.PC=a[0]|(a[1]<<8);
526         }
527         afread(&X.A,1,1);
528         afread(&X.P,1,1);
529         afread(&X.X,1,1);
530         afread(&X.Y,1,1);
531         afread(&X.S,1,1);
532         afread(&version,1,1);
533         afread(&nada,1,1);
534         afread(&nada,1,1);
535         afread(&nada,1,1);
536         afread(&nada,1,1);
537         aread32((int8 *)&X.count);
538         afread(&nada,1,1);
539         afread(&nada,1,1);
540         afread(&nada,1,1);
541         afread(&nada,1,1);
542         aread32((int8 *)&nada);
543         afread(&nada,1,1);
544         afread(&nada,1,1);
545         afread(&nada,1,1);
546         afread(&nada,1,1);
547
548         for(x=0;x<8;x++)
549                 areadupper8of16((int8 *)&CHRBankList[x]);
550         afread(PRGBankList,4,1);
551         for(x=0;x<8;x++)
552                 areadlower8of16((int8 *)&CHRBankList[x]);
553         afread(CHRRAM,1,0x2000);
554         afread(NTARAM,1,0x400);
555         afread(ExtraNTARAM,1,0x400);
556         afread(NTARAM+0x400,1,0x400);
557         afread(ExtraNTARAM+0x400,1,0x400);
558
559         for(x=0;x<0xF00;x++)
560          afread(&nada,1,1);
561         afread(PALRAM,1,0x20);
562         for(x=0;x<256-32;x++)
563          afread(&nada,1,1);
564         for(x=0x00;x<0x20;x++)
565          PALRAM[x]&=0x3f;
566         afread(PPU,1,4);
567         afread(SPRAM,1,0x100);
568         afread(WRAM,1,8192);
569         afread(RAM,1,0x800);
570         aread16((int8 *)&scanline);
571         aread16((int8 *)&RefreshAddr);
572         afread(&VRAMBuffer,1,1);
573
574         afread(&IRQa,1,1);
575         aread32((int8 *)&IRQCount);
576         aread32((int8 *)&IRQLatch);
577         afread(&Mirroring,1,1);
578         afread(PSG,1,0x17);
579         PSG[0x11]&=0x7F;
580         afread(MapperExRAM,1,193);
581         if(version>=31)
582          PSG[0x17]=MapperExRAM[115];
583         else
584          PSG[0x17]|=0x40;
585         PSG[0x15]&=0xF;
586         sqnon=PSG[0x15];
587
588         X.IRQlow=0;
589         afread(&nada,1,1);
590         afread(&nada,1,1);
591         afread(&nada,1,1);
592         afread(&nada,1,1);
593         afread(&nada,1,1);
594         afread(&nada,1,1);
595         afread(&XOffset,1,1);
596         PPUCHRRAM=0;
597         for(x=0;x<8;x++)
598         {
599          nada=0;
600          afread(&nada,1,1);
601          PPUCHRRAM|=(nada?1:0)<<x;
602         }
603
604          afread(mapbyte1,1,8);
605          afread(mapbyte2,1,8);
606          afread(mapbyte3,1,8);
607          afread(mapbyte4,1,8);
608          for(x=0;x<4;x++)
609           aread16((int8 *)&nada);
610
611          PPUNTARAM=0;
612          for(x=0;x<4;x++)
613          {
614           nada=0;
615           aread16((int8 *)&nada);
616           PPUNTARAM|=((nada&0x800)?0:1)<<x;
617          }
618          afread(MapperExRAM,1,32768);
619          afread(&vtoggle,1,1);
620          aread16((int8 *)&TempAddrT);
621          aread16((int8 *)&RefreshAddrT);
622
623          if(GameStateRestore) GameStateRestore(version);
624          free(StateBuffer);
625          FixOldSaveStateSFreq();
626          X.mooPI=X.P;
627          return 1;
628 }
629