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