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