src/gba/io.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 "io.h"
7
8#include "gba/rr/rr.h"
9#include "gba/serialize.h"
10#include "gba/sio.h"
11#include "gba/video.h"
12
13mLOG_DEFINE_CATEGORY(GBA_IO, "GBA I/O");
14
15const char* const GBAIORegisterNames[] = {
16 // Video
17 "DISPCNT",
18 0,
19 "DISPSTAT",
20 "VCOUNT",
21 "BG0CNT",
22 "BG1CNT",
23 "BG2CNT",
24 "BG3CNT",
25 "BG0HOFS",
26 "BG0VOFS",
27 "BG1HOFS",
28 "BG1VOFS",
29 "BG2HOFS",
30 "BG2VOFS",
31 "BG3HOFS",
32 "BG3VOFS",
33 "BG2PA",
34 "BG2PB",
35 "BG2PC",
36 "BG2PD",
37 "BG2X_LO",
38 "BG2X_HI",
39 "BG2Y_LO",
40 "BG2Y_HI",
41 "BG3PA",
42 "BG3PB",
43 "BG3PC",
44 "BG3PD",
45 "BG3X_LO",
46 "BG3X_HI",
47 "BG3Y_LO",
48 "BG3Y_HI",
49 "WIN0H",
50 "WIN1H",
51 "WIN0V",
52 "WIN1V",
53 "WININ",
54 "WINOUT",
55 "MOSAIC",
56 0,
57 "BLDCNT",
58 "BLDALPHA",
59 "BLDY",
60 0,
61 0,
62 0,
63 0,
64 0,
65
66 // Sound
67 "SOUND1CNT_LO",
68 "SOUND1CNT_HI",
69 "SOUND1CNT_X",
70 0,
71 "SOUND2CNT_LO",
72 0,
73 "SOUND2CNT_HI",
74 0,
75 "SOUND3CNT_LO",
76 "SOUND3CNT_HI",
77 "SOUND3CNT_X",
78 0,
79 "SOUND4CNT_LO",
80 0,
81 "SOUND4CNT_HI",
82 0,
83 "SOUNDCNT_LO",
84 "SOUNDCNT_HI",
85 "SOUNDCNT_X",
86 0,
87 "SOUNDBIAS",
88 0,
89 0,
90 0,
91 "WAVE_RAM0_LO",
92 "WAVE_RAM0_HI",
93 "WAVE_RAM1_LO",
94 "WAVE_RAM1_HI",
95 "WAVE_RAM2_LO",
96 "WAVE_RAM2_HI",
97 "WAVE_RAM3_LO",
98 "WAVE_RAM3_HI",
99 "FIFO_A_LO",
100 "FIFO_A_HI",
101 "FIFO_B_LO",
102 "FIFO_B_HI",
103 0,
104 0,
105 0,
106 0,
107
108 // DMA
109 "DMA0SAD_LO",
110 "DMA0SAD_HI",
111 "DMA0DAD_LO",
112 "DMA0DAD_HI",
113 "DMA0CNT_LO",
114 "DMA0CNT_HI",
115 "DMA1SAD_LO",
116 "DMA1SAD_HI",
117 "DMA1DAD_LO",
118 "DMA1DAD_HI",
119 "DMA1CNT_LO",
120 "DMA1CNT_HI",
121 "DMA2SAD_LO",
122 "DMA2SAD_HI",
123 "DMA2DAD_LO",
124 "DMA2DAD_HI",
125 "DMA2CNT_LO",
126 "DMA2CNT_HI",
127 "DMA3SAD_LO",
128 "DMA3SAD_HI",
129 "DMA3DAD_LO",
130 "DMA3DAD_HI",
131 "DMA3CNT_LO",
132 "DMA3CNT_HI",
133
134 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0,
136
137 // Timers
138 "TM0CNT_LO",
139 "TM0CNT_HI",
140 "TM1CNT_LO",
141 "TM1CNT_HI",
142 "TM2CNT_LO",
143 "TM2CNT_HI",
144 "TM3CNT_LO",
145 "TM3CNT_HI",
146
147 0, 0, 0, 0, 0, 0, 0, 0,
148
149 // SIO
150 "SIOMULTI0",
151 "SIOMULTI1",
152 "SIOMULTI2",
153 "SIOMULTI3",
154 "SIOCNT",
155 "SIOMLT_SEND",
156 0,
157 0,
158 "KEYINPUT",
159 "KEYCNT",
160 "RCNT",
161 0,
162 0,
163 0,
164 0,
165 0,
166 "JOYCNT",
167 0,
168 0,
169 0,
170 0,
171 0,
172 0,
173 0,
174 "JOY_RECV_LO",
175 "JOY_RECV_HI",
176 "JOY_TRANS_LO",
177 "JOY_TRANS_HI",
178 "JOYSTAT",
179 0,
180 0,
181 0,
182
183 0, 0, 0, 0, 0, 0, 0, 0,
184 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0,
188 0, 0, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0,
190 0, 0, 0, 0, 0, 0, 0, 0,
191 0, 0, 0, 0, 0, 0, 0, 0,
192 0, 0, 0, 0, 0, 0, 0, 0,
193
194 // Interrupts, etc
195 "IE",
196 "IF",
197 "WAITCNT",
198 0,
199 "IME"
200};
201
202static const int _isValidRegister[REG_MAX >> 1] = {
203 // Video
204 1, 0, 1, 1, 1, 1, 1, 1,
205 1, 1, 1, 1, 1, 1, 1, 1,
206 1, 1, 1, 1, 1, 1, 1, 1,
207 1, 1, 1, 1, 1, 1, 1, 1,
208 1, 1, 1, 1, 1, 1, 1, 0,
209 1, 1, 1, 0, 0, 0, 0, 0,
210 // Audio
211 1, 1, 1, 0, 1, 0, 1, 0,
212 1, 1, 1, 0, 1, 0, 1, 0,
213 1, 1, 1, 0, 1, 0, 0, 0,
214 1, 1, 1, 1, 1, 1, 1, 1,
215 1, 1, 1, 1, 0, 0, 0, 0,
216 // DMA
217 1, 1, 1, 1, 1, 1, 1, 1,
218 1, 1, 1, 1, 1, 1, 1, 1,
219 1, 1, 1, 1, 1, 1, 1, 1,
220 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0,
222 // Timers
223 1, 1, 1, 1, 1, 1, 1, 1,
224 0, 0, 0, 0, 0, 0, 0, 0,
225 // SIO
226 1, 1, 1, 1, 1, 0, 0, 0,
227 1, 1, 1, 0, 0, 0, 0, 0,
228 1, 0, 0, 0, 0, 0, 0, 0,
229 1, 0, 1, 0, 1, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0,
235 0, 0, 0, 0, 0, 0, 0, 0,
236 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0, 0, 0, 0,
240 // Interrupts
241 1, 1, 1, 0, 1
242};
243
244static const int _isRSpecialRegister[REG_MAX >> 1] = {
245 // Video
246 0, 0, 1, 1, 0, 0, 0, 0,
247 1, 1, 1, 1, 1, 1, 1, 1,
248 1, 1, 1, 1, 1, 1, 1, 1,
249 1, 1, 1, 1, 1, 1, 1, 1,
250 1, 1, 1, 1, 1, 1, 1, 1,
251 1, 1, 1, 1, 1, 1, 1, 1,
252 // Audio
253 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 1, 0, 0, 0,
256 1, 1, 1, 1, 1, 1, 1, 1,
257 1, 1, 1, 1, 0, 0, 0, 0,
258 // DMA
259 1, 1, 1, 1, 1, 1, 1, 1,
260 1, 1, 1, 1, 1, 1, 1, 1,
261 1, 1, 1, 1, 1, 1, 1, 1,
262 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0,
264 // Timers
265 1, 1, 1, 1, 1, 1, 1, 1,
266 0, 0, 0, 0, 0, 0, 0, 0,
267 // SIO
268 1, 1, 1, 1, 1, 0, 0, 0,
269 1, 1, 1, 0, 0, 0, 0, 0,
270 1, 0, 0, 0, 0, 0, 0, 0,
271 1, 0, 1, 0, 1, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0,
275 0, 0, 0, 0, 0, 0, 0, 0,
276 0, 0, 0, 0, 0, 0, 0, 0,
277 0, 0, 0, 0, 0, 0, 0, 0,
278 0, 0, 0, 0, 0, 0, 0, 0,
279 0, 0, 0, 0, 0, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 0, 0,
281 0, 0, 0, 0, 0, 0, 0, 0,
282 // Interrupts
283};
284
285static const int _isWSpecialRegister[REG_MAX >> 1] = {
286 // Video
287 0, 0, 1, 1, 0, 0, 0, 0,
288 0, 0, 0, 0, 0, 0, 0, 0,
289 0, 0, 0, 0, 0, 0, 0, 0,
290 0, 0, 0, 0, 0, 0, 0, 0,
291 0, 0, 0, 0, 0, 0, 0, 0,
292 0, 0, 0, 0, 0, 0, 0, 0,
293 // Audio
294 0, 0, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, 0, 0, 0, 0, 0,
296 0, 0, 1, 0, 0, 0, 0, 0,
297 1, 1, 1, 1, 1, 1, 1, 1,
298 1, 1, 1, 1, 0, 0, 0, 0,
299 // DMA
300 0, 0, 0, 0, 0, 1, 0, 0,
301 0, 0, 0, 1, 0, 0, 0, 0,
302 0, 1, 0, 0, 0, 0, 0, 1,
303 0, 0, 0, 0, 0, 0, 0, 0,
304 0, 0, 0, 0, 0, 0, 0, 0,
305 // Timers
306 1, 1, 1, 1, 1, 1, 1, 1,
307 0, 0, 0, 0, 0, 0, 0, 0,
308 // SIO
309 1, 1, 1, 1, 1, 0, 0, 0,
310 1, 1, 1, 0, 0, 0, 0, 0,
311 1, 0, 0, 0, 0, 0, 0, 0,
312 1, 0, 1, 0, 1, 0, 0, 0,
313 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0,
315 0, 0, 0, 0, 0, 0, 0, 0,
316 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 0, 0,
323 // Interrupts
324 1, 1, 0, 0, 1
325};
326
327void GBAIOInit(struct GBA* gba) {
328 gba->memory.io[REG_DISPCNT >> 1] = 0x0080;
329 gba->memory.io[REG_RCNT >> 1] = RCNT_INITIAL;
330 gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF;
331 gba->memory.io[REG_SOUNDBIAS >> 1] = 0x200;
332 gba->memory.io[REG_BG2PA >> 1] = 0x100;
333 gba->memory.io[REG_BG2PD >> 1] = 0x100;
334 gba->memory.io[REG_BG3PA >> 1] = 0x100;
335 gba->memory.io[REG_BG3PD >> 1] = 0x100;
336}
337
338void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
339 if (address < REG_SOUND1CNT_LO && address != REG_DISPSTAT) {
340 value = gba->video.renderer->writeVideoRegister(gba->video.renderer, address, value);
341 } else {
342 switch (address) {
343 // Video
344 case REG_DISPSTAT:
345 value &= 0xFFF8;
346 GBAVideoWriteDISPSTAT(&gba->video, value);
347 return;
348
349 // Audio
350 case REG_SOUND1CNT_LO:
351 GBAAudioWriteSOUND1CNT_LO(&gba->audio, value);
352 value &= 0x007F;
353 break;
354 case REG_SOUND1CNT_HI:
355 GBAAudioWriteSOUND1CNT_HI(&gba->audio, value);
356 break;
357 case REG_SOUND1CNT_X:
358 GBAAudioWriteSOUND1CNT_X(&gba->audio, value);
359 value &= 0x47FF;
360 break;
361 case REG_SOUND2CNT_LO:
362 GBAAudioWriteSOUND2CNT_LO(&gba->audio, value);
363 break;
364 case REG_SOUND2CNT_HI:
365 GBAAudioWriteSOUND2CNT_HI(&gba->audio, value);
366 value &= 0x47FF;
367 break;
368 case REG_SOUND3CNT_LO:
369 GBAAudioWriteSOUND3CNT_LO(&gba->audio, value);
370 value &= 0x00E0;
371 break;
372 case REG_SOUND3CNT_HI:
373 GBAAudioWriteSOUND3CNT_HI(&gba->audio, value);
374 value &= 0xE03F;
375 break;
376 case REG_SOUND3CNT_X:
377 GBAAudioWriteSOUND3CNT_X(&gba->audio, value);
378 // TODO: The low bits need to not be readable, but still 8-bit writable
379 value &= 0x47FF;
380 break;
381 case REG_SOUND4CNT_LO:
382 GBAAudioWriteSOUND4CNT_LO(&gba->audio, value);
383 value &= 0xFF3F;
384 break;
385 case REG_SOUND4CNT_HI:
386 GBAAudioWriteSOUND4CNT_HI(&gba->audio, value);
387 value &= 0x40FF;
388 break;
389 case REG_SOUNDCNT_LO:
390 GBAAudioWriteSOUNDCNT_LO(&gba->audio, value);
391 value &= 0xFF77;
392 break;
393 case REG_SOUNDCNT_HI:
394 GBAAudioWriteSOUNDCNT_HI(&gba->audio, value);
395 value &= 0x770F;
396 break;
397 case REG_SOUNDCNT_X:
398 GBAAudioWriteSOUNDCNT_X(&gba->audio, value);
399 value &= 0x0080;
400 value |= gba->memory.io[REG_SOUNDCNT_X >> 1] & 0xF;
401 break;
402 case REG_SOUNDBIAS:
403 GBAAudioWriteSOUNDBIAS(&gba->audio, value);
404 break;
405
406 case REG_WAVE_RAM0_LO:
407 case REG_WAVE_RAM1_LO:
408 case REG_WAVE_RAM2_LO:
409 case REG_WAVE_RAM3_LO:
410 GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
411 break;
412
413 case REG_WAVE_RAM0_HI:
414 case REG_WAVE_RAM1_HI:
415 case REG_WAVE_RAM2_HI:
416 case REG_WAVE_RAM3_HI:
417 GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
418 break;
419
420 case REG_FIFO_A_LO:
421 case REG_FIFO_B_LO:
422 GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
423 break;
424
425 case REG_FIFO_A_HI:
426 case REG_FIFO_B_HI:
427 GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
428 break;
429
430 // DMA
431 case REG_DMA0SAD_LO:
432 case REG_DMA0DAD_LO:
433 case REG_DMA1SAD_LO:
434 case REG_DMA1DAD_LO:
435 case REG_DMA2SAD_LO:
436 case REG_DMA2DAD_LO:
437 case REG_DMA3SAD_LO:
438 case REG_DMA3DAD_LO:
439 GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
440 break;
441
442 case REG_DMA0SAD_HI:
443 case REG_DMA0DAD_HI:
444 case REG_DMA1SAD_HI:
445 case REG_DMA1DAD_HI:
446 case REG_DMA2SAD_HI:
447 case REG_DMA2DAD_HI:
448 case REG_DMA3SAD_HI:
449 case REG_DMA3DAD_HI:
450 GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
451 break;
452
453 case REG_DMA0CNT_LO:
454 GBAMemoryWriteDMACNT_LO(gba, 0, value);
455 break;
456 case REG_DMA0CNT_HI:
457 value = GBAMemoryWriteDMACNT_HI(gba, 0, value);
458 break;
459 case REG_DMA1CNT_LO:
460 GBAMemoryWriteDMACNT_LO(gba, 1, value);
461 break;
462 case REG_DMA1CNT_HI:
463 value = GBAMemoryWriteDMACNT_HI(gba, 1, value);
464 break;
465 case REG_DMA2CNT_LO:
466 GBAMemoryWriteDMACNT_LO(gba, 2, value);
467 break;
468 case REG_DMA2CNT_HI:
469 value = GBAMemoryWriteDMACNT_HI(gba, 2, value);
470 break;
471 case REG_DMA3CNT_LO:
472 GBAMemoryWriteDMACNT_LO(gba, 3, value);
473 break;
474 case REG_DMA3CNT_HI:
475 value = GBAMemoryWriteDMACNT_HI(gba, 3, value);
476 break;
477
478 // Timers
479 case REG_TM0CNT_LO:
480 GBATimerWriteTMCNT_LO(gba, 0, value);
481 return;
482 case REG_TM1CNT_LO:
483 GBATimerWriteTMCNT_LO(gba, 1, value);
484 return;
485 case REG_TM2CNT_LO:
486 GBATimerWriteTMCNT_LO(gba, 2, value);
487 return;
488 case REG_TM3CNT_LO:
489 GBATimerWriteTMCNT_LO(gba, 3, value);
490 return;
491
492 case REG_TM0CNT_HI:
493 value &= 0x00C7;
494 GBATimerWriteTMCNT_HI(gba, 0, value);
495 break;
496 case REG_TM1CNT_HI:
497 value &= 0x00C7;
498 GBATimerWriteTMCNT_HI(gba, 1, value);
499 break;
500 case REG_TM2CNT_HI:
501 value &= 0x00C7;
502 GBATimerWriteTMCNT_HI(gba, 2, value);
503 break;
504 case REG_TM3CNT_HI:
505 value &= 0x00C7;
506 GBATimerWriteTMCNT_HI(gba, 3, value);
507 break;
508
509 // SIO
510 case REG_SIOCNT:
511 GBASIOWriteSIOCNT(&gba->sio, value);
512 break;
513 case REG_RCNT:
514 value &= 0xC1FF;
515 GBASIOWriteRCNT(&gba->sio, value);
516 break;
517 case REG_SIOMLT_SEND:
518 case REG_JOYCNT:
519 case REG_JOYSTAT:
520 case REG_JOY_RECV_LO:
521 case REG_JOY_RECV_HI:
522 case REG_JOY_TRANS_LO:
523 case REG_JOY_TRANS_HI:
524 value = GBASIOWriteRegister(&gba->sio, address, value);
525 break;
526
527 // Interrupts and misc
528 case REG_WAITCNT:
529 GBAAdjustWaitstates(gba, value);
530 break;
531 case REG_IE:
532 GBAWriteIE(gba, value);
533 break;
534 case REG_IF:
535 value = gba->memory.io[REG_IF >> 1] & ~value;
536 break;
537 case REG_IME:
538 GBAWriteIME(gba, value);
539 break;
540 case REG_MAX:
541 // Some bad interrupt libraries will write to this
542 break;
543 case REG_DEBUG_ENABLE:
544 gba->debug = value == 0xC0DE;
545 return;
546 case REG_DEBUG_FLAGS:
547 if (gba->debug) {
548 GBADebug(gba, value);
549 return;
550 }
551 // Fall through
552 default:
553 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
554 STORE_16LE(value, address - REG_DEBUG_STRING, gba->debugString);
555 return;
556 }
557 mLOG(GBA_IO, STUB, "Stub I/O register write: %03X", address);
558 if (address >= REG_MAX) {
559 mLOG(GBA_IO, GAME_ERROR, "Write to unused I/O register: %03X", address);
560 return;
561 }
562 break;
563 }
564 }
565 gba->memory.io[address >> 1] = value;
566}
567
568void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
569 if (address == REG_HALTCNT) {
570 value &= 0x80;
571 if (!value) {
572 GBAHalt(gba);
573 } else {
574 GBAStop(gba);
575 }
576 return;
577 }
578 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
579 gba->debugString[address - REG_DEBUG_STRING] = value;
580 return;
581 }
582 if (address > SIZE_IO) {
583 return;
584 }
585 uint16_t value16 = value << (8 * (address & 1));
586 value16 |= (gba->memory.io[(address & (SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1)));
587 GBAIOWrite(gba, address & 0xFFFFFFFE, value16);
588}
589
590void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
591 switch (address) {
592 case REG_WAVE_RAM0_LO:
593 GBAAudioWriteWaveRAM(&gba->audio, 0, value);
594 break;
595 case REG_WAVE_RAM1_LO:
596 GBAAudioWriteWaveRAM(&gba->audio, 1, value);
597 break;
598 case REG_WAVE_RAM2_LO:
599 GBAAudioWriteWaveRAM(&gba->audio, 2, value);
600 break;
601 case REG_WAVE_RAM3_LO:
602 GBAAudioWriteWaveRAM(&gba->audio, 3, value);
603 break;
604 case REG_FIFO_A_LO:
605 case REG_FIFO_B_LO:
606 GBAAudioWriteFIFO(&gba->audio, address, value);
607 break;
608 case REG_DMA0SAD_LO:
609 value = GBAMemoryWriteDMASAD(gba, 0, value);
610 break;
611 case REG_DMA0DAD_LO:
612 value = GBAMemoryWriteDMADAD(gba, 0, value);
613 break;
614 case REG_DMA1SAD_LO:
615 value = GBAMemoryWriteDMASAD(gba, 1, value);
616 break;
617 case REG_DMA1DAD_LO:
618 value = GBAMemoryWriteDMADAD(gba, 1, value);
619 break;
620 case REG_DMA2SAD_LO:
621 value = GBAMemoryWriteDMASAD(gba, 2, value);
622 break;
623 case REG_DMA2DAD_LO:
624 value = GBAMemoryWriteDMADAD(gba, 2, value);
625 break;
626 case REG_DMA3SAD_LO:
627 value = GBAMemoryWriteDMASAD(gba, 3, value);
628 break;
629 case REG_DMA3DAD_LO:
630 value = GBAMemoryWriteDMADAD(gba, 3, value);
631 break;
632 default:
633 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
634 STORE_32LE(value, address - REG_DEBUG_STRING, gba->debugString);
635 return;
636 }
637 GBAIOWrite(gba, address, value & 0xFFFF);
638 GBAIOWrite(gba, address | 2, value >> 16);
639 return;
640 }
641 gba->memory.io[address >> 1] = value;
642 gba->memory.io[(address >> 1) + 1] = value >> 16;
643}
644
645bool GBAIOIsReadConstant(uint32_t address) {
646 switch (address) {
647 default:
648 return false;
649 case REG_BG0CNT:
650 case REG_BG1CNT:
651 case REG_BG2CNT:
652 case REG_BG3CNT:
653 case REG_WININ:
654 case REG_WINOUT:
655 case REG_BLDCNT:
656 case REG_BLDALPHA:
657 case REG_SOUND1CNT_LO:
658 case REG_SOUND1CNT_HI:
659 case REG_SOUND1CNT_X:
660 case REG_SOUND2CNT_LO:
661 case REG_SOUND2CNT_HI:
662 case REG_SOUND3CNT_LO:
663 case REG_SOUND3CNT_HI:
664 case REG_SOUND3CNT_X:
665 case REG_SOUND4CNT_LO:
666 case REG_SOUND4CNT_HI:
667 case REG_SOUNDCNT_LO:
668 case REG_SOUNDCNT_HI:
669 case REG_TM0CNT_HI:
670 case REG_TM1CNT_HI:
671 case REG_TM2CNT_HI:
672 case REG_TM3CNT_HI:
673 case REG_KEYINPUT:
674 case REG_IE:
675 return true;
676 }
677}
678
679uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
680 if (!GBAIOIsReadConstant(address)) {
681 // Most IO reads need to disable idle removal
682 gba->haltPending = false;
683 }
684
685 switch (address) {
686 case REG_TM0CNT_LO:
687 GBATimerUpdateRegister(gba, 0);
688 break;
689 case REG_TM1CNT_LO:
690 GBATimerUpdateRegister(gba, 1);
691 break;
692 case REG_TM2CNT_LO:
693 GBATimerUpdateRegister(gba, 2);
694 break;
695 case REG_TM3CNT_LO:
696 GBATimerUpdateRegister(gba, 3);
697 break;
698
699 case REG_KEYINPUT:
700 if (gba->rr && gba->rr->isPlaying(gba->rr)) {
701 return 0x3FF ^ gba->rr->queryInput(gba->rr);
702 } else {
703 uint16_t input = 0x3FF;
704 if (gba->keyCallback) {
705 input = gba->keyCallback->readKeys(gba->keyCallback);
706 } else if (gba->keySource) {
707 input = *gba->keySource;
708 }
709 if (!gba->allowOpposingDirections) {
710 unsigned rl = input & 0x030;
711 unsigned ud = input & 0x0C0;
712 input &= 0x30F;
713 if (rl != 0x030) {
714 input |= rl;
715 }
716 if (ud != 0x0C0) {
717 input |= ud;
718 }
719 }
720 if (gba->rr && gba->rr->isRecording(gba->rr)) {
721 gba->rr->logInput(gba->rr, input);
722 }
723 return 0x3FF ^ input;
724 }
725
726 case REG_SIOCNT:
727 return gba->sio.siocnt;
728 case REG_RCNT:
729 return gba->sio.rcnt;
730
731 case REG_BG0HOFS:
732 case REG_BG0VOFS:
733 case REG_BG1HOFS:
734 case REG_BG1VOFS:
735 case REG_BG2HOFS:
736 case REG_BG2VOFS:
737 case REG_BG3HOFS:
738 case REG_BG3VOFS:
739 case REG_BG2PA:
740 case REG_BG2PB:
741 case REG_BG2PC:
742 case REG_BG2PD:
743 case REG_BG2X_LO:
744 case REG_BG2X_HI:
745 case REG_BG2Y_LO:
746 case REG_BG2Y_HI:
747 case REG_BG3PA:
748 case REG_BG3PB:
749 case REG_BG3PC:
750 case REG_BG3PD:
751 case REG_BG3X_LO:
752 case REG_BG3X_HI:
753 case REG_BG3Y_LO:
754 case REG_BG3Y_HI:
755 case REG_WIN0H:
756 case REG_WIN1H:
757 case REG_WIN0V:
758 case REG_WIN1V:
759 case REG_MOSAIC:
760 case REG_BLDY:
761 case REG_FIFO_A_LO:
762 case REG_FIFO_A_HI:
763 case REG_FIFO_B_LO:
764 case REG_FIFO_B_HI:
765 case REG_DMA0SAD_LO:
766 case REG_DMA0SAD_HI:
767 case REG_DMA0DAD_LO:
768 case REG_DMA0DAD_HI:
769 case REG_DMA1SAD_LO:
770 case REG_DMA1SAD_HI:
771 case REG_DMA1DAD_LO:
772 case REG_DMA1DAD_HI:
773 case REG_DMA2SAD_LO:
774 case REG_DMA2SAD_HI:
775 case REG_DMA2DAD_LO:
776 case REG_DMA2DAD_HI:
777 case REG_DMA3SAD_LO:
778 case REG_DMA3SAD_HI:
779 case REG_DMA3DAD_LO:
780 case REG_DMA3DAD_HI:
781 // Write-only register
782 mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address);
783 return GBALoadBad(gba->cpu);
784
785 case REG_DMA0CNT_LO:
786 case REG_DMA1CNT_LO:
787 case REG_DMA2CNT_LO:
788 case REG_DMA3CNT_LO:
789 // Write-only register
790 mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address);
791 return 0;
792
793 case REG_SOUNDBIAS:
794 case REG_KEYCNT:
795 case REG_POSTFLG:
796 mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address);
797 break;
798 case REG_SOUND1CNT_LO:
799 case REG_SOUND1CNT_HI:
800 case REG_SOUND1CNT_X:
801 case REG_SOUND2CNT_LO:
802 case REG_SOUND2CNT_HI:
803 case REG_SOUND3CNT_LO:
804 case REG_SOUND3CNT_HI:
805 case REG_SOUND3CNT_X:
806 case REG_SOUND4CNT_LO:
807 case REG_SOUND4CNT_HI:
808 case REG_SOUNDCNT_LO:
809 case REG_SOUNDCNT_HI:
810 if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
811 // TODO: Is writing allowed when the circuit is disabled?
812 return 0;
813 }
814 // Fall through
815 case REG_DISPCNT:
816 case REG_DISPSTAT:
817 case REG_VCOUNT:
818 case REG_BG0CNT:
819 case REG_BG1CNT:
820 case REG_BG2CNT:
821 case REG_BG3CNT:
822 case REG_WININ:
823 case REG_WINOUT:
824 case REG_BLDCNT:
825 case REG_BLDALPHA:
826 case REG_SOUNDCNT_X:
827 case REG_WAVE_RAM0_LO:
828 case REG_WAVE_RAM0_HI:
829 case REG_WAVE_RAM1_LO:
830 case REG_WAVE_RAM1_HI:
831 case REG_WAVE_RAM2_LO:
832 case REG_WAVE_RAM2_HI:
833 case REG_WAVE_RAM3_LO:
834 case REG_WAVE_RAM3_HI:
835 case REG_DMA0CNT_HI:
836 case REG_DMA1CNT_HI:
837 case REG_DMA2CNT_HI:
838 case REG_DMA3CNT_HI:
839 case REG_TM0CNT_HI:
840 case REG_TM1CNT_HI:
841 case REG_TM2CNT_HI:
842 case REG_TM3CNT_HI:
843 case REG_SIOMULTI0:
844 case REG_SIOMULTI1:
845 case REG_SIOMULTI2:
846 case REG_SIOMULTI3:
847 case REG_SIOMLT_SEND:
848 case REG_JOYCNT:
849 case REG_JOY_RECV_LO:
850 case REG_JOY_RECV_HI:
851 case REG_JOY_TRANS_LO:
852 case REG_JOY_TRANS_HI:
853 case REG_JOYSTAT:
854 case REG_IE:
855 case REG_IF:
856 case REG_WAITCNT:
857 case REG_IME:
858 // Handled transparently by registers
859 break;
860 case REG_MAX:
861 // Some bad interrupt libraries will read from this
862 break;
863 case 0x66:
864 case 0x6E:
865 case 0x76:
866 case 0x7A:
867 case 0x7E:
868 case 0x86:
869 case 0x8A:
870 mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
871 return 0;
872 case REG_DEBUG_ENABLE:
873 if (gba->debug) {
874 return 0x1DEA;
875 }
876 // Fall through
877 default:
878 mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
879 return GBALoadBad(gba->cpu);
880 }
881 return gba->memory.io[address >> 1];
882}
883
884void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
885 int i;
886 for (i = 0; i < REG_MAX; i += 2) {
887 if (_isRSpecialRegister[i >> 1]) {
888 STORE_16(gba->memory.io[i >> 1], i, state->io);
889 } else if (_isValidRegister[i >> 1]) {
890 uint16_t reg = GBAIORead(gba, i);
891 STORE_16(reg, i, state->io);
892 }
893 }
894
895 for (i = 0; i < 4; ++i) {
896 STORE_16(gba->memory.io[(REG_DMA0CNT_LO + i * 12) >> 1], (REG_DMA0CNT_LO + i * 12), state->io);
897 STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload);
898 STORE_16(gba->timers[i].oldReload, 0, &state->timers[i].oldReload);
899 STORE_32(gba->timers[i].lastEvent, 0, &state->timers[i].lastEvent);
900 STORE_32(gba->timers[i].nextEvent, 0, &state->timers[i].nextEvent);
901 STORE_32(gba->timers[i].overflowInterval, 0, &state->timers[i].overflowInterval);
902 STORE_32(gba->timers[i].flags, 0, &state->timers[i].flags);
903 STORE_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
904 STORE_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
905 STORE_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
906 STORE_32(gba->memory.dma[i].nextEvent, 0, &state->dma[i].nextEvent);
907 }
908
909 GBAHardwareSerialize(&gba->memory.hw, state);
910}
911
912void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
913 int i;
914 for (i = 0; i < REG_MAX; i += 2) {
915 if (_isWSpecialRegister[i >> 1]) {
916 LOAD_16(gba->memory.io[i >> 1], i, state->io);
917 } else if (_isValidRegister[i >> 1]) {
918 uint16_t reg;
919 LOAD_16(reg, i, state->io);
920 GBAIOWrite(gba, i, reg);
921 }
922 }
923
924 gba->timersEnabled = 0;
925 for (i = 0; i < 4; ++i) {
926 LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload);
927 LOAD_16(gba->timers[i].oldReload, 0, &state->timers[i].oldReload);
928 LOAD_32(gba->timers[i].overflowInterval, 0, &state->timers[i].overflowInterval);
929 LOAD_32(gba->timers[i].flags, 0, &state->timers[i].flags);
930 if (i > 0 && GBATimerFlagsIsCountUp(gba->timers[i].flags)) {
931 // Overwrite invalid values in savestate
932 gba->timers[i].lastEvent = 0;
933 gba->timers[i].nextEvent = INT_MAX;
934 } else {
935 LOAD_32(gba->timers[i].lastEvent, 0, &state->timers[i].lastEvent);
936 LOAD_32(gba->timers[i].nextEvent, 0, &state->timers[i].nextEvent);
937 }
938 LOAD_16(gba->memory.dma[i].reg, (REG_DMA0CNT_HI + i * 12), state->io);
939 LOAD_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
940 LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
941 LOAD_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
942 LOAD_32(gba->memory.dma[i].nextEvent, 0, &state->dma[i].nextEvent);
943 if (GBADMARegisterGetTiming(gba->memory.dma[i].reg) != DMA_TIMING_NOW) {
944 GBAMemoryScheduleDMA(gba, i, &gba->memory.dma[i]);
945 }
946
947 if (GBATimerFlagsIsEnable(gba->timers[i].flags)) {
948 gba->timersEnabled |= 1 << i;
949 }
950 }
951 GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
952 GBAMemoryUpdateDMAs(gba, 0);
953 GBAHardwareDeserialize(&gba->memory.hw, state);
954}