all repos — mgba @ 1d021a72c7a1245adeceecd706dbebfb739f6247

mGBA Game Boy Advance Emulator

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