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 }
172
173 if (hw->p->sio.drivers.normal == &hw->gbpDriver.d) {
174 GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32);
175 }
176}
177
178void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) {
179 if (!hw->gpioBase) {
180 return;
181 }
182 switch (address) {
183 case GPIO_REG_DATA:
184 hw->pinState &= ~hw->direction;
185 hw->pinState |= value & hw->direction;
186 _readPins(hw);
187 break;
188 case GPIO_REG_DIRECTION:
189 hw->direction = value;
190 break;
191 case GPIO_REG_CONTROL:
192 hw->readWrite = value;
193 break;
194 default:
195 mLOG(GBA_HW, WARN, "Invalid GPIO address");
196 }
197 if (hw->readWrite) {
198 STORE_16(hw->pinState, 0, hw->gpioBase);
199 STORE_16(hw->direction, 2, hw->gpioBase);
200 STORE_16(hw->readWrite, 4, hw->gpioBase);
201 } else {
202 hw->gpioBase[0] = 0;
203 hw->gpioBase[1] = 0;
204 hw->gpioBase[2] = 0;
205 }
206}
207
208void GBAHardwareInitRTC(struct GBACartridgeHardware* hw) {
209 hw->devices |= HW_RTC;
210 hw->rtc.bytesRemaining = 0;
211
212 hw->rtc.transferStep = 0;
213
214 hw->rtc.bitsRead = 0;
215 hw->rtc.bits = 0;
216 hw->rtc.commandActive = 0;
217 hw->rtc.command = 0;
218 hw->rtc.control = 0x40;
219 memset(hw->rtc.time, 0, sizeof(hw->rtc.time));
220}
221
222void _readPins(struct GBACartridgeHardware* hw) {
223 if (hw->devices & HW_RTC) {
224 _rtcReadPins(hw);
225 }
226
227 if (hw->devices & HW_GYRO) {
228 _gyroReadPins(hw);
229 }
230
231 if (hw->devices & HW_RUMBLE) {
232 _rumbleReadPins(hw);
233 }
234
235 if (hw->devices & HW_LIGHT_SENSOR) {
236 _lightReadPins(hw);
237 }
238}
239
240void _outputPins(struct GBACartridgeHardware* hw, unsigned pins) {
241 if (hw->readWrite) {
242 uint16_t old;
243 LOAD_16(old, 0, hw->gpioBase);
244 old &= hw->direction;
245 hw->pinState = old | (pins & ~hw->direction & 0xF);
246 STORE_16(hw->pinState, 0, hw->gpioBase);
247 }
248}
249
250// == RTC
251
252void _rtcReadPins(struct GBACartridgeHardware* hw) {
253 // Transfer sequence:
254 // P: 0 | 1 | 2 | 3
255 // == Initiate
256 // > HI | - | LO | -
257 // > HI | - | HI | -
258 // == Transfer bit (x8)
259 // > LO | x | HI | -
260 // > HI | - | HI | -
261 // < ?? | x | ?? | -
262 // == Terminate
263 // > - | - | LO | -
264 switch (hw->rtc.transferStep) {
265 case 0:
266 if ((hw->pinState & 5) == 1) {
267 hw->rtc.transferStep = 1;
268 }
269 break;
270 case 1:
271 if ((hw->pinState & 5) == 5) {
272 hw->rtc.transferStep = 2;
273 } else if ((hw->pinState & 5) != 1) {
274 hw->rtc.transferStep = 0;
275 }
276 break;
277 case 2:
278 if (!(hw->pinState & 1)) {
279 hw->rtc.bits &= ~(1 << hw->rtc.bitsRead);
280 hw->rtc.bits |= ((hw->pinState & 2) >> 1) << hw->rtc.bitsRead;
281 } else {
282 if (hw->pinState & 4) {
283 if (!RTCCommandDataIsReading(hw->rtc.command)) {
284 ++hw->rtc.bitsRead;
285 if (hw->rtc.bitsRead == 8) {
286 _rtcProcessByte(hw);
287 }
288 } else {
289 _outputPins(hw, 5 | (_rtcOutput(hw) << 1));
290 ++hw->rtc.bitsRead;
291 if (hw->rtc.bitsRead == 8) {
292 --hw->rtc.bytesRemaining;
293 if (hw->rtc.bytesRemaining <= 0) {
294 hw->rtc.commandActive = 0;
295 hw->rtc.command = 0;
296 }
297 hw->rtc.bitsRead = 0;
298 }
299 }
300 } else {
301 hw->rtc.bitsRead = 0;
302 hw->rtc.bytesRemaining = 0;
303 hw->rtc.commandActive = 0;
304 hw->rtc.command = 0;
305 hw->rtc.transferStep = hw->pinState & 1;
306 _outputPins(hw, 1);
307 }
308 }
309 break;
310 }
311}
312
313void _rtcProcessByte(struct GBACartridgeHardware* hw) {
314 --hw->rtc.bytesRemaining;
315 if (!hw->rtc.commandActive) {
316 RTCCommandData command;
317 command = hw->rtc.bits;
318 if (RTCCommandDataGetMagic(command) == 0x06) {
319 hw->rtc.command = command;
320
321 hw->rtc.bytesRemaining = RTC_BYTES[RTCCommandDataGetCommand(command)];
322 hw->rtc.commandActive = hw->rtc.bytesRemaining > 0;
323 switch (RTCCommandDataGetCommand(command)) {
324 case RTC_RESET:
325 hw->rtc.control = 0;
326 break;
327 case RTC_DATETIME:
328 case RTC_TIME:
329 _rtcUpdateClock(hw);
330 break;
331 case RTC_FORCE_IRQ:
332 case RTC_CONTROL:
333 break;
334 }
335 } else {
336 mLOG(GBA_HW, WARN, "Invalid RTC command byte: %02X", hw->rtc.bits);
337 }
338 } else {
339 switch (RTCCommandDataGetCommand(hw->rtc.command)) {
340 case RTC_CONTROL:
341 hw->rtc.control = hw->rtc.bits;
342 break;
343 case RTC_FORCE_IRQ:
344 mLOG(GBA_HW, STUB, "Unimplemented RTC command %u", RTCCommandDataGetCommand(hw->rtc.command));
345 break;
346 case RTC_RESET:
347 case RTC_DATETIME:
348 case RTC_TIME:
349 break;
350 }
351 }
352
353 hw->rtc.bits = 0;
354 hw->rtc.bitsRead = 0;
355 if (!hw->rtc.bytesRemaining) {
356 hw->rtc.commandActive = 0;
357 hw->rtc.command = 0;
358 }
359}
360
361unsigned _rtcOutput(struct GBACartridgeHardware* hw) {
362 uint8_t outputByte = 0;
363 if (!hw->rtc.commandActive) {
364 mLOG(GBA_HW, GAME_ERROR, "Attempting to use RTC without an active command");
365 return 0;
366 }
367 switch (RTCCommandDataGetCommand(hw->rtc.command)) {
368 case RTC_CONTROL:
369 outputByte = hw->rtc.control;
370 break;
371 case RTC_DATETIME:
372 case RTC_TIME:
373 outputByte = hw->rtc.time[7 - hw->rtc.bytesRemaining];
374 break;
375 case RTC_FORCE_IRQ:
376 case RTC_RESET:
377 break;
378 }
379 unsigned output = (outputByte >> hw->rtc.bitsRead) & 1;
380 return output;
381}
382
383void _rtcUpdateClock(struct GBACartridgeHardware* hw) {
384 time_t t;
385 struct mRTCSource* rtc = hw->p->rtcSource;
386 if (rtc) {
387 if (rtc->sample) {
388 rtc->sample(rtc);
389 }
390 t = rtc->unixTime(rtc);
391 } else {
392 t = time(0);
393 }
394 struct tm date;
395 localtime_r(&t, &date);
396 hw->rtc.time[0] = _rtcBCD(date.tm_year - 100);
397 hw->rtc.time[1] = _rtcBCD(date.tm_mon + 1);
398 hw->rtc.time[2] = _rtcBCD(date.tm_mday);
399 hw->rtc.time[3] = _rtcBCD(date.tm_wday);
400 if (RTCControlIsHour24(hw->rtc.control)) {
401 hw->rtc.time[4] = _rtcBCD(date.tm_hour);
402 } else {
403 hw->rtc.time[4] = _rtcBCD(date.tm_hour % 12);
404 }
405 hw->rtc.time[5] = _rtcBCD(date.tm_min);
406 hw->rtc.time[6] = _rtcBCD(date.tm_sec);
407}
408
409unsigned _rtcBCD(unsigned value) {
410 int counter = value % 10;
411 value /= 10;
412 counter += (value % 10) << 4;
413 return counter;
414}
415
416time_t _rtcGenericCallback(struct mRTCSource* source) {
417 struct GBARTCGenericSource* rtc = (struct GBARTCGenericSource*) source;
418 switch (rtc->override) {
419 case RTC_NO_OVERRIDE:
420 default:
421 return time(0);
422 case RTC_FIXED:
423 return rtc->value;
424 case RTC_FAKE_EPOCH:
425 return rtc->value + rtc->p->video.frameCounter * (int64_t) VIDEO_TOTAL_LENGTH / GBA_ARM7TDMI_FREQUENCY;
426 }
427}
428
429void GBARTCGenericSourceInit(struct GBARTCGenericSource* rtc, struct GBA* gba) {
430 rtc->p = gba;
431 rtc->override = RTC_NO_OVERRIDE;
432 rtc->value = 0;
433 rtc->d.sample = 0;
434 rtc->d.unixTime = _rtcGenericCallback;
435}
436
437// == Gyro
438
439void GBAHardwareInitGyro(struct GBACartridgeHardware* hw) {
440 hw->devices |= HW_GYRO;
441 hw->gyroSample = 0;
442 hw->gyroEdge = 0;
443}
444
445void _gyroReadPins(struct GBACartridgeHardware* hw) {
446 struct mRotationSource* gyro = hw->p->rotationSource;
447 if (!gyro || !gyro->readGyroZ) {
448 return;
449 }
450
451 if (hw->pinState & 1) {
452 if (gyro->sample) {
453 gyro->sample(gyro);
454 }
455 int32_t sample = gyro->readGyroZ(gyro);
456
457 // Normalize to ~12 bits, focused on 0x6C0
458 hw->gyroSample = (sample >> 21) + 0x6C0; // Crop off an extra bit so that we can't go negative
459 }
460
461 if (hw->gyroEdge && !(hw->pinState & 2)) {
462 // Write bit on falling edge
463 unsigned bit = hw->gyroSample >> 15;
464 hw->gyroSample <<= 1;
465 _outputPins(hw, bit << 2);
466 }
467
468 hw->gyroEdge = !!(hw->pinState & 2);
469}
470
471// == Rumble
472
473void GBAHardwareInitRumble(struct GBACartridgeHardware* hw) {
474 hw->devices |= HW_RUMBLE;
475}
476
477void _rumbleReadPins(struct GBACartridgeHardware* hw) {
478 struct mRumble* rumble = hw->p->rumble;
479 if (!rumble) {
480 return;
481 }
482
483 rumble->setRumble(rumble, !!(hw->pinState & 8));
484}
485
486// == Light sensor
487
488void GBAHardwareInitLight(struct GBACartridgeHardware* hw) {
489 hw->devices |= HW_LIGHT_SENSOR;
490 hw->lightCounter = 0;
491 hw->lightEdge = false;
492 hw->lightSample = 0xFF;
493}
494
495void _lightReadPins(struct GBACartridgeHardware* hw) {
496 if (hw->pinState & 4) {
497 // Boktai chip select
498 return;
499 }
500 if (hw->pinState & 2) {
501 struct GBALuminanceSource* lux = hw->p->luminanceSource;
502 mLOG(GBA_HW, DEBUG, "[SOLAR] Got reset");
503 hw->lightCounter = 0;
504 if (lux) {
505 lux->sample(lux);
506 hw->lightSample = lux->readLuminance(lux);
507 } else {
508 hw->lightSample = 0xFF;
509 }
510 }
511 if ((hw->pinState & 1) && hw->lightEdge) {
512 ++hw->lightCounter;
513 }
514 hw->lightEdge = !(hw->pinState & 1);
515
516 bool sendBit = hw->lightCounter >= hw->lightSample;
517 _outputPins(hw, sendBit << 3);
518 mLOG(GBA_HW, DEBUG, "[SOLAR] Output %u with pins %u", hw->lightCounter, hw->pinState);
519}
520
521// == Tilt
522
523void GBAHardwareInitTilt(struct GBACartridgeHardware* hw) {
524 hw->devices |= HW_TILT;
525 hw->tiltX = 0xFFF;
526 hw->tiltY = 0xFFF;
527 hw->tiltState = 0;
528}
529
530void GBAHardwareTiltWrite(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value) {
531 switch (address) {
532 case 0x8000:
533 if (value == 0x55) {
534 hw->tiltState = 1;
535 } else {
536 mLOG(GBA_HW, GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
537 }
538 break;
539 case 0x8100:
540 if (value == 0xAA && hw->tiltState == 1) {
541 hw->tiltState = 0;
542 struct mRotationSource* rotationSource = hw->p->rotationSource;
543 if (!rotationSource || !rotationSource->readTiltX || !rotationSource->readTiltY) {
544 return;
545 }
546 if (rotationSource->sample) {
547 rotationSource->sample(rotationSource);
548 }
549 int32_t x = rotationSource->readTiltX(rotationSource);
550 int32_t y = rotationSource->readTiltY(rotationSource);
551 // Normalize to ~12 bits, focused on 0x3A0
552 hw->tiltX = (x >> 21) + 0x3A0; // Crop off an extra bit so that we can't go negative
553 hw->tiltY = (y >> 21) + 0x3A0;
554 } else {
555 mLOG(GBA_HW, GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
556 }
557 break;
558 default:
559 mLOG(GBA_HW, GAME_ERROR, "Invalid tilt sensor write to %04x: %02x", address, value);
560 break;
561 }
562}
563
564uint8_t GBAHardwareTiltRead(struct GBACartridgeHardware* hw, uint32_t address) {
565 switch (address) {
566 case 0x8200:
567 return hw->tiltX & 0xFF;
568 case 0x8300:
569 return ((hw->tiltX >> 8) & 0xF) | 0x80;
570 case 0x8400:
571 return hw->tiltY & 0xFF;
572 case 0x8500:
573 return (hw->tiltY >> 8) & 0xF;
574 default:
575 mLOG(GBA_HW, GAME_ERROR, "Invalid tilt sensor read from %04x", address);
576 break;
577 }
578 return 0xFF;
579}
580
581// == Game Boy Player
582
583static const uint16_t _logoPalette[] = {
584 0xFFDF, 0x640C, 0xE40C, 0xE42D, 0x644E, 0xE44E, 0xE46E, 0x68AF,
585 0xE8B0, 0x68D0, 0x68F0, 0x6911, 0xE911, 0x6D32, 0xED32, 0xED73,
586 0x6D93, 0xED94, 0x6DB4, 0xF1D5, 0x71F5, 0xF1F6, 0x7216, 0x7257,
587 0xF657, 0x7678, 0xF678, 0xF699, 0xF6B9, 0x76D9, 0xF6DA, 0x7B1B,
588 0xFB1B, 0xFB3C, 0x7B5C, 0x7B7D, 0xFF7D, 0x7F9D, 0x7FBE, 0x7FFF,
589 0x642D, 0x648E, 0xE88F, 0xE8F1, 0x6D52, 0x6D73, 0xF1B4, 0xF216,
590 0x7237, 0x7698, 0x7AFA, 0xFAFA, 0xFB5C, 0xFFBE, 0x7FDE, 0xFFFF,
591 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
592};
593
594static const uint32_t _logoHash = 0xEEDA6963;
595
596static const uint32_t _gbpTxData[] = {
597 0x0000494E, 0x0000494E,
598 0xB6B1494E, 0xB6B1544E,
599 0xABB1544E, 0xABB14E45,
600 0xB1BA4E45, 0xB1BA4F44,
601 0xB0BB4F44, 0xB0BB8002,
602 0x10000010, 0x20000013,
603 0x30000003
604};
605
606bool GBAHardwarePlayerCheckScreen(const struct GBAVideo* video) {
607 if (memcmp(video->palette, _logoPalette, sizeof(_logoPalette)) != 0) {
608 return false;
609 }
610 uint32_t hash = hash32(&video->renderer->vram[0x4000], 0x4000, 0);
611 return hash == _logoHash;
612}
613
614void GBAHardwarePlayerUpdate(struct GBA* gba) {
615 if (gba->memory.hw.devices & HW_GB_PLAYER) {
616 if (GBAHardwarePlayerCheckScreen(&gba->video)) {
617 ++gba->memory.hw.gbpInputsPosted;
618 gba->memory.hw.gbpInputsPosted %= 3;
619 gba->keyCallback = &gba->memory.hw.gbpCallback.d;
620 } else {
621 // TODO: Save and restore
622 gba->keyCallback = 0;
623 }
624 gba->memory.hw.gbpTxPosition = 0;
625 return;
626 }
627 if (gba->keyCallback || gba->sio.drivers.normal) {
628 return;
629 }
630 if (GBAHardwarePlayerCheckScreen(&gba->video)) {
631 gba->memory.hw.devices |= HW_GB_PLAYER;
632 gba->memory.hw.gbpInputsPosted = 0;
633 gba->keyCallback = &gba->memory.hw.gbpCallback.d;
634 GBASIOSetDriver(&gba->sio, &gba->memory.hw.gbpDriver.d, SIO_NORMAL_32);
635 }
636}
637
638uint16_t _gbpRead(struct mKeyCallback* callback) {
639 struct GBAGBPKeyCallback* gbpCallback = (struct GBAGBPKeyCallback*) callback;
640 if (gbpCallback->p->gbpInputsPosted == 2) {
641 return 0xF0;
642 }
643 return 0;
644}
645
646uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) {
647 struct GBAGBPSIODriver* gbp = (struct GBAGBPSIODriver*) driver;
648 if (address == REG_SIOCNT) {
649 if (value & 0x0080) {
650 uint32_t rx = gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] | (gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] << 16);
651 if (gbp->p->gbpTxPosition < 12 && gbp->p->gbpTxPosition > 0) {
652 // TODO: Check expected
653 } else if (gbp->p->gbpTxPosition >= 12) {
654 uint32_t mask = 0x33;
655 // 0x00 = Stop
656 // 0x11 = Hard Stop
657 // 0x22 = Start
658 if (gbp->p->p->rumble) {
659 gbp->p->p->rumble->setRumble(gbp->p->p->rumble, (rx & mask) == 0x22);
660 }
661 }
662 mTimingDeschedule(&gbp->p->p->timing, &gbp->p->gbpNextEvent);
663 mTimingSchedule(&gbp->p->p->timing, &gbp->p->gbpNextEvent, 2048);
664 }
665 value &= 0x78FB;
666 }
667 return value;
668}
669
670void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
671 UNUSED(timing);
672 UNUSED(cyclesLate);
673 struct GBAGBPSIODriver* gbp = user;
674 uint32_t tx = 0;
675 int txPosition = gbp->p->gbpTxPosition;
676 if (txPosition > 16) {
677 gbp->p->gbpTxPosition = 0;
678 txPosition = 0;
679 } else if (txPosition > 12) {
680 txPosition = 12;
681 }
682 tx = _gbpTxData[txPosition];
683 ++gbp->p->gbpTxPosition;
684 gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
685 gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
686 if (GBASIONormalIsIrq(gbp->d.p->siocnt)) {
687 GBARaiseIRQ(gbp->p->p, IRQ_SIO, cyclesLate);
688 }
689 gbp->d.p->siocnt = GBASIONormalClearStart(gbp->d.p->siocnt);
690 gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080;
691}
692
693// == e-Reader
694
695void GBAHardwareInitEReader(struct GBACartridgeHardware* hw) {
696 hw->devices |= HW_EREADER;
697 _eReaderReset(hw);
698
699 if (hw->p->memory.savedata.data[0xD000] == 0xFF) {
700 memset(&hw->p->memory.savedata.data[0xD000], 0, 0x1000);
701 memcpy(&hw->p->memory.savedata.data[0xD000], EREADER_CALIBRATION_TEMPLATE, sizeof(EREADER_CALIBRATION_TEMPLATE));
702 }
703 if (hw->p->memory.savedata.data[0xE000] == 0xFF) {
704 memset(&hw->p->memory.savedata.data[0xE000], 0, 0x1000);
705 memcpy(&hw->p->memory.savedata.data[0xE000], EREADER_CALIBRATION_TEMPLATE, sizeof(EREADER_CALIBRATION_TEMPLATE));
706 }
707}
708
709void GBAHardwareEReaderWrite(struct GBACartridgeHardware* hw, uint32_t address, uint16_t value) {
710 address &= 0x700FF;
711 switch (address >> 17) {
712 case 0:
713 hw->eReaderRegisterUnk = value & 0xF;
714 break;
715 case 1:
716 hw->eReaderRegisterReset = (value & 0x8A) | 4;
717 if (value & 2) {
718 _eReaderReset(hw);
719 }
720 break;
721 case 2:
722 mLOG(GBA_HW, GAME_ERROR, "e-Reader write to read-only registers: %05X:%04X", address, value);
723 break;
724 default:
725 mLOG(GBA_HW, STUB, "Unimplemented e-Reader write: %05X:%04X", address, value);
726 }
727}
728
729void GBAHardwareEReaderWriteFlash(struct GBACartridgeHardware* hw, uint32_t address, uint8_t value) {
730 address &= 0xFFFF;
731 switch (address) {
732 case 0xFFB0:
733 _eReaderWriteControl0(hw, value);
734 break;
735 case 0xFFB1:
736 _eReaderWriteControl1(hw, value);
737 break;
738 case 0xFFB2:
739 hw->eReaderRegisterLed &= 0xFF00;
740 hw->eReaderRegisterLed |= value;
741 break;
742 case 0xFFB3:
743 hw->eReaderRegisterLed &= 0x00FF;
744 hw->eReaderRegisterLed |= value << 8;
745 break;
746 default:
747 mLOG(GBA_HW, STUB, "Unimplemented e-Reader write to flash: %04X:%02X", address, value);
748 }
749}
750
751uint16_t GBAHardwareEReaderRead(struct GBACartridgeHardware* hw, uint32_t address) {
752 address &= 0x700FF;
753 uint16_t value;
754 switch (address >> 17) {
755 case 0:
756 return hw->eReaderRegisterUnk;
757 case 1:
758 return hw->eReaderRegisterReset;
759 case 2:
760 if (address > 0x40088) {
761 return 0;
762 }
763 LOAD_16(value, address & 0xFE, hw->eReaderData);
764 return value;
765 }
766 mLOG(GBA_HW, STUB, "Unimplemented e-Reader read: %05X", address);
767 return 0;
768}
769
770uint8_t GBAHardwareEReaderReadFlash(struct GBACartridgeHardware* hw, uint32_t address) {
771 address &= 0xFFFF;
772 switch (address) {
773 case 0xFFB0:
774 return hw->eReaderRegisterControl0;
775 case 0xFFB1:
776 return hw->eReaderRegisterControl1;
777 default:
778 mLOG(GBA_HW, STUB, "Unimplemented e-Reader read from flash: %04X", address);
779 return 0;
780 }
781}
782
783static void _eReaderAnchor(uint8_t* origin) {
784 origin[EREADER_DOTCODE_STRIDE * 0 + 1] = 1;
785 origin[EREADER_DOTCODE_STRIDE * 0 + 2] = 1;
786 origin[EREADER_DOTCODE_STRIDE * 0 + 3] = 1;
787 origin[EREADER_DOTCODE_STRIDE * 1 + 0] = 1;
788 origin[EREADER_DOTCODE_STRIDE * 1 + 1] = 1;
789 origin[EREADER_DOTCODE_STRIDE * 1 + 2] = 1;
790 origin[EREADER_DOTCODE_STRIDE * 1 + 3] = 1;
791 origin[EREADER_DOTCODE_STRIDE * 1 + 4] = 1;
792 origin[EREADER_DOTCODE_STRIDE * 2 + 0] = 1;
793 origin[EREADER_DOTCODE_STRIDE * 2 + 1] = 1;
794 origin[EREADER_DOTCODE_STRIDE * 2 + 2] = 1;
795 origin[EREADER_DOTCODE_STRIDE * 2 + 3] = 1;
796 origin[EREADER_DOTCODE_STRIDE * 2 + 4] = 1;
797 origin[EREADER_DOTCODE_STRIDE * 3 + 0] = 1;
798 origin[EREADER_DOTCODE_STRIDE * 3 + 1] = 1;
799 origin[EREADER_DOTCODE_STRIDE * 3 + 2] = 1;
800 origin[EREADER_DOTCODE_STRIDE * 3 + 3] = 1;
801 origin[EREADER_DOTCODE_STRIDE * 3 + 4] = 1;
802 origin[EREADER_DOTCODE_STRIDE * 4 + 1] = 1;
803 origin[EREADER_DOTCODE_STRIDE * 4 + 2] = 1;
804 origin[EREADER_DOTCODE_STRIDE * 4 + 3] = 1;
805}
806
807static void _eReaderAlignment(uint8_t* origin) {
808 origin[8] = 1;
809 origin[10] = 1;
810 origin[12] = 1;
811 origin[14] = 1;
812 origin[16] = 1;
813 origin[18] = 1;
814 origin[21] = 1;
815 origin[23] = 1;
816 origin[25] = 1;
817 origin[27] = 1;
818 origin[29] = 1;
819 origin[31] = 1;
820}
821
822static void _eReaderAddress(uint8_t* origin, int a) {
823 origin[EREADER_DOTCODE_STRIDE * 7 + 2] = 1;
824 uint16_t addr = EREADER_ADDRESS_CODES[a];
825 int i;
826 for (i = 0; i < 16; ++i) {
827 origin[EREADER_DOTCODE_STRIDE * (16 + i) + 2] = (addr >> (15 - i)) & 1;
828 }
829}
830
831void GBAHardwareEReaderScan(struct GBACartridgeHardware* hw, const void* data, size_t size) {
832 if (!hw->eReaderDots) {
833 hw->eReaderDots = anonymousMemoryMap(EREADER_DOTCODE_SIZE);
834 }
835 memset(hw->eReaderDots, 0, EREADER_DOTCODE_SIZE);
836
837 int base;
838 switch (size) {
839 case 2912:
840 base = 25;
841 break;
842 case 1872:
843 base = 1;
844 break;
845 default:
846 return;
847 }
848
849 size_t i;
850 for (i = 0; i < (size / 104) + 1; ++i) {
851 uint8_t* origin = &hw->eReaderDots[35 * i + 200];
852 _eReaderAnchor(&origin[EREADER_DOTCODE_STRIDE * 0]);
853 _eReaderAnchor(&origin[EREADER_DOTCODE_STRIDE * 35]);
854 _eReaderAddress(origin, base + i);
855 }
856 for (i = 0; i < size / 104; ++i) {
857 uint8_t block[1040];
858 uint8_t* origin = &hw->eReaderDots[35 * i + 200];
859 _eReaderAlignment(&origin[EREADER_DOTCODE_STRIDE * 2]);
860 _eReaderAlignment(&origin[EREADER_DOTCODE_STRIDE * 37]);
861
862 int b;
863 for (b = 0; b < 104; ++b) {
864 const int* nybble5;
865 nybble5 = EREADER_NYBBLE_5BIT[((const uint8_t*) data)[i * 104 + b] >> 4];
866 block[b * 10 + 0] = nybble5[0];
867 block[b * 10 + 1] = nybble5[1];
868 block[b * 10 + 2] = nybble5[2];
869 block[b * 10 + 3] = nybble5[3];
870 block[b * 10 + 4] = nybble5[4];
871 nybble5 = EREADER_NYBBLE_5BIT[((const uint8_t*) data)[i * 104 + b] & 0xF];
872 block[b * 10 + 5] = nybble5[0];
873 block[b * 10 + 6] = nybble5[1];
874 block[b * 10 + 7] = nybble5[2];
875 block[b * 10 + 8] = nybble5[3];
876 block[b * 10 + 9] = nybble5[4];
877 }
878
879 b = 0;
880 int y;
881 for (y = 0; y < 3; ++y) {
882 memcpy(&origin[EREADER_DOTCODE_STRIDE * (4 + y) + 7], &block[b], 26);
883 b += 26;
884 }
885 for (y = 0; y < 26; ++y) {
886 memcpy(&origin[EREADER_DOTCODE_STRIDE * (7 + y) + 3], &block[b], 34);
887 b += 34;
888 }
889 for (y = 0; y < 3; ++y) {
890 memcpy(&origin[EREADER_DOTCODE_STRIDE * (33 + y) + 7], &block[b], 26);
891 b += 26;
892 }
893 }
894 hw->eReaderX = -24;
895}
896
897void _eReaderReset(struct GBACartridgeHardware* hw) {
898 memset(hw->eReaderData, 0, sizeof(hw->eReaderData));
899 hw->eReaderRegisterUnk = 0;
900 hw->eReaderRegisterReset = 4;
901 hw->eReaderRegisterControl0 = 0;
902 hw->eReaderRegisterControl1 = 0x80;
903 hw->eReaderRegisterLed = 0;
904 hw->eReaderState = 0;
905 hw->eReaderActiveRegister = 0;
906}
907
908void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value) {
909 EReaderControl0 control = value & 0x7F;
910 EReaderControl0 oldControl = hw->eReaderRegisterControl0;
911 if (hw->eReaderState == EREADER_SERIAL_INACTIVE) {
912 if (EReaderControl0IsClock(oldControl) && EReaderControl0IsData(oldControl) && !EReaderControl0IsData(control)) {
913 hw->eReaderState = EREADER_SERIAL_STARTING;
914 }
915 } else if (EReaderControl0IsClock(oldControl) && !EReaderControl0IsData(oldControl) && EReaderControl0IsData(control)) {
916 hw->eReaderState = EREADER_SERIAL_INACTIVE;
917
918 } else if (hw->eReaderState == EREADER_SERIAL_STARTING) {
919 if (EReaderControl0IsClock(oldControl) && !EReaderControl0IsData(oldControl) && !EReaderControl0IsClock(control)) {
920 hw->eReaderState = EREADER_SERIAL_BIT_0;
921 hw->eReaderCommand = EREADER_COMMAND_IDLE;
922 }
923 } else if (EReaderControl0IsClock(oldControl) && !EReaderControl0IsClock(control)) {
924 mLOG(GBA_HW, DEBUG, "[e-Reader] Serial falling edge: %c %i", EReaderControl0IsDirection(control) ? '>' : '<', EReaderControl0GetData(control));
925 // TODO: Improve direction control
926 if (EReaderControl0IsDirection(control)) {
927 hw->eReaderByte |= EReaderControl0GetData(control) << (7 - (hw->eReaderState - EREADER_SERIAL_BIT_0));
928 ++hw->eReaderState;
929 if (hw->eReaderState == EREADER_SERIAL_END_BIT) {
930 mLOG(GBA_HW, DEBUG, "[e-Reader] Wrote serial byte: %02x", hw->eReaderByte);
931 switch (hw->eReaderCommand) {
932 case EREADER_COMMAND_IDLE:
933 hw->eReaderCommand = hw->eReaderByte;
934 break;
935 case EREADER_COMMAND_SET_INDEX:
936 hw->eReaderActiveRegister = hw->eReaderByte;
937 hw->eReaderCommand = EREADER_COMMAND_WRITE_DATA;
938 break;
939 case EREADER_COMMAND_WRITE_DATA:
940 switch (hw->eReaderActiveRegister & 0x7F) {
941 case 0:
942 case 0x57:
943 case 0x58:
944 case 0x59:
945 case 0x5A:
946 // Read-only
947 mLOG(GBA_HW, GAME_ERROR, "Writing to read-only e-Reader serial register: %02X", hw->eReaderActiveRegister);
948 break;
949 default:
950 if ((hw->eReaderActiveRegister & 0x7F) > 0x5A) {
951 mLOG(GBA_HW, GAME_ERROR, "Writing to non-existent e-Reader serial register: %02X", hw->eReaderActiveRegister);
952 break;
953 }
954 hw->eReaderSerial[hw->eReaderActiveRegister & 0x7F] = hw->eReaderByte;
955 break;
956 }
957 ++hw->eReaderActiveRegister;
958 break;
959 default:
960 mLOG(GBA_HW, ERROR, "Hit undefined state %02X in e-Reader state machine", hw->eReaderCommand);
961 break;
962 }
963 hw->eReaderState = EREADER_SERIAL_BIT_0;
964 hw->eReaderByte = 0;
965 }
966 } else if (hw->eReaderCommand == EREADER_COMMAND_READ_DATA) {
967 int bit = hw->eReaderSerial[hw->eReaderActiveRegister & 0x7F] >> (7 - (hw->eReaderState - EREADER_SERIAL_BIT_0));
968 control = EReaderControl0SetData(control, bit);
969 ++hw->eReaderState;
970 if (hw->eReaderState == EREADER_SERIAL_END_BIT) {
971 ++hw->eReaderActiveRegister;
972 mLOG(GBA_HW, DEBUG, "[e-Reader] Read serial byte: %02x", hw->eReaderSerial[hw->eReaderActiveRegister & 0x7F]);
973 }
974 }
975 } else if (!EReaderControl0IsDirection(control)) {
976 // Clear the error bit
977 control = EReaderControl0ClearData(control);
978 }
979 hw->eReaderRegisterControl0 = control;
980 if (!EReaderControl0IsScan(oldControl) && EReaderControl0IsScan(control)) {
981 hw->eReaderX = 0;
982 hw->eReaderY = 0;
983 _eReaderReadData(hw);
984 } else if (EReaderControl0IsLedEnable(control) && EReaderControl1IsScanline(hw->eReaderRegisterControl1)) {
985 GBARaiseIRQ(hw->p, IRQ_GAMEPAK, 0);
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 += 225;
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}