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