src/gb/serialize.h (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef GB_SERIALIZE_H
7#define GB_SERIALIZE_H
8
9#include "util/common.h"
10
11#include "core/core.h"
12#include "gb/gb.h"
13
14extern const uint32_t GB_SAVESTATE_MAGIC;
15extern const uint32_t GB_SAVESTATE_VERSION;
16
17mLOG_DECLARE_CATEGORY(GB_STATE);
18
19/* Savestate format:
20 * 0x00000 - 0x00003: Version Magic (0x01000001)
21 * 0x00004 - 0x00007: ROM CRC32
22 * 0x00008: Game Boy model
23 * 0x00009 - 0x0000F: Reserved (leave zero)
24 * 0x00010 - 0x0001F: Game title/code (e.g. PM_CRYSTALBYTE)
25 * 0x00020 - 0x00047: CPU state:
26 * | 0x00020: A register
27 * | 0x00021: F register
28 * | 0x00022: B register
29 * | 0x00023: C register
30 * | 0x00024: D register
31 * | 0x00025: E register
32 * | 0x00026: H register
33 * | 0x00027: L register
34 * | 0x00028 - 0z00029: SP register
35 * | 0x0002A - 0z0002B: PC register
36 * | 0x0002C - 0x0002F: Cycles since last event
37 * | 0x00030 - 0x00033: Cycles until next event
38 * | 0x00034 - 0x00035: Reserved (current instruction)
39 * | 0x00036 - 0x00037: Index address
40 * | 0x00038: Bus value
41 * | 0x00039: Execution state
42 * | 0x0003A - 0x0003B: IRQ vector
43 * | 0x0003C - 0x0003F: EI pending cycles
44 * | 0x00040 - 0x00043: Reserved (DI pending cycles)
45 * | 0x00044 - 0x00048: Flags
46 * 0x00048 - 0x0005B: Audio channel 1/framer state
47 * | 0x00048 - 0x0004B: Envelepe timing
48 * | bits 0 - 6: Remaining length
49 * | bits 7 - 9: Next step
50 * | bits 10 - 20: Shadow frequency register
51 * | bits 21 - 31: Reserved
52 * | 0x0004C - 0x0004F: Next frame
53 * | 0x00050 - 0x00057: Reserved
54 * | 0x00058 - 0x0005B: Next event
55 * 0x0005C - 0x0006B: Audio channel 2 state
56 * | 0x0005C - 0x0005F: Envelepe timing
57 * | bits 0 - 2: Remaining length
58 * | bits 3 - 5: Next step
59 * | bits 6 - 31: Reserved
60 * | 0x00060 - 0x00067: Reserved
61 * | 0x00068 - 0x0006B: Next event
62 * 0x0006C - 0x00093: Audio channel 3 state
63 * | 0x0006C - 0x0008B: Wave banks
64 * | 0x0008C - 0x0008D: Remaining length
65 * | 0x0008E - 0x0008F: Reserved
66 * | 0x00090 - 0x00093: Next event
67 * 0x00094 - 0x000A3: Audio channel 4 state
68 * | 0x00094 - 0x00097: Linear feedback shift register state
69 * | 0x00098 - 0x0009B: Envelepe timing
70 * | bits 0 - 2: Remaining length
71 * | bits 3 - 5: Next step
72 * | bits 6 - 31: Reserved
73 * | 0x00098 - 0x0009F: Reserved
74 * | 0x000A0 - 0x000A3: Next event
75 * 0x000A4 - 0x000B7: Audio miscellaneous state
76 * | TODO: Fix this, they're in big-endian order, but field is little-endian
77 * | 0x000A4: Channel 1 envelope state
78 * | bits 0 - 3: Current volume
79 * | bits 4 - 5: Is dead?
80 * | bit 6: Is high?
81 * | 0x000A5: Channel 2 envelope state
82 * | bits 0 - 3: Current volume
83 * | bits 4 - 5: Is dead?
84 * | bit 6: Is high?
85* | bits 7: Reserved
86 * | 0x000A6: Channel 4 envelope state
87 * | bits 0 - 3: Current volume
88 * | bits 4 - 5: Is dead?
89 * | bit 6: Is high?
90* | bits 7: Reserved
91 * | 0x000A7: Miscellaneous audio flags
92 * | bits 0 - 3: Current frame
93 * | bit 4: Is channel 1 sweep enabled?
94 * | bit 5: Has channel 1 sweep occurred?
95 * | bits 6 - 7: Reserved
96 * | 0x000A8 - 0x000AB: Next event
97 * | 0x000AC - 0x000AF: Event diff
98 * | 0x000B0 - 0x000B3: Next sample
99*/
100
101DECL_BITFIELD(GBSerializedAudioFlags, uint32_t);
102DECL_BITS(GBSerializedAudioFlags, Ch1Volume, 0, 4);
103DECL_BITS(GBSerializedAudioFlags, Ch1Dead, 4, 2);
104DECL_BIT(GBSerializedAudioFlags, Ch1Hi, 6);
105DECL_BITS(GBSerializedAudioFlags, Ch2Volume, 8, 4);
106DECL_BITS(GBSerializedAudioFlags, Ch2Dead, 12, 2);
107DECL_BIT(GBSerializedAudioFlags, Ch2Hi, 14);
108DECL_BITS(GBSerializedAudioFlags, Ch4Volume, 16, 4);
109DECL_BITS(GBSerializedAudioFlags, Ch4Dead, 20, 2);
110DECL_BITS(GBSerializedAudioFlags, Frame, 22, 3);
111DECL_BIT(GBSerializedAudioFlags, Ch1SweepEnabled, 25);
112DECL_BIT(GBSerializedAudioFlags, Ch1SweepOccurred, 26);
113
114DECL_BITFIELD(GBSerializedAudioEnvelope, uint32_t);
115DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7);
116DECL_BITS(GBSerializedAudioEnvelope, NextStep, 7, 3);
117DECL_BITS(GBSerializedAudioEnvelope, Frequency, 10, 11);
118
119struct GBSerializedPSGState {
120 struct {
121 GBSerializedAudioEnvelope envelope;
122 int32_t nextFrame;
123 int32_t reserved[2];
124 int32_t nextEvent;
125 } ch1;
126 struct {
127 GBSerializedAudioEnvelope envelope;
128 int32_t reserved[2];
129 int32_t nextEvent;
130 } ch2;
131 struct {
132 uint32_t wavebanks[8];
133 int16_t length;
134 int16_t reserved;
135 int32_t nextEvent;
136 } ch3;
137 struct {
138 int32_t lfsr;
139 GBSerializedAudioEnvelope envelope;
140 int32_t reserved;
141 int32_t nextEvent;
142 } ch4;
143};
144
145#pragma pack(push, 1)
146struct GBSerializedState {
147 uint32_t versionMagic;
148 uint32_t romCrc32;
149 uint8_t model;
150 uint8_t reservedHeader[7];
151
152 char title[16];
153
154 struct {
155 uint8_t a;
156 uint8_t f;
157 uint8_t b;
158 uint8_t c;
159 uint8_t d;
160 uint8_t e;
161 uint8_t h;
162 uint8_t l;
163 uint16_t sp;
164 uint16_t pc;
165
166 int32_t cycles;
167 int32_t nextEvent;
168
169 uint16_t reservedInstruction;
170 uint16_t index;
171 uint8_t bus;
172 uint8_t executionState;
173
174 uint16_t irqVector;
175
176 int32_t eiPending;
177 int32_t reservedDiPending;
178 bool condition : 1;
179 bool irqPending : 1;
180 bool doubleSpeed : 1;
181 } cpu;
182
183 struct {
184 struct GBSerializedPSGState psg;
185 GBSerializedAudioFlags flags;
186 int32_t nextEvent;
187 int32_t eventDiff;
188 int32_t nextSample;
189 } audio;
190
191 struct {
192 int16_t x;
193 int16_t ly;
194 int32_t nextEvent;
195 int32_t eventDiff;
196 int32_t nextMode;
197 int32_t dotCounter;
198 int32_t frameCounter;
199
200 uint8_t vramCurrentBank;
201
202 bool bcpIncrement : 1;
203 bool ocpIncrement : 1;
204 uint16_t bcpIndex;
205 uint16_t ocpIndex;
206
207 uint16_t palette[64];
208 } video;
209
210 struct {
211 int32_t nextEvent;
212 int32_t eventDiff;
213
214 int32_t nextDiv;
215 int32_t nextTima;
216 int32_t timaPeriod;
217 } timer;
218
219 struct {
220 uint16_t currentBank;
221 uint8_t wramCurrentBank;
222 uint8_t sramCurrentBank;
223
224 int32_t dmaNext;
225 uint16_t dmaSource;
226 uint16_t dmaDest;
227
228 int32_t hdmaNext;
229 uint16_t hdmaSource;
230 uint16_t hdmaDest;
231
232 uint16_t hdmaRemaining;
233 uint8_t dmaRemaining;
234 uint8_t rtcRegs[5];
235
236 union {
237 struct {
238 uint32_t mode;
239 } mbc1;
240 struct {
241 int8_t machineState;
242 GBMBC7Field field;
243 int8_t address;
244 uint8_t srBits;
245 uint32_t sr;
246 uint8_t command : 2;
247 bool writable : 1;
248 } mbc7;
249 struct {
250 uint8_t reserved[16];
251 } padding;
252 };
253
254 bool sramAccess : 1;
255 bool rtcAccess : 1;
256 bool rtcLatched : 1;
257 bool ime : 1;
258 bool isHdma : 1;
259 uint8_t activeRtcReg : 5;
260 } memory;
261
262 uint8_t io[GB_SIZE_IO];
263 uint8_t hram[GB_SIZE_HRAM];
264 uint8_t ie;
265
266 uint64_t creationUsec;
267
268 uint8_t oam[GB_SIZE_OAM];
269 uint8_t vram[GB_SIZE_VRAM];
270 uint8_t wram[GB_SIZE_WORKING_RAM];
271};
272#pragma pack(pop)
273
274#endif