1 #include "rockmacros.h"
13 #ifdef ROCKBOX_LITTLE_ENDIAN
16 #define LIL(x) ((x<<24)|((x&0xff00)<<8)|((x>>8)&0xff00)|(x>>24))
19 #define I1(s, p) { 1, s, p }
20 #define I2(s, p) { 2, s, p }
21 #define I4(s, p) { 4, s, p }
22 #define R(r) I1(#r, &R_##r)
23 #define NOSAVE { -1, "\0\0\0\0", 0 }
24 #define END { 0, "\0\0\0\0", 0 }
34 static int sramblock
, iramblock
, vramblock
;
35 static int hramofs
, hiofs
, palofs
, oamofs
, wavofs
;
58 I4("spd ", &cpu
.speed
),
59 I4("halt", &cpu
.halt
),
62 I4("lcdc", &cpu
.lcdc
),
65 I1("ints", &hw
.ilines
),
69 I4("mbcm", &mbc
.model
),
70 I4("romb", &mbc
.rombank
),
71 I4("ramb", &mbc
.rambank
),
72 I4("enab", &mbc
.enableram
),
73 I4("batt", &mbc
.batt
),
76 I4("rtcL", &rtc
.latch
),
77 I4("rtcC", &rtc
.carry
),
78 I4("rtcS", &rtc
.stop
),
84 I1("rtR8", &rtc
.regs
[0]),
85 I1("rtR9", &rtc
.regs
[1]),
86 I1("rtRA", &rtc
.regs
[2]),
87 I1("rtRB", &rtc
.regs
[3]),
88 I1("rtRC", &rtc
.regs
[4]),
90 I4("S1on", &snd
.ch
[0].on
),
91 I4("S1p ", &snd
.ch
[0].pos
),
92 I4("S1c ", &snd
.ch
[0].len
),
93 I4("S1ec", &snd
.ch
[0].enlen
),
94 I4("S1sc", &snd
.ch
[0].swlen
),
96 I4("S2on", &snd
.ch
[1].on
),
97 I4("S2p ", &snd
.ch
[1].pos
),
98 I4("S2c ", &snd
.ch
[1].len
),
99 I4("S2ec", &snd
.ch
[1].enlen
),
101 I4("S3on", &snd
.ch
[2].on
),
102 I4("S3p ", &snd
.ch
[2].pos
),
103 I4("S3c ", &snd
.ch
[2].len
),
105 I4("S4on", &snd
.ch
[3].on
),
106 I4("S4p ", &snd
.ch
[3].pos
),
107 I4("S4c ", &snd
.ch
[3].len
),
108 I4("S4ec", &snd
.ch
[3].enlen
),
110 I4("hdma", &hw
.hdma
),
112 I4("sram", &sramblock
),
113 I4("iram", &iramblock
),
114 I4("vram", &vramblock
),
119 /* NOSAVE is a special code to prevent the rest of the table
120 * from being saved, used to support old stuff for backwards
121 * compatibility... */
124 /* the following are obsolete as of 0x104 */
126 I4("hram", &hramofs
),
127 /* I4("gba ", &hw.gba), */
128 /* I4("S1sf", &snd.ch[0].swfreq), */
132 R(DIV
), R(TIMA
), R(TMA
), R(TAC
),
134 R(LCDC
), R(STAT
), R(LY
), R(LYC
),
135 R(SCX
), R(SCY
), R(WX
), R(WY
),
136 R(BGP
), R(OBP0
), R(OBP1
),
139 R(VBK
), R(SVBK
), R(KEY1
),
140 R(BCPS
), R(BCPD
), R(OCPS
), R(OCPD
),
142 R(NR10
), R(NR11
), R(NR12
), R(NR13
), R(NR14
),
143 R(NR21
), R(NR22
), R(NR23
), R(NR24
),
144 R(NR30
), R(NR31
), R(NR32
), R(NR33
), R(NR34
),
145 R(NR41
), R(NR42
), R(NR43
), R(NR44
),
146 R(NR50
), R(NR51
), R(NR52
),
148 I1("DMA1", &R_HDMA1
),
149 I1("DMA2", &R_HDMA2
),
150 I1("DMA3", &R_HDMA3
),
151 I1("DMA4", &R_HDMA4
),
152 I1("DMA5", &R_HDMA5
),
158 void loadstate(int fd
)
162 un32 (*header
)[2] = (un32 (*)[2])buf
;
164 int irl
= hw
.cgb
? 8 : 2;
165 int vrl
= hw
.cgb
? 4 : 2;
166 int srl
= mbc
.ramsize
<< 1;
169 ver
= hramofs
= hiofs
= palofs
= oamofs
= wavofs
= 0;
171 base_offset
= lseek(fd
, 0, SEEK_CUR
);
175 for (j
= 0; header
[j
][0]; j
++)
177 for (i
= 0; svars
[i
].ptr
; i
++)
179 if (header
[j
][0] != *(un32
*)svars
[i
].key
)
181 d
= LIL(header
[j
][1]);
182 switch (svars
[i
].len
)
185 *(byte
*)svars
[i
].ptr
= d
;
188 *(un16
*)svars
[i
].ptr
= d
;
191 *(un32
*)svars
[i
].ptr
= d
;
198 /* obsolete as of version 0x104 */
199 if (hramofs
) memcpy(ram
.hi
+128, buf
+hramofs
, 127);
200 if (wavofs
) memcpy(ram
.hi
+48, buf
+wavofs
, 16);
202 if (hiofs
) memcpy(ram
.hi
, buf
+hiofs
, sizeof ram
.hi
);
203 if (palofs
) memcpy(lcd
.pal
, buf
+palofs
, sizeof lcd
.pal
);
204 if (oamofs
) memcpy(lcd
.oam
.mem
, buf
+oamofs
, sizeof lcd
.oam
);
206 lseek(fd
, base_offset
+ (iramblock
<< 12), SEEK_SET
);
207 read(fd
,ram
.ibank
, 4096*irl
);
209 lseek(fd
, base_offset
+ (vramblock
<< 12), SEEK_SET
);
210 read(fd
,lcd
.vbank
, 4096*vrl
);
212 lseek(fd
, base_offset
+ (sramblock
<< 12), SEEK_SET
);
213 read(fd
,ram
.sbank
, 4096*srl
);
220 void savestate(int fd
)
224 un32 (*header
)[2] = (un32 (*)[2])buf
;
226 int irl
= hw
.cgb
? 8 : 2;
227 int vrl
= hw
.cgb
? 4 : 2;
228 int srl
= mbc
.ramsize
<< 1;
234 sramblock
= 1+irl
+vrl
;
238 memset(buf
, 0, sizeof buf
);
240 for (i
= 0; svars
[i
].len
> 0; i
++)
242 header
[i
][0] = *(un32
*)svars
[i
].key
;
243 switch (svars
[i
].len
)
246 d
= *(byte
*)svars
[i
].ptr
;
249 d
= *(un16
*)svars
[i
].ptr
;
252 d
= *(un32
*)svars
[i
].ptr
;
255 header
[i
][1] = LIL(d
);
257 header
[i
][0] = header
[i
][1] = 0;
259 memcpy(buf
+hiofs
, ram
.hi
, sizeof ram
.hi
);
260 memcpy(buf
+palofs
, lcd
.pal
, sizeof lcd
.pal
);
261 memcpy(buf
+oamofs
, lcd
.oam
.mem
, sizeof lcd
.oam
);
263 /* calculate base offset for output file */
264 /* (we'll seek relative to that from now on) */
265 base_offset
= lseek(fd
, 0, SEEK_CUR
);
268 lseek(fd
, base_offset
+ (iramblock
<< 12), SEEK_SET
);
269 write(fd
,ram
.ibank
, 4096*irl
);
271 lseek(fd
, base_offset
+ (vramblock
<< 12), SEEK_SET
);
272 write(fd
,lcd
.vbank
, 4096*vrl
);
274 lseek(fd
, base_offset
+ (sramblock
<< 12), SEEK_SET
);
275 write(fd
,ram
.sbank
, 4096*srl
);