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 <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#define EREADER_BLOCK_SIZE 40
16#define EREADER_DOTCODE_STRIDE 1200
17#define EREADER_DOTCODE_SIZE (EREADER_DOTCODE_STRIDE * 40 + 200)
18
19mLOG_DEFINE_CATEGORY(GBA_HW, "GBA Pak Hardware", "gba.hardware");
20
21MGBA_EXPORT const int GBA_LUX_LEVELS[10] = { 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 };
22const uint16_t EREADER_ADDRESS_CODES[] = {
23 1023,
24 1174,
25 2628,
26 3373,
27 4233,
28 6112,
29 6450,
30 7771,
31 8826,
32 9491,
33 11201,
34 11432,
35 12556,
36 13925,
37 14519,
38 16350,
39 16629,
40 18332,
41 18766,
42 20007,
43 21379,
44 21738,
45 23096,
46 23889,
47 24944,
48 26137,
49 26827,
50 28578,
51 29190,
52 30063,
53 31677,
54 31956,
55 33410,
56 34283,
57 35641,
58 35920,
59 37364,
60 38557,
61 38991,
62 40742,
63 41735,
64 42094,
65 43708,
66 44501,
67 45169,
68 46872,
69 47562,
70 48803,
71 49544,
72 50913,
73 51251,
74 53082,
75 54014,
76 54679
77};
78
79const int EREADER_NYBBLE_5BIT[16][5] = {
80 { 0, 0, 0, 0, 0 },
81 { 0, 0, 0, 0, 1 },
82 { 0, 0, 0, 1, 0 },
83 { 1, 0, 0, 1, 0 },
84 { 0, 0, 1, 0, 0 },
85 { 0, 0, 1, 0, 1 },
86 { 0, 0, 1, 1, 0 },
87 { 1, 0, 1, 1, 0 },
88 { 0, 1, 0, 0, 0 },
89 { 0, 1, 0, 0, 1 },
90 { 0, 1, 0, 1, 0 },
91 { 1, 0, 1, 0, 0 },
92 { 0, 1, 1, 0, 0 },
93 { 0, 1, 1, 0, 1 },
94 { 1, 0, 0, 0, 1 },
95 { 1, 0, 0, 0, 0 }
96};
97
98const uint8_t EREADER_CALIBRATION_TEMPLATE[] = {
99 0x43, 0x61, 0x72, 0x64, 0x2d, 0x45, 0x20, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x32, 0x30,
100 0x30, 0x31, 0x00, 0x00, 0xcf, 0x72, 0x2f, 0x37, 0x3a, 0x3a, 0x3a, 0x38, 0x33, 0x30, 0x30, 0x37,
101 0x3a, 0x39, 0x37, 0x35, 0x33, 0x2f, 0x2f, 0x34, 0x36, 0x36, 0x37, 0x36, 0x34, 0x31, 0x2d, 0x30,
102 0x32, 0x34, 0x35, 0x35, 0x34, 0x30, 0x2a, 0x2d, 0x2d, 0x2f, 0x31, 0x32, 0x31, 0x2f, 0x29, 0x2a,
103 0x2c, 0x2b, 0x2c, 0x2e, 0x2e, 0x2d, 0x18, 0x2d, 0x8f, 0x03, 0x00, 0x00, 0xc0, 0xfd, 0x77, 0x00,
104 0x00, 0x00, 0x01
105};
106
107static void _readPins(struct GBACartridgeHardware* hw);
108static void _outputPins(struct GBACartridgeHardware* hw, unsigned pins);
109
110static void _rtcReadPins(struct GBACartridgeHardware* hw);
111static unsigned _rtcOutput(struct GBACartridgeHardware* hw);
112static void _rtcProcessByte(struct GBACartridgeHardware* hw);
113static void _rtcUpdateClock(struct GBACartridgeHardware* hw);
114static unsigned _rtcBCD(unsigned value);
115
116static time_t _rtcGenericCallback(struct mRTCSource* source);
117
118static void _gyroReadPins(struct GBACartridgeHardware* hw);
119
120static void _rumbleReadPins(struct GBACartridgeHardware* hw);
121
122static void _lightReadPins(struct GBACartridgeHardware* hw);
123
124static uint16_t _gbpRead(struct mKeyCallback*);
125static uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value);
126static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate);
127
128static void _eReaderReset(struct GBACartridgeHardware* hw);
129static void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value);
130static void _eReaderWriteControl1(struct GBACartridgeHardware* hw, uint8_t value);
131static void _eReaderReadData(struct GBACartridgeHardware* hw);
132
133static const int RTC_BYTES[8] = {
134 0, // Force reset
135 0, // Empty
136 7, // Date/Time
137 0, // Force IRQ
138 1, // Control register
139 0, // Empty
140 3, // Time
141 0 // Empty
142};
143
144void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) {
145 hw->gpioBase = base;
146 hw->eReaderDots = NULL;
147 GBAHardwareClear(hw);
148
149 hw->gbpCallback.d.readKeys = _gbpRead;
150 hw->gbpCallback.p = hw;
151 hw->gbpDriver.d.init = 0;
152 hw->gbpDriver.d.deinit = 0;
153 hw->gbpDriver.d.load = 0;
154 hw->gbpDriver.d.unload = 0;
155 hw->gbpDriver.d.writeRegister = _gbpSioWriteRegister;
156 hw->gbpDriver.p = hw;
157 hw->gbpNextEvent.context = &hw->gbpDriver;
158 hw->gbpNextEvent.name = "GBA SIO Game Boy Player";
159 hw->gbpNextEvent.callback = _gbpSioProcessEvents;
160 hw->gbpNextEvent.priority = 0x80;
161}
162
163void GBAHardwareClear(struct GBACartridgeHardware* hw) {
164 hw->devices = HW_NONE | (hw->devices & HW_GB_PLAYER_DETECTION);
165 hw->readWrite = GPIO_WRITE_ONLY;
166 hw->pinState = 0;
167 hw->direction = 0;
168
169 if (hw->eReaderDots) {
170 mappedMemoryFree(hw->eReaderDots, EREADER_DOTCODE_SIZE);
171 hw->eReaderDots = NULL;
172 }
173
174 if (hw->p->sio.drivers.normal == &hw->gbpDriver.d) {
175 GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32);
176 }
177}
178
179void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) {
180 if (!hw->gpioBase) {
181 return;
182 }
183 switch (address) {
184 case GPIO_REG_DATA:
185 hw->pinState &= ~hw->direction;
186 hw->pinState |= value & hw->direction;
187 _readPins(hw);
188 break;
189 case GPIO_REG_DIRECTION:
190 hw->direction = value;
191 break;
192 case GPIO_REG_CONTROL:
193 hw->readWrite = value;
194 break;
195 default:
196 mLOG(GBA_HW, WARN, "Invalid GPIO address");
197 }
198 if (hw->readWrite) {
199 STORE_16(hw->pinState, 0, hw->gpioBase);
200 STORE_16(hw->direction, 2, hw->gpioBase);
201 STORE_16(hw->readWrite, 4, hw->gpioBase);
202 } else {
203 hw->gpioBase[0] = 0;
204 hw->gpioBase[1] = 0;
205 hw->gpioBase[2] = 0;
206 }
207}
208
209void GBAHardwareInitRTC(struct GBACartridgeHardware* hw) {
210 hw->devices |= HW_RTC;
211 hw->rtc.bytesRemaining = 0;
212
213 hw->rtc.transferStep = 0;
214
215 hw->rtc.bitsRead = 0;
216 hw->rtc.bits = 0;
217 hw->rtc.commandActive = 0;
218 hw->rtc.command = 0;
219 hw->rtc.control = 0x40;
220 memset(hw->rtc.time, 0, sizeof(hw->rtc.time));
221}
222
223void _readPins(struct GBACartridgeHardware* hw) {
224 if (hw->devices & HW_RTC) {
225 _rtcReadPins(hw);
226 }
227
228 if (hw->devices & HW_GYRO) {
229 _gyroReadPins(hw);
230 }
231
232 if (hw->devices & HW_RUMBLE) {
233 _rumbleReadPins(hw);
234 }
235
236 if (hw->devices & HW_LIGHT_SENSOR) {
237 _lightReadPins(hw);
238 }
239}
240
241void _outputPins(struct GBACartridgeHardware* hw, unsigned pins) {
242 if (hw->readWrite) {
243 uint16_t old;
244 LOAD_16(old, 0, hw->gpioBase);
245 old &= hw->direction;
246 hw->pinState = old | (pins & ~hw->direction & 0xF);
247 STORE_16(hw->pinState, 0, hw->gpioBase);
248 }
249}
250
251// == RTC
252
253void _rtcReadPins(struct GBACartridgeHardware* hw) {
254 // Transfer sequence:
255 // P: 0 | 1 | 2 | 3
256 // == Initiate
257 // > HI | - | LO | -
258 // > HI | - | HI | -
259 // == Transfer bit (x8)
260 // > LO | x | HI | -
261 // > HI | - | HI | -
262 // < ?? | x | ?? | -
263 // == Terminate
264 // > - | - | LO | -
265 switch (hw->rtc.transferStep) {
266 case 0:
267 if ((hw->pinState & 5) == 1) {
268 hw->rtc.transferStep = 1;
269 }
270 break;
271 case 1:
272 if ((hw->pinState & 5) == 5) {
273 hw->rtc.transferStep = 2;
274 } else if ((hw->pinState & 5) != 1) {
275 hw->rtc.transferStep = 0;
276 }
277 break;
278 case 2:
279 if (!(hw->pinState & 1)) {
280 hw->rtc.bits &= ~(1 << hw->rtc.bitsRead);
281 hw->rtc.bits |= ((hw->pinState & 2) >> 1) << hw->rtc.bitsRead;
282 } else {
283 if (hw->pinState & 4) {
284 if (!RTCCommandDataIsReading(hw->rtc.command)) {
285 ++hw->rtc.bitsRead;
286 if (hw->rtc.bitsRead == 8) {
287 _rtcProcessByte(hw);
288 }
289 } else {
290 _outputPins(hw, 5 | (_rtcOutput(hw) << 1));
291 ++hw->rtc.bitsRead;
292 if (hw->rtc.bitsRead == 8) {
293 --hw->rtc.bytesRemaining;
294 if (hw->rtc.bytesRemaining <= 0) {
295 hw->rtc.commandActive = 0;
296 hw->rtc.command = 0;
297 }
298 hw->rtc.bitsRead = 0;
299 }
300 }
301 } else {
302 hw->rtc.bitsRead = 0;
303 hw->rtc.bytesRemaining = 0;
304 hw->rtc.commandActive = 0;
305 hw->rtc.command = 0;
306 hw->rtc.transferStep = hw->pinState & 1;
307 _outputPins(hw, 1);
308 }
309 }
310 break;
311 }
312}
313
314void _rtcProcessByte(struct GBACartridgeHardware* hw) {
315 --hw->rtc.bytesRemaining;
316 if (!hw->rtc.commandActive) {
317 RTCCommandData command;
318 command = hw->rtc.bits;
319 if (RTCCommandDataGetMagic(command) == 0x06) {
320 hw->rtc.command = command;
321
322 hw->rtc.bytesRemaining = RTC_BYTES[RTCCommandDataGetCommand(command)];
323 hw->rtc.commandActive = hw->rtc.bytesRemaining > 0;
324 switch (RTCCommandDataGetCommand(command)) {
325 case RTC_RESET:
326 hw->rtc.control = 0;
327 break;
328 case RTC_DATETIME:
329 case RTC_TIME:
330 _rtcUpdateClock(hw);
331 break;
332 case RTC_FORCE_IRQ:
333 case RTC_CONTROL:
334 break;
335 }
336 } else {
337 mLOG(GBA_HW, WARN, "Invalid RTC command byte: %02X", hw->rtc.bits);
338 }
339 } else {
340 switch (RTCCommandDataGetCommand(hw->rtc.command)) {
341 case RTC_CONTROL:
342 hw->rtc.control = hw->rtc.bits;
343 break;
344 case RTC_FORCE_IRQ:
345 mLOG(GBA_HW, STUB, "Unimplemented RTC command %u", RTCCommandDataGetCommand(hw->rtc.command));
346 break;
347 case RTC_RESET:
348 case RTC_DATETIME:
349 case RTC_TIME:
350 break;
351 }
352 }
353
354 hw->rtc.bits = 0;
355 hw->rtc.bitsRead = 0;
356 if (!hw->rtc.bytesRemaining) {
357 hw->rtc.commandActive = 0;
358 hw->rtc.command = 0;
359 }
360}
361
362unsigned _rtcOutput(struct GBACartridgeHardware* hw) {
363 uint8_t outputByte = 0;
364 if (!hw->rtc.commandActive) {
365 mLOG(GBA_HW, GAME_ERROR, "Attempting to use RTC without an active command");
366 return 0;
367 }
368 switch (RTCCommandDataGetCommand(hw->rtc.command)) {
369 case RTC_CONTROL:
370 outputByte = hw->rtc.control;
371 break;
372 case RTC_DATETIME:
373 case RTC_TIME:
374 outputByte = hw->rtc.time[7 - hw->rtc.bytesRemaining];
375 break;
376 case RTC_FORCE_IRQ:
377 case RTC_RESET:
378 break;
379 }
380 unsigned output = (outputByte >> hw->rtc.bitsRead) & 1;
381 return output;
382}
383
384void _rtcUpdateClock(struct GBACartridgeHardware* hw) {
385 time_t t;
386 struct mRTCSource* rtc = hw->p->rtcSource;
387 if (rtc) {
388 if (rtc->sample) {
389 rtc->sample(rtc);
390 }
391 t = rtc->unixTime(rtc);
392 } else {
393 t = time(0);
394 }
395 struct tm date;
396 localtime_r(&t, &date);
397 hw->rtc.time[0] = _rtcBCD(date.tm_year - 100);
398 hw->rtc.time[1] = _rtcBCD(date.tm_mon + 1);
399 hw->rtc.time[2] = _rtcBCD(date.tm_mday);
400 hw->rtc.time[3] = _rtcBCD(date.tm_wday);
401 if (RTCControlIsHour24(hw->rtc.control)) {
402 hw->rtc.time[4] = _rtcBCD(date.tm_hour);
403 } else {
404 hw->rtc.time[4] = _rtcBCD(date.tm_hour % 12);
405 }
406 hw->rtc.time[5] = _rtcBCD(date.tm_min);
407 hw->rtc.time[6] = _rtcBCD(date.tm_sec);
408}
409
410unsigned _rtcBCD(unsigned value) {
411 int counter = value % 10;
412 value /= 10;
413 counter += (value % 10) << 4;
414 return counter;
415}
416
417time_t _rtcGenericCallback(struct mRTCSource* source) {
418 struct GBARTCGenericSource* rtc = (struct GBARTCGenericSource*) source;
419 switch (rtc->override) {
420 case RTC_NO_OVERRIDE:
421 default:
422 return time(0);
423 case RTC_FIXED:
424 return rtc->value;
425 case RTC_FAKE_EPOCH:
426 return rtc->value + rtc->p->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY;
427 }
428}
429
430void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba) {
431 rtc->p = gba;
432 rtc->override = RTC_NO_OVERRIDE;
433 rtc->value = 0;
434 rtc->d.sample = 0;
435 rtc->d.unixTime = _rtcGenericCallback;
436}
437
438// == Gyro
439
440void GBAHardwareInitGyro(struct GBACartridgeHardware* hw) {
441 hw->devices |= HW_GYRO;
442 hw->gyroSample = 0;
443 hw->gyroEdge = 0;
444}
445
446void _gyroReadPins(struct GBACartridgeHardware* hw) {
447 struct mRotationSource* gyro = hw->p->rotationSource;
448 if (!gyro || !gyro->readGyroZ) {
449 return;
450 }
451
452 if (hw->pinState & 1) {
453 if (gyro->sample) {
454 gyro->sample(gyro);
455 }
456 int32_t sample = gyro->readGyroZ(gyro);
457
458 // Normalize to ~12 bits, focused on 0x6C0
459 hw->gyroSample = (sample >> 21) + 0x6C0; // Crop off an extra bit so that we can't go negative
460 }
461
462 if (hw->gyroEdge && !(hw->pinState & 2)) {
463 // Write bit on falling edge
464 unsigned bit = hw->gyroSample >> 15;
465 hw->gyroSample <<= 1;
466 _outputPins(hw, bit << 2);
467 }
468
469 hw->gyroEdge = !!(hw->pinState & 2);
470}
471
472// == Rumble
473
474void GBAHardwareInitRumble(struct GBACartridgeHardware* hw) {
475 hw->devices |= HW_RUMBLE;
476}
477
478void _rumbleReadPins(struct GBACartridgeHardware* hw) {
479 struct mRumble* rumble = hw->p->rumble;
480 if (!rumble) {
481 return;
482 }
483
484 rumble->setRumble(rumble, !!(hw->pinState & 8));
485}
486
487// == Light sensor
488
489void GBAHardwareInitLight(struct GBACartridgeHardware* hw) {
490 hw->devices |= HW_LIGHT_SENSOR;
491 hw->lightCounter = 0;
492 hw->lightEdge = false;
493 hw->lightSample = 0xFF;
494}
495
496void _lightReadPins(struct GBACartridgeHardware* hw) {
497 if (hw->pinState & 4) {
498 // Boktai chip select
499 return;
500 }
501 if (hw->pinState & 2) {
502 struct GBALuminanceSource* lux = hw->p->luminanceSource;
503 mLOG(GBA_HW, DEBUG, "[SOLAR] Got reset");
504 hw->lightCounter = 0;
505 if (lux) {
506 lux->sample(lux);
507 hw->lightSample = lux->readLuminance(lux);
508 } else {
509 hw->lightSample = 0xFF;
510 }
511 }
512 if ((hw->pinState & 1) && hw->lightEdge) {
513 ++hw->lightCounter;
514 }
515 hw->lightEdge = !(hw->pinState & 1);
516
517 bool sendBit = hw->lightCounter >= hw->lightSample;
518 _outputPins(hw, sendBit << 3);
519 mLOG(GBA_HW, DEBUG, "[SOLAR] Output %u with pins %u", hw->lightCounter, hw->pinState);
520}
521
522// == Tilt
523
524void GBAHardwareInitTilt(struct GBACartridgeHardware* hw) {
525 hw->devices |= HW_TILT;
526 hw->tiltX = 0xFFF;
527 hw->tiltY = 0xFFF;
528 hw->tiltState = 0;
529}
530
531void GBAHardwareTiltWrite(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value) {
532 switch (address) {
533 case 0x8000:
534 if (value == 0x55) {
535 hw->tiltState = 1;
536 } else {
537 mLOG(GBA_HW, GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
538 }
539 break;
540 case 0x8100:
541 if (value == 0xAA && hw->tiltState == 1) {
542 hw->tiltState = 0;
543 struct mRotationSource* rotationSource = hw->p->rotationSource;
544 if (!rotationSource || !rotationSource->readTiltX || !rotationSource->readTiltY) {
545 return;
546 }
547 if (rotationSource->sample) {
548 rotationSource->sample(rotationSource);
549 }
550 int32_t x = rotationSource->readTiltX(rotationSource);
551 int32_t y = rotationSource->readTiltY(rotationSource);
552 // Normalize to ~12 bits, focused on 0x3A0
553 hw->tiltX = (x >> 21) + 0x3A0; // Crop off an extra bit so that we can't go negative
554 hw->tiltY = (y >> 21) + 0x3A0;
555 } else {
556 mLOG(GBA_HW, GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
557 }
558 break;
559 default:
560 mLOG(GBA_HW, GAME_ERROR, "Invalid tilt sensor write to %04x: %02x", address, value);
561 break;
562 }
563}
564
565uint8_t GBAHardwareTiltRead(struct GBACartridgeHardware* hw, uint32_t address) {
566 switch (address) {
567 case 0x8200:
568 return hw->tiltX & 0xFF;
569 case 0x8300:
570 return ((hw->tiltX >> 8) & 0xF) | 0x80;
571 case 0x8400:
572 return hw->tiltY & 0xFF;
573 case 0x8500:
574 return (hw->tiltY >> 8) & 0xF;
575 default:
576 mLOG(GBA_HW, GAME_ERROR, "Invalid tilt sensor read from %04x", address);
577 break;
578 }
579 return 0xFF;
580}
581
582// == Game Boy Player
583
584static const uint16_t _logoPalette[] = {
585 0xFFDF, 0x640C, 0xE40C, 0xE42D, 0x644E, 0xE44E, 0xE46E, 0x68AF,
586 0xE8B0, 0x68D0, 0x68F0, 0x6911, 0xE911, 0x6D32, 0xED32, 0xED73,
587 0x6D93, 0xED94, 0x6DB4, 0xF1D5, 0x71F5, 0xF1F6, 0x7216, 0x7257,
588 0xF657, 0x7678, 0xF678, 0xF699, 0xF6B9, 0x76D9, 0xF6DA, 0x7B1B,
589 0xFB1B, 0xFB3C, 0x7B5C, 0x7B7D, 0xFF7D, 0x7F9D, 0x7FBE, 0x7FFF,
590 0x642D, 0x648E, 0xE88F, 0xE8F1, 0x6D52, 0x6D73, 0xF1B4, 0xF216,
591 0x7237, 0x7698, 0x7AFA, 0xFAFA, 0xFB5C, 0xFFBE, 0x7FDE, 0xFFFF,
592 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
593};
594
595static const uint32_t _logoHash = 0xEEDA6963;
596
597static const uint32_t _gbpTxData[] = {
598 0x0000494E, 0x0000494E,
599 0xB6B1494E, 0xB6B1544E,
600 0xABB1544E, 0xABB14E45,
601 0xB1BA4E45, 0xB1BA4F44,
602 0xB0BB4F44, 0xB0BB8002,
603 0x10000010, 0x20000013,
604 0x30000003
605};
606
607bool GBAHardwarePlayerCheckScreen(const struct GBAVideo* video) {
608 if (memcmp(video->palette, _logoPalette, sizeof(_logoPalette)) != 0) {
609 return false;
610 }
611 uint32_t hash = hash32(&video->renderer->vram[0x4000], 0x4000, 0);
612 return hash == _logoHash;
613}
614
615void GBAHardwarePlayerUpdate(struct GBA* gba) {
616 if (gba->memory.hw.devices & HW_GB_PLAYER) {
617 if (GBAHardwarePlayerCheckScreen(&gba->video)) {
618 ++gba->memory.hw.gbpInputsPosted;
619 gba->memory.hw.gbpInputsPosted %= 3;
620 gba->keyCallback = &gba->memory.hw.gbpCallback.d;
621 } else {
622 // TODO: Save and restore
623 gba->keyCallback = 0;
624 }
625 gba->memory.hw.gbpTxPosition = 0;
626 return;
627 }
628 if (gba->keyCallback || gba->sio.drivers.normal) {
629 return;
630 }
631 if (GBAHardwarePlayerCheckScreen(&gba->video)) {
632 gba->memory.hw.devices |= HW_GB_PLAYER;
633 gba->memory.hw.gbpInputsPosted = 0;
634 gba->keyCallback = &gba->memory.hw.gbpCallback.d;
635 GBASIOSetDriver(&gba->sio, &gba->memory.hw.gbpDriver.d, SIO_NORMAL_32);
636 }
637}
638
639uint16_t _gbpRead(struct mKeyCallback* callback) {
640 struct GBAGBPKeyCallback* gbpCallback = (struct GBAGBPKeyCallback*) callback;
641 if (gbpCallback->p->gbpInputsPosted == 2) {
642 return 0xF0;
643 }
644 return 0;
645}
646
647uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) {
648 struct GBAGBPSIODriver* gbp = (struct GBAGBPSIODriver*) driver;
649 if (address == REG_SIOCNT) {
650 if (value & 0x0080) {
651 uint32_t rx = gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] | (gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] << 16);
652 if (gbp->p->gbpTxPosition < 12 && gbp->p->gbpTxPosition > 0) {
653 // TODO: Check expected
654 } else if (gbp->p->gbpTxPosition >= 12) {
655 uint32_t mask = 0x33;
656 // 0x00 = Stop
657 // 0x11 = Hard Stop
658 // 0x22 = Start
659 if (gbp->p->p->rumble) {
660 gbp->p->p->rumble->setRumble(gbp->p->p->rumble, (rx & mask) == 0x22);
661 }
662 }
663 mTimingDeschedule(&gbp->p->p->timing, &gbp->p->gbpNextEvent);
664 mTimingSchedule(&gbp->p->p->timing, &gbp->p->gbpNextEvent, 2048);
665 }
666 value &= 0x78FB;
667 }
668 return value;
669}
670
671void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
672 UNUSED(timing);
673 UNUSED(cyclesLate);
674 struct GBAGBPSIODriver* gbp = user;
675 uint32_t tx = 0;
676 int txPosition = gbp->p->gbpTxPosition;
677 if (txPosition > 16) {
678 gbp->p->gbpTxPosition = 0;
679 txPosition = 0;
680 } else if (txPosition > 12) {
681 txPosition = 12;
682 }
683 tx = _gbpTxData[txPosition];
684 ++gbp->p->gbpTxPosition;
685 gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
686 gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
687 if (GBASIONormalIsIrq(gbp->d.p->siocnt)) {
688 GBARaiseIRQ(gbp->p->p, IRQ_SIO, cyclesLate);
689 }
690 gbp->d.p->siocnt = GBASIONormalClearStart(gbp->d.p->siocnt);
691 gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080;
692}
693
694// == e-Reader
695
696void GBAHardwareInitEReader(struct GBACartridgeHardware* hw) {
697 hw->devices |= HW_EREADER;
698 _eReaderReset(hw);
699
700 if (hw->p->memory.savedata.data[0xD000] == 0xFF) {
701 memset(&hw->p->memory.savedata.data[0xD000], 0, 0x1000);
702 memcpy(&hw->p->memory.savedata.data[0xD000], EREADER_CALIBRATION_TEMPLATE, sizeof(EREADER_CALIBRATION_TEMPLATE));
703 }
704 if (hw->p->memory.savedata.data[0xE000] == 0xFF) {
705 memset(&hw->p->memory.savedata.data[0xE000], 0, 0x1000);
706 memcpy(&hw->p->memory.savedata.data[0xE000], EREADER_CALIBRATION_TEMPLATE, sizeof(EREADER_CALIBRATION_TEMPLATE));
707 }
708}
709
710void GBAHardwareEReaderWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) {
711 address &= 0x700FF;
712 switch (address >> 17) {
713 case 0:
714 hw->eReaderRegisterUnk = value & 0xF;
715 break;
716 case 1:
717 hw->eReaderRegisterReset = (value & 0x8A) | 4;
718 if (value & 2) {
719 _eReaderReset(hw);
720 }
721 break;
722 case 2:
723 mLOG(GBA_HW, GAME_ERROR, "e-Reader write to read-only registers: %05X:%04X", address, value);
724 break;
725 default:
726 mLOG(GBA_HW, STUB, "Unimplemented e-Reader write: %05X:%04X", address, value);
727 }
728}
729
730void GBAHardwareEReaderWriteFlash(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value) {
731 address &= 0xFFFF;
732 switch (address) {
733 case 0xFFB0:
734 _eReaderWriteControl0(hw, value);
735 break;
736 case 0xFFB1:
737 _eReaderWriteControl1(hw, value);
738 break;
739 case 0xFFB2:
740 hw->eReaderRegisterLed &= 0xFF00;
741 hw->eReaderRegisterLed |= value;
742 break;
743 case 0xFFB3:
744 hw->eReaderRegisterLed &= 0x00FF;
745 hw->eReaderRegisterLed |= value << 8;
746 break;
747 default:
748 mLOG(GBA_HW, STUB, "Unimplemented e-Reader write to flash: %04X:%02X", address, value);
749 }
750}
751
752uint16_t GBAHardwareEReaderRead(struct GBACartridgeHardware* hw, uint32_t address) {
753 address &= 0x700FF;
754 uint16_t value;
755 switch (address >> 17) {
756 case 0:
757 return hw->eReaderRegisterUnk;
758 case 1:
759 return hw->eReaderRegisterReset;
760 case 2:
761 if (address > 0x40088) {
762 return 0;
763 }
764 LOAD_16(value, address & 0xFE, hw->eReaderData);
765 return value;
766 }
767 mLOG(GBA_HW, STUB, "Unimplemented e-Reader read: %05X", address);
768 return 0;
769}
770
771uint8_t GBAHardwareEReaderReadFlash(struct GBACartridgeHardware* hw, uint32_t address) {
772 address &= 0xFFFF;
773 switch (address) {
774 case 0xFFB0:
775 return hw->eReaderRegisterControl0;
776 case 0xFFB1:
777 return hw->eReaderRegisterControl1;
778 default:
779 mLOG(GBA_HW, STUB, "Unimplemented e-Reader read from flash: %04X", address);
780 return 0;
781 }
782}
783
784static void _eReaderAnchor(uint8_t* origin) {
785 origin[EREADER_DOTCODE_STRIDE * 0 + 1] = 1;
786 origin[EREADER_DOTCODE_STRIDE * 0 + 2] = 1;
787 origin[EREADER_DOTCODE_STRIDE * 0 + 3] = 1;
788 origin[EREADER_DOTCODE_STRIDE * 1 + 0] = 1;
789 origin[EREADER_DOTCODE_STRIDE * 1 + 1] = 1;
790 origin[EREADER_DOTCODE_STRIDE * 1 + 2] = 1;
791 origin[EREADER_DOTCODE_STRIDE * 1 + 3] = 1;
792 origin[EREADER_DOTCODE_STRIDE * 1 + 4] = 1;
793 origin[EREADER_DOTCODE_STRIDE * 2 + 0] = 1;
794 origin[EREADER_DOTCODE_STRIDE * 2 + 1] = 1;
795 origin[EREADER_DOTCODE_STRIDE * 2 + 2] = 1;
796 origin[EREADER_DOTCODE_STRIDE * 2 + 3] = 1;
797 origin[EREADER_DOTCODE_STRIDE * 2 + 4] = 1;
798 origin[EREADER_DOTCODE_STRIDE * 3 + 0] = 1;
799 origin[EREADER_DOTCODE_STRIDE * 3 + 1] = 1;
800 origin[EREADER_DOTCODE_STRIDE * 3 + 2] = 1;
801 origin[EREADER_DOTCODE_STRIDE * 3 + 3] = 1;
802 origin[EREADER_DOTCODE_STRIDE * 3 + 4] = 1;
803 origin[EREADER_DOTCODE_STRIDE * 4 + 1] = 1;
804 origin[EREADER_DOTCODE_STRIDE * 4 + 2] = 1;
805 origin[EREADER_DOTCODE_STRIDE * 4 + 3] = 1;
806}
807
808static void _eReaderAlignment(uint8_t* origin) {
809 origin[8] = 1;
810 origin[10] = 1;
811 origin[12] = 1;
812 origin[14] = 1;
813 origin[16] = 1;
814 origin[18] = 1;
815 origin[21] = 1;
816 origin[23] = 1;
817 origin[25] = 1;
818 origin[27] = 1;
819 origin[29] = 1;
820 origin[31] = 1;
821}
822
823static void _eReaderAddress(uint8_t* origin, int a) {
824 origin[EREADER_DOTCODE_STRIDE * 7 + 2] = 1;
825 uint16_t addr = EREADER_ADDRESS_CODES[a];
826 int i;
827 for (i = 0; i < 16; ++i) {
828 origin[EREADER_DOTCODE_STRIDE * (16 + i) + 2] = (addr >> (15 - i)) & 1;
829 }
830}
831
832void GBAHardwareEReaderScan(struct GBACartridgeHardware* hw, const void* data, size_t size) {
833 if (!hw->eReaderDots) {
834 hw->eReaderDots = anonymousMemoryMap(EREADER_DOTCODE_SIZE);
835 }
836 memset(hw->eReaderDots, 0, EREADER_DOTCODE_SIZE);
837
838 int base;
839 switch (size) {
840 case 2912:
841 base = 25;
842 break;
843 case 1872:
844 base = 1;
845 break;
846 default:
847 return;
848 }
849
850 size_t i;
851 for (i = 0; i < (size / 104) + 1; ++i) {
852 uint8_t* origin = &hw->eReaderDots[35 * i + 200];
853 _eReaderAnchor(&origin[EREADER_DOTCODE_STRIDE * 0]);
854 _eReaderAnchor(&origin[EREADER_DOTCODE_STRIDE * 35]);
855 _eReaderAddress(origin, base + i);
856 }
857 for (i = 0; i < size / 104; ++i) {
858 uint8_t block[1040];
859 uint8_t* origin = &hw->eReaderDots[35 * i + 200];
860 _eReaderAlignment(&origin[EREADER_DOTCODE_STRIDE * 2]);
861 _eReaderAlignment(&origin[EREADER_DOTCODE_STRIDE * 37]);
862
863 int b;
864 for (b = 0; b < 104; ++b) {
865 const int* nybble5;
866 nybble5 = EREADER_NYBBLE_5BIT[((const uint8_t*) data)[i * 104 + b] >> 4];
867 block[b * 10 + 0] = nybble5[0];
868 block[b * 10 + 1] = nybble5[1];
869 block[b * 10 + 2] = nybble5[2];
870 block[b * 10 + 3] = nybble5[3];
871 block[b * 10 + 4] = nybble5[4];
872 nybble5 = EREADER_NYBBLE_5BIT[((const uint8_t*) data)[i * 104 + b] & 0xF];
873 block[b * 10 + 5] = nybble5[0];
874 block[b * 10 + 6] = nybble5[1];
875 block[b * 10 + 7] = nybble5[2];
876 block[b * 10 + 8] = nybble5[3];
877 block[b * 10 + 9] = nybble5[4];
878 }
879
880 b = 0;
881 int y;
882 for (y = 0; y < 3; ++y) {
883 memcpy(&origin[EREADER_DOTCODE_STRIDE * (4 + y) + 7], &block[b], 26);
884 b += 26;
885 }
886 for (y = 0; y < 26; ++y) {
887 memcpy(&origin[EREADER_DOTCODE_STRIDE * (7 + y) + 3], &block[b], 34);
888 b += 34;
889 }
890 for (y = 0; y < 3; ++y) {
891 memcpy(&origin[EREADER_DOTCODE_STRIDE * (33 + y) + 7], &block[b], 26);
892 b += 26;
893 }
894 }
895 hw->eReaderX = -24;
896}
897
898void _eReaderReset(struct GBACartridgeHardware* hw) {
899 memset(hw->eReaderData, 0, sizeof(hw->eReaderData));
900 hw->eReaderRegisterUnk = 0;
901 hw->eReaderRegisterReset = 4;
902 hw->eReaderRegisterControl0 = 0;
903 hw->eReaderRegisterControl1 = 0x80;
904 hw->eReaderRegisterLed = 0;
905 hw->eReaderState = 0;
906 hw->eReaderActiveRegister = 0;
907}
908
909void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value) {
910 EReaderControl0 control = value & 0x7F;
911 EReaderControl0 oldControl = hw->eReaderRegisterControl0;
912 if (hw->eReaderState == EREADER_SERIAL_INACTIVE) {
913 if (EReaderControl0IsClock(oldControl) && EReaderControl0IsData(oldControl) && !EReaderControl0IsData(control)) {
914 hw->eReaderState = EREADER_SERIAL_STARTING;
915 }
916 } else if (EReaderControl0IsClock(oldControl) && !EReaderControl0IsData(oldControl) && EReaderControl0IsData(control)) {
917 hw->eReaderState = EREADER_SERIAL_INACTIVE;
918
919 } else if (hw->eReaderState == EREADER_SERIAL_STARTING) {
920 if (EReaderControl0IsClock(oldControl) && !EReaderControl0IsData(oldControl) && !EReaderControl0IsClock(control)) {
921 hw->eReaderState = EREADER_SERIAL_BIT_0;
922 hw->eReaderCommand = EREADER_COMMAND_IDLE;
923 }
924 } else if (EReaderControl0IsClock(oldControl) && !EReaderControl0IsClock(control)) {
925 mLOG(GBA_HW, DEBUG, "[e-Reader] Serial falling edge: %c %i", EReaderControl0IsDirection(control) ? '>' : '<', EReaderControl0GetData(control));
926 // TODO: Improve direction control
927 if (EReaderControl0IsDirection(control)) {
928 hw->eReaderByte |= EReaderControl0GetData(control) << (7 - (hw->eReaderState - EREADER_SERIAL_BIT_0));
929 ++hw->eReaderState;
930 if (hw->eReaderState == EREADER_SERIAL_END_BIT) {
931 mLOG(GBA_HW, DEBUG, "[e-Reader] Wrote serial byte: %02x", hw->eReaderByte);
932 switch (hw->eReaderCommand) {
933 case EREADER_COMMAND_IDLE:
934 hw->eReaderCommand = hw->eReaderByte;
935 break;
936 case EREADER_COMMAND_SET_INDEX:
937 hw->eReaderActiveRegister = hw->eReaderByte;
938 hw->eReaderCommand = EREADER_COMMAND_WRITE_DATA;
939 break;
940 case EREADER_COMMAND_WRITE_DATA:
941 switch (hw->eReaderActiveRegister & 0x7F) {
942 case 0:
943 case 0x57:
944 case 0x58:
945 case 0x59:
946 case 0x5A:
947 // Read-only
948 mLOG(GBA_HW, GAME_ERROR, "Writing to read-only e-Reader serial register: %02X", hw->eReaderActiveRegister);
949 break;
950 default:
951 if ((hw->eReaderActiveRegister & 0x7F) > 0x5A) {
952 mLOG(GBA_HW, GAME_ERROR, "Writing to non-existent e-Reader serial register: %02X", hw->eReaderActiveRegister);
953 break;
954 }
955 hw->eReaderSerial[hw->eReaderActiveRegister & 0x7F] = hw->eReaderByte;
956 break;
957 }
958 ++hw->eReaderActiveRegister;
959 break;
960 default:
961 mLOG(GBA_HW, ERROR, "Hit undefined state %02X in e-Reader state machine", hw->eReaderCommand);
962 break;
963 }
964 hw->eReaderState = EREADER_SERIAL_BIT_0;
965 hw->eReaderByte = 0;
966 }
967 } else if (hw->eReaderCommand == EREADER_COMMAND_READ_DATA) {
968 int bit = hw->eReaderSerial[hw->eReaderActiveRegister & 0x7F] >> (7 - (hw->eReaderState - EREADER_SERIAL_BIT_0));
969 control = EReaderControl0SetData(control, bit);
970 ++hw->eReaderState;
971 if (hw->eReaderState == EREADER_SERIAL_END_BIT) {
972 ++hw->eReaderActiveRegister;
973 mLOG(GBA_HW, DEBUG, "[e-Reader] Read serial byte: %02x", hw->eReaderSerial[hw->eReaderActiveRegister & 0x7F]);
974 }
975 }
976 } else if (!EReaderControl0IsDirection(control)) {
977 // Clear the error bit
978 control = EReaderControl0ClearData(control);
979 }
980 hw->eReaderRegisterControl0 = control;
981 if (!EReaderControl0IsScan(oldControl) && EReaderControl0IsScan(control)) {
982 hw->eReaderX = 0;
983 hw->eReaderY = 0;
984 } else if (EReaderControl0IsLedEnable(control) && EReaderControl0IsScan(control) && !EReaderControl1IsScanline(hw->eReaderRegisterControl1)) {
985 _eReaderReadData(hw);
986 }
987 mLOG(GBA_HW, STUB, "Unimplemented e-Reader Control0 write: %02X", value);
988}
989
990void _eReaderWriteControl1(struct GBACartridgeHardware* hw, uint8_t value) {
991 EReaderControl1 control = (value & 0x32) | 0x80;
992 hw->eReaderRegisterControl1 = control;
993 if (EReaderControl0IsScan(hw->eReaderRegisterControl0) && !EReaderControl1IsScanline(control)) {
994 ++hw->eReaderY;
995 if (hw->eReaderY == (hw->eReaderSerial[0x15] | (hw->eReaderSerial[0x14] << 8))) {
996 hw->eReaderY = 0;
997 if (hw->eReaderX < 3400) {
998 hw->eReaderX += 220;
999 }
1000 }
1001 _eReaderReadData(hw);
1002 }
1003 mLOG(GBA_HW, STUB, "Unimplemented e-Reader Control1 write: %02X", value);
1004}
1005
1006void _eReaderReadData(struct GBACartridgeHardware* hw) {
1007 memset(hw->eReaderData, 0, EREADER_BLOCK_SIZE);
1008 if (hw->eReaderDots) {
1009 int y = hw->eReaderY - 10;
1010 if (y < 0 || y >= 120) {
1011 memset(hw->eReaderData, 0, EREADER_BLOCK_SIZE);
1012 } else {
1013 int i;
1014 uint8_t* origin = &hw->eReaderDots[EREADER_DOTCODE_STRIDE * (y / 3) + 16];
1015 for (i = 0; i < 20; ++i) {
1016 uint16_t word = 0;
1017 int x = hw->eReaderX + i * 16;
1018 word |= origin[(x + 0) / 3] << 8;
1019 word |= origin[(x + 1) / 3] << 9;
1020 word |= origin[(x + 2) / 3] << 10;
1021 word |= origin[(x + 3) / 3] << 11;
1022 word |= origin[(x + 4) / 3] << 12;
1023 word |= origin[(x + 5) / 3] << 13;
1024 word |= origin[(x + 6) / 3] << 14;
1025 word |= origin[(x + 7) / 3] << 15;
1026 word |= origin[(x + 8) / 3];
1027 word |= origin[(x + 9) / 3] << 1;
1028 word |= origin[(x + 10) / 3] << 2;
1029 word |= origin[(x + 11) / 3] << 3;
1030 word |= origin[(x + 12) / 3] << 4;
1031 word |= origin[(x + 13) / 3] << 5;
1032 word |= origin[(x + 14) / 3] << 6;
1033 word |= origin[(x + 15) / 3] << 7;
1034 STORE_16(word, (19 - i) << 1, hw->eReaderData);
1035 }
1036 }
1037 }
1038 hw->eReaderRegisterControl1 = EReaderControl1FillScanline(hw->eReaderRegisterControl1);
1039 if (EReaderControl0IsLedEnable(hw->eReaderRegisterControl0)) {
1040 uint16_t led = 2754; // TODO: Figure out why this breaks if using the LED register
1041 GBARaiseIRQ(hw->p, IRQ_GAMEPAK, -led);
1042 }
1043}
1044
1045// == Serialization
1046
1047void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASerializedState* state) {
1048 GBASerializedHWFlags1 flags1 = 0;
1049 GBASerializedHWFlags2 flags2 = 0;
1050 flags1 = GBASerializedHWFlags1SetReadWrite(flags1, hw->readWrite);
1051 STORE_16(hw->pinState, 0, &state->hw.pinState);
1052 STORE_16(hw->direction, 0, &state->hw.pinDirection);
1053 state->hw.devices = hw->devices;
1054
1055 STORE_32(hw->rtc.bytesRemaining, 0, &state->hw.rtc.bytesRemaining);
1056 STORE_32(hw->rtc.transferStep, 0, &state->hw.rtc.transferStep);
1057 STORE_32(hw->rtc.bitsRead, 0, &state->hw.rtc.bitsRead);
1058 STORE_32(hw->rtc.bits, 0, &state->hw.rtc.bits);
1059 STORE_32(hw->rtc.commandActive, 0, &state->hw.rtc.commandActive);
1060 STORE_32(hw->rtc.command, 0, &state->hw.rtc.command);
1061 STORE_32(hw->rtc.control, 0, &state->hw.rtc.control);
1062 memcpy(state->hw.rtc.time, hw->rtc.time, sizeof(state->hw.rtc.time));
1063
1064 STORE_16(hw->gyroSample, 0, &state->hw.gyroSample);
1065 flags1 = GBASerializedHWFlags1SetGyroEdge(flags1, hw->gyroEdge);
1066 STORE_16(hw->tiltX, 0, &state->hw.tiltSampleX);
1067 STORE_16(hw->tiltY, 0, &state->hw.tiltSampleY);
1068 flags2 = GBASerializedHWFlags2SetTiltState(flags2, hw->tiltState);
1069 flags2 = GBASerializedHWFlags1SetLightCounter(flags2, hw->lightCounter);
1070 state->hw.lightSample = hw->lightSample;
1071 flags1 = GBASerializedHWFlags1SetLightEdge(flags1, hw->lightEdge);
1072 flags2 = GBASerializedHWFlags2SetGbpInputsPosted(flags2, hw->gbpInputsPosted);
1073 flags2 = GBASerializedHWFlags2SetGbpTxPosition(flags2, hw->gbpTxPosition);
1074 STORE_32(hw->gbpNextEvent.when - mTimingCurrentTime(&hw->p->timing), 0, &state->hw.gbpNextEvent);
1075 STORE_16(flags1, 0, &state->hw.flags1);
1076 state->hw.flags2 = flags2;
1077}
1078
1079void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASerializedState* state) {
1080 GBASerializedHWFlags1 flags1;
1081 LOAD_16(flags1, 0, &state->hw.flags1);
1082 hw->readWrite = GBASerializedHWFlags1GetReadWrite(flags1);
1083 LOAD_16(hw->pinState, 0, &state->hw.pinState);
1084 LOAD_16(hw->direction, 0, &state->hw.pinDirection);
1085 hw->devices = state->hw.devices;
1086
1087 LOAD_32(hw->rtc.bytesRemaining, 0, &state->hw.rtc.bytesRemaining);
1088 LOAD_32(hw->rtc.transferStep, 0, &state->hw.rtc.transferStep);
1089 LOAD_32(hw->rtc.bitsRead, 0, &state->hw.rtc.bitsRead);
1090 LOAD_32(hw->rtc.bits, 0, &state->hw.rtc.bits);
1091 LOAD_32(hw->rtc.commandActive, 0, &state->hw.rtc.commandActive);
1092 LOAD_32(hw->rtc.command, 0, &state->hw.rtc.command);
1093 LOAD_32(hw->rtc.control, 0, &state->hw.rtc.control);
1094 memcpy(hw->rtc.time, state->hw.rtc.time, sizeof(hw->rtc.time));
1095
1096 LOAD_16(hw->gyroSample, 0, &state->hw.gyroSample);
1097 hw->gyroEdge = GBASerializedHWFlags1GetGyroEdge(flags1);
1098 LOAD_16(hw->tiltX, 0, &state->hw.tiltSampleX);
1099 LOAD_16(hw->tiltY, 0, &state->hw.tiltSampleY);
1100 hw->tiltState = GBASerializedHWFlags2GetTiltState(state->hw.flags2);
1101 hw->lightCounter = GBASerializedHWFlags1GetLightCounter(flags1);
1102 hw->lightSample = state->hw.lightSample;
1103 hw->lightEdge = GBASerializedHWFlags1GetLightEdge(flags1);
1104 hw->gbpInputsPosted = GBASerializedHWFlags2GetGbpInputsPosted(state->hw.flags2);
1105 hw->gbpTxPosition = GBASerializedHWFlags2GetGbpTxPosition(state->hw.flags2);
1106
1107 uint32_t when;
1108 LOAD_32(when, 0, &state->hw.gbpNextEvent);
1109 if (hw->devices & HW_GB_PLAYER) {
1110 GBASIOSetDriver(&hw->p->sio, &hw->gbpDriver.d, SIO_NORMAL_32);
1111 if (hw->p->memory.io[REG_SIOCNT >> 1] & 0x0080) {
1112 mTimingSchedule(&hw->p->timing, &hw->gbpNextEvent, when);
1113 }
1114 }
1115}