all repos — mgba @ 74fc29fc68e7ae84f0c27130d1d98299434ce6f2

mGBA Game Boy Advance Emulator

src/gba/hardware.c (view raw)

  1/* Copyright (c) 2013-2015 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#include "hardware.h"
  7
  8#include "gba/io.h"
  9#include "gba/serialize.h"
 10#include "util/formatting.h"
 11#include "util/hash.h"
 12
 13const int GBA_LUX_LEVELS[10] = { 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 };
 14
 15static void _readPins(struct GBACartridgeHardware* hw);
 16static void _outputPins(struct GBACartridgeHardware* hw, unsigned pins);
 17
 18static void _rtcReadPins(struct GBACartridgeHardware* hw);
 19static unsigned _rtcOutput(struct GBACartridgeHardware* hw);
 20static void _rtcProcessByte(struct GBACartridgeHardware* hw);
 21static void _rtcUpdateClock(struct GBACartridgeHardware* hw);
 22static unsigned _rtcBCD(unsigned value);
 23
 24static time_t _rtcGenericCallback(struct mRTCSource* source);
 25
 26static void _gyroReadPins(struct GBACartridgeHardware* hw);
 27
 28static void _rumbleReadPins(struct GBACartridgeHardware* hw);
 29
 30static void _lightReadPins(struct GBACartridgeHardware* hw);
 31
 32static uint16_t _gbpRead(struct mKeyCallback*);
 33static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
 34static int32_t _gbpSioProcessEvents(struct GBASIODriver* driver, int32_t cycles);
 35
 36static const int RTC_BYTES[8] = {
 37	0, // Force reset
 38	0, // Empty
 39	7, // Date/Time
 40	0, // Force IRQ
 41	1, // Control register
 42	0, // Empty
 43	3, // Time
 44	0 // Empty
 45};
 46
 47void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) {
 48	hw->gpioBase = base;
 49	GBAHardwareClear(hw);
 50
 51	hw->gbpCallback.d.readKeys = _gbpRead;
 52	hw->gbpCallback.p = hw;
 53	hw->gbpDriver.d.init = 0;
 54	hw->gbpDriver.d.deinit = 0;
 55	hw->gbpDriver.d.load = 0;
 56	hw->gbpDriver.d.unload = 0;
 57	hw->gbpDriver.d.writeRegister = _gbpSioWriteRegister;
 58	hw->gbpDriver.d.processEvents = _gbpSioProcessEvents;
 59	hw->gbpDriver.p = hw;
 60}
 61
 62void GBAHardwareClear(struct GBACartridgeHardware* hw) {
 63	hw->devices = HW_NONE | (hw->devices & HW_GB_PLAYER_DETECTION);
 64	hw->direction = GPIO_WRITE_ONLY;
 65	hw->pinState = 0;
 66	hw->direction = 0;
 67
 68	if (hw->p->sio.drivers.normal == &hw->gbpDriver.d) {
 69		GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32);
 70	}
 71}
 72
 73void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) {
 74	switch (address) {
 75	case GPIO_REG_DATA:
 76		hw->pinState &= ~hw->direction;
 77		hw->pinState |= value;
 78		_readPins(hw);
 79		break;
 80	case GPIO_REG_DIRECTION:
 81		hw->direction = value;
 82		break;
 83	case GPIO_REG_CONTROL:
 84		hw->readWrite = value;
 85		break;
 86	default:
 87		GBALog(hw->p, GBA_LOG_WARN, "Invalid GPIO address");
 88	}
 89	if (hw->readWrite) {
 90		uint16_t old;
 91		LOAD_16(old, 0, hw->gpioBase);
 92		old &= ~hw->direction;
 93		old |= hw->pinState;
 94		STORE_16(old, 0, hw->gpioBase);
 95	} else {
 96		hw->gpioBase[0] = 0;
 97	}
 98}
 99
100void GBAHardwareInitRTC(struct GBACartridgeHardware* hw) {
101	hw->devices |= HW_RTC;
102	hw->rtc.bytesRemaining = 0;
103
104	hw->rtc.transferStep = 0;
105
106	hw->rtc.bitsRead = 0;
107	hw->rtc.bits = 0;
108	hw->rtc.commandActive = 0;
109	hw->rtc.command = 0;
110	hw->rtc.control = 0x40;
111	memset(hw->rtc.time, 0, sizeof(hw->rtc.time));
112}
113
114void _readPins(struct GBACartridgeHardware* hw) {
115	if (hw->devices & HW_RTC) {
116		_rtcReadPins(hw);
117	}
118
119	if (hw->devices & HW_GYRO) {
120		_gyroReadPins(hw);
121	}
122
123	if (hw->devices & HW_RUMBLE) {
124		_rumbleReadPins(hw);
125	}
126
127	if (hw->devices & HW_LIGHT_SENSOR) {
128		_lightReadPins(hw);
129	}
130}
131
132void _outputPins(struct GBACartridgeHardware* hw, unsigned pins) {
133	if (hw->readWrite) {
134		uint16_t old;
135		LOAD_16(old, 0, hw->gpioBase);
136		old &= hw->direction;
137		hw->pinState = old | (pins & ~hw->direction & 0xF);
138		STORE_16(hw->pinState, 0, hw->gpioBase);
139	}
140}
141
142// == RTC
143
144void _rtcReadPins(struct GBACartridgeHardware* hw) {
145	// Transfer sequence:
146	// P: 0 | 1 |  2 | 3
147	// == Initiate
148	// > HI | - | LO | -
149	// > HI | - | HI | -
150	// == Transfer bit (x8)
151	// > LO | x | HI | -
152	// > HI | - | HI | -
153	// < ?? | x | ?? | -
154	// == Terminate
155	// >  - | - | LO | -
156	switch (hw->rtc.transferStep) {
157	case 0:
158		if ((hw->pinState & 5) == 1) {
159			hw->rtc.transferStep = 1;
160		}
161		break;
162	case 1:
163		if ((hw->pinState & 5) == 5) {
164			hw->rtc.transferStep = 2;
165		}
166		break;
167	case 2:
168		if (!(hw->pinState & 1)) {
169			hw->rtc.bits &= ~(1 << hw->rtc.bitsRead);
170			hw->rtc.bits |= ((hw->pinState & 2) >> 1) << hw->rtc.bitsRead;
171		} else {
172			if (hw->pinState & 4) {
173				// GPIO direction should always != reading
174				if (hw->direction & 2) {
175					if (RTCCommandDataIsReading(hw->rtc.command)) {
176						GBALog(hw->p, GBA_LOG_GAME_ERROR, "Attempting to write to RTC while in read mode");
177					}
178					++hw->rtc.bitsRead;
179					if (hw->rtc.bitsRead == 8) {
180						_rtcProcessByte(hw);
181					}
182				} else {
183					_outputPins(hw, 5 | (_rtcOutput(hw) << 1));
184					++hw->rtc.bitsRead;
185					if (hw->rtc.bitsRead == 8) {
186						--hw->rtc.bytesRemaining;
187						if (hw->rtc.bytesRemaining <= 0) {
188							hw->rtc.commandActive = 0;
189							hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command);
190						}
191						hw->rtc.bitsRead = 0;
192					}
193				}
194			} else {
195				hw->rtc.bitsRead = 0;
196				hw->rtc.bytesRemaining = 0;
197				hw->rtc.commandActive = 0;
198				hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command);
199				hw->rtc.transferStep = 0;
200			}
201		}
202		break;
203	}
204}
205
206void _rtcProcessByte(struct GBACartridgeHardware* hw) {
207	--hw->rtc.bytesRemaining;
208	if (!hw->rtc.commandActive) {
209		RTCCommandData command;
210		command = hw->rtc.bits;
211		if (RTCCommandDataGetMagic(command) == 0x06) {
212			hw->rtc.command = command;
213
214			hw->rtc.bytesRemaining = RTC_BYTES[RTCCommandDataGetCommand(command)];
215			hw->rtc.commandActive = hw->rtc.bytesRemaining > 0;
216			switch (RTCCommandDataGetCommand(command)) {
217			case RTC_RESET:
218				hw->rtc.control = 0;
219				break;
220			case RTC_DATETIME:
221			case RTC_TIME:
222				_rtcUpdateClock(hw);
223				break;
224			case RTC_FORCE_IRQ:
225			case RTC_CONTROL:
226				break;
227			}
228		} else {
229			GBALog(hw->p, GBA_LOG_WARN, "Invalid RTC command byte: %02X", hw->rtc.bits);
230		}
231	} else {
232		switch (RTCCommandDataGetCommand(hw->rtc.command)) {
233		case RTC_CONTROL:
234			hw->rtc.control = hw->rtc.bits;
235			break;
236		case RTC_FORCE_IRQ:
237			GBALog(hw->p, GBA_LOG_STUB, "Unimplemented RTC command %u", RTCCommandDataGetCommand(hw->rtc.command));
238			break;
239		case RTC_RESET:
240		case RTC_DATETIME:
241		case RTC_TIME:
242			break;
243		}
244	}
245
246	hw->rtc.bits = 0;
247	hw->rtc.bitsRead = 0;
248	if (!hw->rtc.bytesRemaining) {
249		hw->rtc.commandActive = 0;
250		hw->rtc.command = RTCCommandDataClearReading(hw->rtc.command);
251	}
252}
253
254unsigned _rtcOutput(struct GBACartridgeHardware* hw) {
255	uint8_t outputByte = 0;
256	switch (RTCCommandDataGetCommand(hw->rtc.command)) {
257	case RTC_CONTROL:
258		outputByte = hw->rtc.control;
259		break;
260	case RTC_DATETIME:
261	case RTC_TIME:
262		outputByte = hw->rtc.time[7 - hw->rtc.bytesRemaining];
263		break;
264	case RTC_FORCE_IRQ:
265	case RTC_RESET:
266		break;
267	}
268	unsigned output = (outputByte >> hw->rtc.bitsRead) & 1;
269	return output;
270}
271
272void _rtcUpdateClock(struct GBACartridgeHardware* hw) {
273	time_t t;
274	struct mRTCSource* rtc = hw->p->rtcSource;
275	if (rtc) {
276		if (rtc->sample) {
277			rtc->sample(rtc);
278		}
279		t = rtc->unixTime(rtc);
280	} else {
281		t = time(0);
282	}
283	struct tm date;
284	localtime_r(&t, &date);
285	hw->rtc.time[0] = _rtcBCD(date.tm_year - 100);
286	hw->rtc.time[1] = _rtcBCD(date.tm_mon + 1);
287	hw->rtc.time[2] = _rtcBCD(date.tm_mday);
288	hw->rtc.time[3] = _rtcBCD(date.tm_wday);
289	if (RTCControlIsHour24(hw->rtc.control)) {
290		hw->rtc.time[4] = _rtcBCD(date.tm_hour);
291	} else {
292		hw->rtc.time[4] = _rtcBCD(date.tm_hour % 12);
293	}
294	hw->rtc.time[5] = _rtcBCD(date.tm_min);
295	hw->rtc.time[6] = _rtcBCD(date.tm_sec);
296}
297
298unsigned _rtcBCD(unsigned value) {
299	int counter = value % 10;
300	value /= 10;
301	counter += (value % 10) << 4;
302	return counter;
303}
304
305time_t _rtcGenericCallback(struct mRTCSource* source) {
306	struct GBARTCGenericSource* rtc = (struct GBARTCGenericSource*) source;
307	switch (rtc->override) {
308	case RTC_NO_OVERRIDE:
309	default:
310		return time(0);
311	case RTC_FIXED:
312		return rtc->value;
313	case RTC_FAKE_EPOCH:
314		return rtc->value + rtc->p->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY;
315	}
316}
317
318void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba) {
319	rtc->p = gba;
320	rtc->override = RTC_NO_OVERRIDE;
321	rtc->value = 0;
322	rtc->d.sample = 0;
323	rtc->d.unixTime = _rtcGenericCallback;
324}
325
326// == Gyro
327
328void GBAHardwareInitGyro(struct GBACartridgeHardware* hw) {
329	hw->devices |= HW_GYRO;
330	hw->gyroSample = 0;
331	hw->gyroEdge = 0;
332}
333
334void _gyroReadPins(struct GBACartridgeHardware* hw) {
335	struct mRotationSource* gyro = hw->p->rotationSource;
336	if (!gyro || !gyro->readGyroZ) {
337		return;
338	}
339
340	if (hw->pinState & 1) {
341		if (gyro->sample) {
342			gyro->sample(gyro);
343		}
344		int32_t sample = gyro->readGyroZ(gyro);
345
346		// Normalize to ~12 bits, focused on 0x6C0
347		hw->gyroSample = (sample >> 21) + 0x6C0; // Crop off an extra bit so that we can't go negative
348	}
349
350	if (hw->gyroEdge && !(hw->pinState & 2)) {
351		// Write bit on falling edge
352		unsigned bit = hw->gyroSample >> 15;
353		hw->gyroSample <<= 1;
354		_outputPins(hw, bit << 2);
355	}
356
357	hw->gyroEdge = !!(hw->pinState & 2);
358}
359
360// == Rumble
361
362void GBAHardwareInitRumble(struct GBACartridgeHardware* hw) {
363	hw->devices |= HW_RUMBLE;
364}
365
366void _rumbleReadPins(struct GBACartridgeHardware* hw) {
367	struct mRumble* rumble = hw->p->rumble;
368	if (!rumble) {
369		return;
370	}
371
372	rumble->setRumble(rumble, !!(hw->pinState & 8));
373}
374
375// == Light sensor
376
377void GBAHardwareInitLight(struct GBACartridgeHardware* hw) {
378	hw->devices |= HW_LIGHT_SENSOR;
379	hw->lightCounter = 0;
380	hw->lightEdge = false;
381	hw->lightSample = 0xFF;
382}
383
384void _lightReadPins(struct GBACartridgeHardware* hw) {
385	if (hw->pinState & 4) {
386		// Boktai chip select
387		return;
388	}
389	if (hw->pinState & 2) {
390		struct GBALuminanceSource* lux = hw->p->luminanceSource;
391		GBALog(hw->p, GBA_LOG_DEBUG, "[SOLAR] Got reset");
392		hw->lightCounter = 0;
393		if (lux) {
394			lux->sample(lux);
395			hw->lightSample = lux->readLuminance(lux);
396		} else {
397			hw->lightSample = 0xFF;
398		}
399	}
400	if ((hw->pinState & 1) && hw->lightEdge) {
401		++hw->lightCounter;
402	}
403	hw->lightEdge = !(hw->pinState & 1);
404
405	bool sendBit = hw->lightCounter >= hw->lightSample;
406	_outputPins(hw, sendBit << 3);
407	GBALog(hw->p, GBA_LOG_DEBUG, "[SOLAR] Output %u with pins %u", hw->lightCounter, hw->pinState);
408}
409
410// == Tilt
411
412void GBAHardwareInitTilt(struct GBACartridgeHardware* hw) {
413	hw->devices |= HW_TILT;
414	hw->tiltX = 0xFFF;
415	hw->tiltY = 0xFFF;
416	hw->tiltState = 0;
417}
418
419void GBAHardwareTiltWrite(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value) {
420	switch (address) {
421	case 0x8000:
422		if (value == 0x55) {
423			hw->tiltState = 1;
424		} else {
425			GBALog(hw->p, GBA_LOG_GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
426		}
427		break;
428	case 0x8100:
429		if (value == 0xAA && hw->tiltState == 1) {
430			hw->tiltState = 0;
431			struct mRotationSource* rotationSource = hw->p->rotationSource;
432			if (!rotationSource || !rotationSource->readTiltX || !rotationSource->readTiltY) {
433				return;
434			}
435			if (rotationSource->sample) {
436				rotationSource->sample(rotationSource);
437			}
438			int32_t x = rotationSource->readTiltX(rotationSource);
439			int32_t y = rotationSource->readTiltY(rotationSource);
440			// Normalize to ~12 bits, focused on 0x3A0
441			hw->tiltX = (x >> 21) + 0x3A0; // Crop off an extra bit so that we can't go negative
442			hw->tiltY = (y >> 21) + 0x3A0;
443		} else {
444			GBALog(hw->p, GBA_LOG_GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
445		}
446		break;
447	default:
448		GBALog(hw->p, GBA_LOG_GAME_ERROR, "Invalid tilt sensor write to %04x: %02x", address, value);
449		break;
450	}
451}
452
453uint8_t GBAHardwareTiltRead(struct GBACartridgeHardware* hw, uint32_t address) {
454	switch (address) {
455	case 0x8200:
456		return hw->tiltX & 0xFF;
457	case 0x8300:
458		return ((hw->tiltX >> 8) & 0xF) | 0x80;
459	case 0x8400:
460		return hw->tiltY & 0xFF;
461	case 0x8500:
462		return (hw->tiltY >> 8) & 0xF;
463	default:
464		GBALog(hw->p, GBA_LOG_GAME_ERROR, "Invalid tilt sensor read from %04x", address);
465		break;
466	}
467	return 0xFF;
468}
469
470// == Game Boy Player
471
472static const uint16_t _logoPalette[] = {
473	0xFFDF, 0x640C, 0xE40C, 0xE42D, 0x644E, 0xE44E, 0xE46E, 0x68AF,
474	0xE8B0, 0x68D0, 0x68F0, 0x6911, 0xE911, 0x6D32, 0xED32, 0xED73,
475	0x6D93, 0xED94, 0x6DB4, 0xF1D5, 0x71F5, 0xF1F6, 0x7216, 0x7257,
476	0xF657, 0x7678, 0xF678, 0xF699, 0xF6B9, 0x76D9, 0xF6DA, 0x7B1B,
477	0xFB1B, 0xFB3C, 0x7B5C, 0x7B7D, 0xFF7D, 0x7F9D, 0x7FBE, 0x7FFF,
478	0x642D, 0x648E, 0xE88F, 0xE8F1, 0x6D52, 0x6D73, 0xF1B4, 0xF216,
479	0x7237, 0x7698, 0x7AFA, 0xFAFA, 0xFB5C, 0xFFBE, 0x7FDE, 0xFFFF,
480	0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
481};
482
483static const uint32_t _logoHash = 0xEEDA6963;
484
485static const uint32_t _gbpTxData[] = {
486	0x0000494E, 0x0000494E,
487	0xB6B1494E, 0xB6B1544E,
488	0xABB1544E, 0xABB14E45,
489	0xB1BA4E45, 0xB1BA4F44,
490	0xB0BB4F44, 0xB0BB8002,
491	0x10000010, 0x20000013,
492	0x30000003
493};
494
495static const uint32_t _gbpRxData[] = {
496	0x00000000, 0x494EB6B1,
497	0x494EB6B1, 0x544EB6B1,
498	0x544EABB1, 0x4E45ABB1,
499	0x4E45B1BA, 0x4F44B1BA,
500	0x4F44B0BB, 0x8000B0BB,
501	0x10000010, 0x20000013,
502	0x40000004
503};
504
505bool GBAHardwarePlayerCheckScreen(const struct GBAVideo* video) {
506	if (memcmp(video->palette, _logoPalette, sizeof(_logoPalette)) != 0) {
507		return false;
508	}
509	uint32_t hash = hash32(&video->renderer->vram[0x4000], 0x4000, 0);
510	return hash == _logoHash;
511}
512
513void GBAHardwarePlayerUpdate(struct GBA* gba) {
514	if (gba->memory.hw.devices & HW_GB_PLAYER) {
515		if (GBAHardwarePlayerCheckScreen(&gba->video)) {
516			++gba->memory.hw.gbpInputsPosted;
517			gba->memory.hw.gbpInputsPosted %= 3;
518			gba->keyCallback = &gba->memory.hw.gbpCallback.d;
519		} else {
520			// TODO: Save and restore
521			gba->keyCallback = 0;
522		}
523		gba->memory.hw.gbpTxPosition = 0;
524		return;
525	}
526	if (gba->keyCallback || gba->sio.drivers.normal) {
527		return;
528	}
529	if (GBAHardwarePlayerCheckScreen(&gba->video)) {
530		gba->memory.hw.devices |= HW_GB_PLAYER;
531		gba->memory.hw.gbpInputsPosted = 0;
532		gba->memory.hw.gbpNextEvent = INT_MAX;
533		gba->keyCallback = &gba->memory.hw.gbpCallback.d;
534		GBASIOSetDriver(&gba->sio, &gba->memory.hw.gbpDriver.d, SIO_NORMAL_32);
535	}
536}
537
538uint16_t _gbpRead(struct mKeyCallback* callback) {
539	struct GBAGBPKeyCallback* gbpCallback = (struct GBAGBPKeyCallback*) callback;
540	if (gbpCallback->p->gbpInputsPosted == 2) {
541		return 0x30F;
542	}
543	return 0x3FF;
544}
545
546uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) {
547	struct GBAGBPSIODriver* gbp = (struct GBAGBPSIODriver*) driver;
548	if (address == REG_SIOCNT) {
549		if (value & 0x0080) {
550			uint32_t rx = gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] | (gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] << 16);
551			if (gbp->p->gbpTxPosition < 12 && gbp->p->gbpTxPosition > 0) {
552				uint32_t expected = _gbpRxData[gbp->p->gbpTxPosition];
553				// TODO: Check expected
554			} else if (gbp->p->gbpTxPosition >= 12) {
555				uint32_t mask = 0x33;
556				// 0x00 = Stop
557				// 0x11 = Hard Stop
558				// 0x22 = Start
559				if (gbp->p->p->rumble) {
560					gbp->p->p->rumble->setRumble(gbp->p->p->rumble, (rx & mask) == 0x22);
561				}
562			}
563			gbp->p->gbpNextEvent = 2048;
564		}
565		value &= 0x78FB;
566	}
567	return value;
568}
569
570int32_t _gbpSioProcessEvents(struct GBASIODriver* driver, int32_t cycles) {
571	struct GBAGBPSIODriver* gbp = (struct GBAGBPSIODriver*) driver;
572	gbp->p->gbpNextEvent -= cycles;
573	if (gbp->p->gbpNextEvent <= 0) {
574		uint32_t tx = 0;
575		if (gbp->p->gbpTxPosition <= 12) {
576			tx = _gbpTxData[gbp->p->gbpTxPosition];
577			if (gbp->p->gbpTxPosition < 12) {
578				++gbp->p->gbpTxPosition;
579			}
580		}
581		gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
582		gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
583		if (gbp->d.p->normalControl.irq) {
584			GBARaiseIRQ(gbp->p->p, IRQ_SIO);
585		}
586		gbp->d.p->normalControl.start = 0;
587		gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt;
588		gbp->p->gbpNextEvent = INT_MAX;
589	}
590	return gbp->p->gbpNextEvent;
591}
592
593// == Serialization
594
595void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASerializedState* state) {
596	GBASerializedHWFlags1 flags1 = 0;
597	GBASerializedHWFlags2 flags2 = 0;
598	flags1 = GBASerializedHWFlags1SetReadWrite(flags1, hw->readWrite);
599	STORE_16(hw->pinState, 0, &state->hw.pinState);
600	STORE_16(hw->direction, 0, &state->hw.pinDirection);
601	state->hw.devices = hw->devices;
602
603	STORE_32(hw->rtc.bytesRemaining, 0, &state->hw.rtc.bytesRemaining);
604	STORE_32(hw->rtc.transferStep, 0, &state->hw.rtc.transferStep);
605	STORE_32(hw->rtc.bitsRead, 0, &state->hw.rtc.bitsRead);
606	STORE_32(hw->rtc.bits, 0, &state->hw.rtc.bits);
607	STORE_32(hw->rtc.commandActive, 0, &state->hw.rtc.commandActive);
608	STORE_32(hw->rtc.command, 0, &state->hw.rtc.command);
609	STORE_32(hw->rtc.control, 0, &state->hw.rtc.control);
610	memcpy(state->hw.rtc.time, hw->rtc.time, sizeof(state->hw.rtc.time));
611
612	STORE_16(hw->gyroSample, 0, &state->hw.gyroSample);
613	flags1 = GBASerializedHWFlags1SetGyroEdge(flags1, hw->gyroEdge);
614	STORE_16(hw->tiltX, 0, &state->hw.tiltSampleX);
615	STORE_16(hw->tiltY, 0, &state->hw.tiltSampleY);
616	flags2 = GBASerializedHWFlags2SetTiltState(flags2, hw->tiltState);
617	flags2 = GBASerializedHWFlags1SetLightCounter(flags2, hw->lightCounter);
618	state->hw.lightSample = hw->lightSample;
619	flags1 = GBASerializedHWFlags1SetLightEdge(flags1, hw->lightEdge);
620	flags2 = GBASerializedHWFlags2SetGbpInputsPosted(flags2, hw->gbpInputsPosted);
621	flags2 = GBASerializedHWFlags2SetGbpTxPosition(flags2, hw->gbpTxPosition);
622	STORE_32(hw->gbpNextEvent, 0, &state->hw.gbpNextEvent);
623	STORE_16(flags1, 0, &state->hw.flags1);
624	state->hw.flags2 = flags2;
625}
626
627void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASerializedState* state) {
628	GBASerializedHWFlags1 flags1;
629	LOAD_16(flags1, 0, &state->hw.flags1);
630	hw->readWrite = GBASerializedHWFlags1GetReadWrite(flags1);
631	LOAD_16(hw->pinState, 0, &state->hw.pinState);
632	LOAD_16(hw->direction, 0, &state->hw.pinDirection);
633	hw->devices = state->hw.devices;
634
635	LOAD_32(hw->rtc.bytesRemaining, 0, &state->hw.rtc.bytesRemaining);
636	LOAD_32(hw->rtc.transferStep, 0, &state->hw.rtc.transferStep);
637	LOAD_32(hw->rtc.bitsRead, 0, &state->hw.rtc.bitsRead);
638	LOAD_32(hw->rtc.bits, 0, &state->hw.rtc.bits);
639	LOAD_32(hw->rtc.commandActive, 0, &state->hw.rtc.commandActive);
640	LOAD_32(hw->rtc.command, 0, &state->hw.rtc.command);
641	LOAD_32(hw->rtc.control, 0, &state->hw.rtc.control);
642	memcpy(hw->rtc.time, state->hw.rtc.time, sizeof(hw->rtc.time));
643
644	LOAD_16(hw->gyroSample, 0, &state->hw.gyroSample);
645	hw->gyroEdge = GBASerializedHWFlags1GetGyroEdge(flags1);
646	LOAD_16(hw->tiltX, 0, &state->hw.tiltSampleX);
647	LOAD_16(hw->tiltY, 0, &state->hw.tiltSampleY);
648	hw->tiltState = GBASerializedHWFlags2GetTiltState(state->hw.flags2);
649	hw->lightCounter = GBASerializedHWFlags1GetLightCounter(flags1);
650	hw->lightSample = state->hw.lightSample;
651	hw->lightEdge = GBASerializedHWFlags1GetLightEdge(flags1);
652	hw->gbpInputsPosted = GBASerializedHWFlags2GetGbpInputsPosted(state->hw.flags2);
653	hw->gbpTxPosition = GBASerializedHWFlags2GetGbpTxPosition(state->hw.flags2);
654	LOAD_32(hw->gbpNextEvent, 0, &state->hw.gbpNextEvent);
655	if (hw->devices & HW_GB_PLAYER) {
656		GBASIOSetDriver(&hw->p->sio, &hw->gbpDriver.d, SIO_NORMAL_32);
657	}
658}