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 <mgba/internal/gba/io.h>
7
8#include <mgba/internal/arm/macros.h>
9#include <mgba/internal/gba/dma.h>
10#include <mgba/internal/gba/gba.h>
11#include <mgba/internal/gba/serialize.h>
12
13mLOG_DEFINE_CATEGORY(GBA_IO, "GBA I/O", "gba.io");
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, 1, 0, 0, 0, 1, 0,
254 0, 0, 1, 0, 0, 0, 1, 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 1, 1, 1, 0, 1, 0, 1, 0,
295 1, 0, 1, 0, 1, 0, 1, 0,
296 1, 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 if (!gba->biosVf) {
338 gba->memory.io[REG_VCOUNT >> 1] = 0x7E;
339 gba->memory.io[REG_POSTFLG >> 1] = 1;
340 }
341}
342
343void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
344 if (address < REG_SOUND1CNT_LO && (address > REG_VCOUNT || address == REG_DISPCNT)) {
345 value = gba->video.renderer->writeVideoRegister(gba->video.renderer, address, value);
346 } else {
347 switch (address) {
348 // Video
349 case REG_DISPSTAT:
350 value &= 0xFFF8;
351 GBAVideoWriteDISPSTAT(&gba->video, value);
352 return;
353
354 case REG_VCOUNT:
355 mLOG(GBA_IO, GAME_ERROR, "Write to read-only I/O register: %03X", address);
356 return;
357
358 // Audio
359 case REG_SOUND1CNT_LO:
360 GBAAudioWriteSOUND1CNT_LO(&gba->audio, value);
361 value &= 0x007F;
362 break;
363 case REG_SOUND1CNT_HI:
364 GBAAudioWriteSOUND1CNT_HI(&gba->audio, value);
365 break;
366 case REG_SOUND1CNT_X:
367 GBAAudioWriteSOUND1CNT_X(&gba->audio, value);
368 value &= 0x47FF;
369 break;
370 case REG_SOUND2CNT_LO:
371 GBAAudioWriteSOUND2CNT_LO(&gba->audio, value);
372 break;
373 case REG_SOUND2CNT_HI:
374 GBAAudioWriteSOUND2CNT_HI(&gba->audio, value);
375 value &= 0x47FF;
376 break;
377 case REG_SOUND3CNT_LO:
378 GBAAudioWriteSOUND3CNT_LO(&gba->audio, value);
379 value &= 0x00E0;
380 break;
381 case REG_SOUND3CNT_HI:
382 GBAAudioWriteSOUND3CNT_HI(&gba->audio, value);
383 value &= 0xE03F;
384 break;
385 case REG_SOUND3CNT_X:
386 GBAAudioWriteSOUND3CNT_X(&gba->audio, value);
387 // TODO: The low bits need to not be readable, but still 8-bit writable
388 value &= 0x47FF;
389 break;
390 case REG_SOUND4CNT_LO:
391 GBAAudioWriteSOUND4CNT_LO(&gba->audio, value);
392 value &= 0xFF3F;
393 break;
394 case REG_SOUND4CNT_HI:
395 GBAAudioWriteSOUND4CNT_HI(&gba->audio, value);
396 value &= 0x40FF;
397 break;
398 case REG_SOUNDCNT_LO:
399 GBAAudioWriteSOUNDCNT_LO(&gba->audio, value);
400 value &= 0xFF77;
401 break;
402 case REG_SOUNDCNT_HI:
403 GBAAudioWriteSOUNDCNT_HI(&gba->audio, value);
404 value &= 0x770F;
405 break;
406 case REG_SOUNDCNT_X:
407 GBAAudioWriteSOUNDCNT_X(&gba->audio, value);
408 value &= 0x0080;
409 value |= gba->memory.io[REG_SOUNDCNT_X >> 1] & 0xF;
410 break;
411 case REG_SOUNDBIAS:
412 GBAAudioWriteSOUNDBIAS(&gba->audio, value);
413 break;
414
415 case REG_WAVE_RAM0_LO:
416 case REG_WAVE_RAM1_LO:
417 case REG_WAVE_RAM2_LO:
418 case REG_WAVE_RAM3_LO:
419 GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
420 break;
421
422 case REG_WAVE_RAM0_HI:
423 case REG_WAVE_RAM1_HI:
424 case REG_WAVE_RAM2_HI:
425 case REG_WAVE_RAM3_HI:
426 GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
427 break;
428
429 case REG_FIFO_A_LO:
430 case REG_FIFO_B_LO:
431 GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
432 break;
433
434 case REG_FIFO_A_HI:
435 case REG_FIFO_B_HI:
436 GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
437 break;
438
439 // DMA
440 case REG_DMA0SAD_LO:
441 case REG_DMA0DAD_LO:
442 case REG_DMA1SAD_LO:
443 case REG_DMA1DAD_LO:
444 case REG_DMA2SAD_LO:
445 case REG_DMA2DAD_LO:
446 case REG_DMA3SAD_LO:
447 case REG_DMA3DAD_LO:
448 GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value);
449 break;
450
451 case REG_DMA0SAD_HI:
452 case REG_DMA0DAD_HI:
453 case REG_DMA1SAD_HI:
454 case REG_DMA1DAD_HI:
455 case REG_DMA2SAD_HI:
456 case REG_DMA2DAD_HI:
457 case REG_DMA3SAD_HI:
458 case REG_DMA3DAD_HI:
459 GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16));
460 break;
461
462 case REG_DMA0CNT_LO:
463 GBADMAWriteCNT_LO(gba, 0, value & 0x3FFF);
464 break;
465 case REG_DMA0CNT_HI:
466 value = GBADMAWriteCNT_HI(gba, 0, value);
467 break;
468 case REG_DMA1CNT_LO:
469 GBADMAWriteCNT_LO(gba, 1, value & 0x3FFF);
470 break;
471 case REG_DMA1CNT_HI:
472 value = GBADMAWriteCNT_HI(gba, 1, value);
473 break;
474 case REG_DMA2CNT_LO:
475 GBADMAWriteCNT_LO(gba, 2, value & 0x3FFF);
476 break;
477 case REG_DMA2CNT_HI:
478 value = GBADMAWriteCNT_HI(gba, 2, value);
479 break;
480 case REG_DMA3CNT_LO:
481 GBADMAWriteCNT_LO(gba, 3, value);
482 break;
483 case REG_DMA3CNT_HI:
484 value = GBADMAWriteCNT_HI(gba, 3, value);
485 break;
486
487 // Timers
488 case REG_TM0CNT_LO:
489 GBATimerWriteTMCNT_LO(gba, 0, value);
490 return;
491 case REG_TM1CNT_LO:
492 GBATimerWriteTMCNT_LO(gba, 1, value);
493 return;
494 case REG_TM2CNT_LO:
495 GBATimerWriteTMCNT_LO(gba, 2, value);
496 return;
497 case REG_TM3CNT_LO:
498 GBATimerWriteTMCNT_LO(gba, 3, value);
499 return;
500
501 case REG_TM0CNT_HI:
502 value &= 0x00C7;
503 GBATimerWriteTMCNT_HI(gba, 0, value);
504 break;
505 case REG_TM1CNT_HI:
506 value &= 0x00C7;
507 GBATimerWriteTMCNT_HI(gba, 1, value);
508 break;
509 case REG_TM2CNT_HI:
510 value &= 0x00C7;
511 GBATimerWriteTMCNT_HI(gba, 2, value);
512 break;
513 case REG_TM3CNT_HI:
514 value &= 0x00C7;
515 GBATimerWriteTMCNT_HI(gba, 3, value);
516 break;
517
518 // SIO
519 case REG_SIOCNT:
520 GBASIOWriteSIOCNT(&gba->sio, value);
521 break;
522 case REG_RCNT:
523 value &= 0xC1FF;
524 GBASIOWriteRCNT(&gba->sio, value);
525 break;
526 case REG_JOY_TRANS_LO:
527 case REG_JOY_TRANS_HI:
528 gba->memory.io[REG_JOYSTAT >> 1] |= JOYSTAT_TRANS_BIT;
529 // Fall through
530 case REG_SIOMLT_SEND:
531 case REG_JOYCNT:
532 case REG_JOYSTAT:
533 case REG_JOY_RECV_LO:
534 case REG_JOY_RECV_HI:
535 value = GBASIOWriteRegister(&gba->sio, address, value);
536 break;
537
538 // Interrupts and misc
539 case REG_KEYCNT:
540 value &= 0xC3FF;
541 gba->memory.io[address >> 1] = value;
542 GBATestKeypadIRQ(gba);
543 return;
544 case REG_WAITCNT:
545 value &= 0x5FFF;
546 GBAAdjustWaitstates(gba, value);
547 break;
548 case REG_IE:
549 gba->memory.io[REG_IE >> 1] = value;
550 GBATestIRQ(gba, 1);
551 return;
552 case REG_IF:
553 value = gba->memory.io[REG_IF >> 1] & ~value;
554 gba->memory.io[REG_IF >> 1] = value;
555 GBATestIRQ(gba, 1);
556 return;
557 case REG_IME:
558 gba->memory.io[REG_IME >> 1] = value;
559 GBATestIRQ(gba, 1);
560 return;
561 case REG_MAX:
562 // Some bad interrupt libraries will write to this
563 break;
564 case REG_DEBUG_ENABLE:
565 gba->debug = value == 0xC0DE;
566 return;
567 case REG_DEBUG_FLAGS:
568 if (gba->debug) {
569 GBADebug(gba, value);
570 return;
571 }
572 // Fall through
573 default:
574 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
575 STORE_16LE(value, address - REG_DEBUG_STRING, gba->debugString);
576 return;
577 }
578 mLOG(GBA_IO, STUB, "Stub I/O register write: %03X", address);
579 if (address >= REG_MAX) {
580 mLOG(GBA_IO, GAME_ERROR, "Write to unused I/O register: %03X", address);
581 return;
582 }
583 break;
584 }
585 }
586 gba->memory.io[address >> 1] = value;
587}
588
589void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
590 if (address == REG_HALTCNT) {
591 value &= 0x80;
592 if (!value) {
593 GBAHalt(gba);
594 } else {
595 GBAStop(gba);
596 }
597 return;
598 }
599 if (address == REG_POSTFLG) {
600 gba->memory.io[(address & (SIZE_IO - 1)) >> 1] = value;
601 return;
602 }
603 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
604 gba->debugString[address - REG_DEBUG_STRING] = value;
605 return;
606 }
607 if (address > SIZE_IO) {
608 return;
609 }
610 uint16_t value16 = value << (8 * (address & 1));
611 value16 |= (gba->memory.io[(address & (SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1)));
612 GBAIOWrite(gba, address & 0xFFFFFFFE, value16);
613}
614
615void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
616 switch (address) {
617 case REG_WAVE_RAM0_LO:
618 GBAAudioWriteWaveRAM(&gba->audio, 0, value);
619 break;
620 case REG_WAVE_RAM1_LO:
621 GBAAudioWriteWaveRAM(&gba->audio, 1, value);
622 break;
623 case REG_WAVE_RAM2_LO:
624 GBAAudioWriteWaveRAM(&gba->audio, 2, value);
625 break;
626 case REG_WAVE_RAM3_LO:
627 GBAAudioWriteWaveRAM(&gba->audio, 3, value);
628 break;
629 case REG_FIFO_A_LO:
630 case REG_FIFO_B_LO:
631 GBAAudioWriteFIFO(&gba->audio, address, value);
632 break;
633 case REG_DMA0SAD_LO:
634 value = GBADMAWriteSAD(gba, 0, value);
635 break;
636 case REG_DMA0DAD_LO:
637 value = GBADMAWriteDAD(gba, 0, value);
638 break;
639 case REG_DMA1SAD_LO:
640 value = GBADMAWriteSAD(gba, 1, value);
641 break;
642 case REG_DMA1DAD_LO:
643 value = GBADMAWriteDAD(gba, 1, value);
644 break;
645 case REG_DMA2SAD_LO:
646 value = GBADMAWriteSAD(gba, 2, value);
647 break;
648 case REG_DMA2DAD_LO:
649 value = GBADMAWriteDAD(gba, 2, value);
650 break;
651 case REG_DMA3SAD_LO:
652 value = GBADMAWriteSAD(gba, 3, value);
653 break;
654 case REG_DMA3DAD_LO:
655 value = GBADMAWriteDAD(gba, 3, value);
656 break;
657 default:
658 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
659 STORE_32LE(value, address - REG_DEBUG_STRING, gba->debugString);
660 return;
661 }
662 GBAIOWrite(gba, address, value & 0xFFFF);
663 GBAIOWrite(gba, address | 2, value >> 16);
664 return;
665 }
666 gba->memory.io[address >> 1] = value;
667 gba->memory.io[(address >> 1) + 1] = value >> 16;
668}
669
670bool GBAIOIsReadConstant(uint32_t address) {
671 switch (address) {
672 default:
673 return false;
674 case REG_BG0CNT:
675 case REG_BG1CNT:
676 case REG_BG2CNT:
677 case REG_BG3CNT:
678 case REG_WININ:
679 case REG_WINOUT:
680 case REG_BLDCNT:
681 case REG_BLDALPHA:
682 case REG_SOUND1CNT_LO:
683 case REG_SOUND1CNT_HI:
684 case REG_SOUND1CNT_X:
685 case REG_SOUND2CNT_LO:
686 case REG_SOUND2CNT_HI:
687 case REG_SOUND3CNT_LO:
688 case REG_SOUND3CNT_HI:
689 case REG_SOUND3CNT_X:
690 case REG_SOUND4CNT_LO:
691 case REG_SOUND4CNT_HI:
692 case REG_SOUNDCNT_LO:
693 case REG_SOUNDCNT_HI:
694 case REG_TM0CNT_HI:
695 case REG_TM1CNT_HI:
696 case REG_TM2CNT_HI:
697 case REG_TM3CNT_HI:
698 case REG_KEYINPUT:
699 case REG_KEYCNT:
700 case REG_IE:
701 return true;
702 }
703}
704
705uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
706 if (!GBAIOIsReadConstant(address)) {
707 // Most IO reads need to disable idle removal
708 gba->haltPending = false;
709 }
710
711 switch (address) {
712 // Reading this takes two cycles (1N+1I), so let's remove them preemptively
713 case REG_TM0CNT_LO:
714 GBATimerUpdateRegister(gba, 0, 2);
715 break;
716 case REG_TM1CNT_LO:
717 GBATimerUpdateRegister(gba, 1, 2);
718 break;
719 case REG_TM2CNT_LO:
720 GBATimerUpdateRegister(gba, 2, 2);
721 break;
722 case REG_TM3CNT_LO:
723 GBATimerUpdateRegister(gba, 3, 2);
724 break;
725
726 case REG_KEYINPUT: {
727 size_t c;
728 for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
729 struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
730 if (callbacks->keysRead) {
731 callbacks->keysRead(callbacks->context);
732 }
733 }
734 uint16_t input = 0;
735 if (gba->keyCallback) {
736 input = gba->keyCallback->readKeys(gba->keyCallback);
737 if (gba->keySource) {
738 *gba->keySource = input;
739 }
740 } else if (gba->keySource) {
741 input = *gba->keySource;
742 if (!gba->allowOpposingDirections) {
743 unsigned rl = input & 0x030;
744 unsigned ud = input & 0x0C0;
745 input &= 0x30F;
746 if (rl != 0x030) {
747 input |= rl;
748 }
749 if (ud != 0x0C0) {
750 input |= ud;
751 }
752 }
753 }
754 return 0x3FF ^ input;
755 }
756 case REG_SIOCNT:
757 return gba->sio.siocnt;
758 case REG_RCNT:
759 return gba->sio.rcnt;
760
761 case REG_BG0HOFS:
762 case REG_BG0VOFS:
763 case REG_BG1HOFS:
764 case REG_BG1VOFS:
765 case REG_BG2HOFS:
766 case REG_BG2VOFS:
767 case REG_BG3HOFS:
768 case REG_BG3VOFS:
769 case REG_BG2PA:
770 case REG_BG2PB:
771 case REG_BG2PC:
772 case REG_BG2PD:
773 case REG_BG2X_LO:
774 case REG_BG2X_HI:
775 case REG_BG2Y_LO:
776 case REG_BG2Y_HI:
777 case REG_BG3PA:
778 case REG_BG3PB:
779 case REG_BG3PC:
780 case REG_BG3PD:
781 case REG_BG3X_LO:
782 case REG_BG3X_HI:
783 case REG_BG3Y_LO:
784 case REG_BG3Y_HI:
785 case REG_WIN0H:
786 case REG_WIN1H:
787 case REG_WIN0V:
788 case REG_WIN1V:
789 case REG_MOSAIC:
790 case REG_BLDY:
791 case REG_FIFO_A_LO:
792 case REG_FIFO_A_HI:
793 case REG_FIFO_B_LO:
794 case REG_FIFO_B_HI:
795 case REG_DMA0SAD_LO:
796 case REG_DMA0SAD_HI:
797 case REG_DMA0DAD_LO:
798 case REG_DMA0DAD_HI:
799 case REG_DMA1SAD_LO:
800 case REG_DMA1SAD_HI:
801 case REG_DMA1DAD_LO:
802 case REG_DMA1DAD_HI:
803 case REG_DMA2SAD_LO:
804 case REG_DMA2SAD_HI:
805 case REG_DMA2DAD_LO:
806 case REG_DMA2DAD_HI:
807 case REG_DMA3SAD_LO:
808 case REG_DMA3SAD_HI:
809 case REG_DMA3DAD_LO:
810 case REG_DMA3DAD_HI:
811 // Write-only register
812 mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address);
813 return GBALoadBad(gba->cpu);
814
815 case REG_DMA0CNT_LO:
816 case REG_DMA1CNT_LO:
817 case REG_DMA2CNT_LO:
818 case REG_DMA3CNT_LO:
819 // Many, many things read from the DMA register
820 case REG_MAX:
821 // Some bad interrupt libraries will read from this
822 // (Silent) write-only register
823 return 0;
824
825 case REG_JOY_RECV_LO:
826 case REG_JOY_RECV_HI:
827 gba->memory.io[REG_JOYSTAT >> 1] &= ~JOYSTAT_RECV_BIT;
828 break;
829
830 case REG_SOUNDBIAS:
831 case REG_POSTFLG:
832 mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address);
833 break;
834 case REG_SOUND1CNT_LO:
835 case REG_SOUND1CNT_HI:
836 case REG_SOUND1CNT_X:
837 case REG_SOUND2CNT_LO:
838 case REG_SOUND2CNT_HI:
839 case REG_SOUND3CNT_LO:
840 case REG_SOUND3CNT_HI:
841 case REG_SOUND3CNT_X:
842 case REG_SOUND4CNT_LO:
843 case REG_SOUND4CNT_HI:
844 case REG_SOUNDCNT_LO:
845 if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
846 // TODO: Is writing allowed when the circuit is disabled?
847 return 0;
848 }
849 // Fall through
850 case REG_DISPCNT:
851 case REG_DISPSTAT:
852 case REG_VCOUNT:
853 case REG_BG0CNT:
854 case REG_BG1CNT:
855 case REG_BG2CNT:
856 case REG_BG3CNT:
857 case REG_WININ:
858 case REG_WINOUT:
859 case REG_BLDCNT:
860 case REG_BLDALPHA:
861 case REG_SOUNDCNT_HI:
862 case REG_SOUNDCNT_X:
863 case REG_WAVE_RAM0_LO:
864 case REG_WAVE_RAM0_HI:
865 case REG_WAVE_RAM1_LO:
866 case REG_WAVE_RAM1_HI:
867 case REG_WAVE_RAM2_LO:
868 case REG_WAVE_RAM2_HI:
869 case REG_WAVE_RAM3_LO:
870 case REG_WAVE_RAM3_HI:
871 case REG_DMA0CNT_HI:
872 case REG_DMA1CNT_HI:
873 case REG_DMA2CNT_HI:
874 case REG_DMA3CNT_HI:
875 case REG_TM0CNT_HI:
876 case REG_TM1CNT_HI:
877 case REG_TM2CNT_HI:
878 case REG_TM3CNT_HI:
879 case REG_KEYCNT:
880 case REG_SIOMULTI0:
881 case REG_SIOMULTI1:
882 case REG_SIOMULTI2:
883 case REG_SIOMULTI3:
884 case REG_SIOMLT_SEND:
885 case REG_JOYCNT:
886 case REG_JOY_TRANS_LO:
887 case REG_JOY_TRANS_HI:
888 case REG_JOYSTAT:
889 case REG_IE:
890 case REG_IF:
891 case REG_WAITCNT:
892 case REG_IME:
893 // Handled transparently by registers
894 break;
895 case 0x066:
896 case 0x06E:
897 case 0x076:
898 case 0x07A:
899 case 0x07E:
900 case 0x086:
901 case 0x08A:
902 case 0x136:
903 case 0x142:
904 case 0x15A:
905 case 0x206:
906 mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
907 return 0;
908 case REG_DEBUG_ENABLE:
909 if (gba->debug) {
910 return 0x1DEA;
911 }
912 // Fall through
913 default:
914 mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
915 return GBALoadBad(gba->cpu);
916 }
917 return gba->memory.io[address >> 1];
918}
919
920void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
921 int i;
922 for (i = 0; i < REG_MAX; i += 2) {
923 if (_isRSpecialRegister[i >> 1]) {
924 STORE_16(gba->memory.io[i >> 1], i, state->io);
925 } else if (_isValidRegister[i >> 1]) {
926 uint16_t reg = GBAIORead(gba, i);
927 STORE_16(reg, i, state->io);
928 }
929 }
930
931 for (i = 0; i < 4; ++i) {
932 STORE_16(gba->memory.io[(REG_DMA0CNT_LO + i * 12) >> 1], (REG_DMA0CNT_LO + i * 12), state->io);
933 STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload);
934 STORE_32(gba->timers[i].lastEvent - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].lastEvent);
935 STORE_32(gba->timers[i].event.when - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].nextEvent);
936 STORE_32(gba->timers[i].flags, 0, &state->timers[i].flags);
937 STORE_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
938 STORE_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
939 STORE_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
940 STORE_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
941 }
942
943 STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
944 STORE_32(gba->dmaPC, 0, &state->dmaBlockPC);
945
946 GBAHardwareSerialize(&gba->memory.hw, state);
947}
948
949void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
950 int i;
951 for (i = 0; i < REG_MAX; i += 2) {
952 if (_isWSpecialRegister[i >> 1]) {
953 LOAD_16(gba->memory.io[i >> 1], i, state->io);
954 } else if (_isValidRegister[i >> 1]) {
955 uint16_t reg;
956 LOAD_16(reg, i, state->io);
957 GBAIOWrite(gba, i, reg);
958 }
959 }
960
961 uint32_t when;
962 for (i = 0; i < 4; ++i) {
963 LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload);
964 LOAD_32(gba->timers[i].flags, 0, &state->timers[i].flags);
965 LOAD_32(when, 0, &state->timers[i].lastEvent);
966 gba->timers[i].lastEvent = when + mTimingCurrentTime(&gba->timing);
967 LOAD_32(when, 0, &state->timers[i].nextEvent);
968 if ((i < 1 || !GBATimerFlagsIsCountUp(gba->timers[i].flags)) && GBATimerFlagsIsEnable(gba->timers[i].flags)) {
969 mTimingSchedule(&gba->timing, &gba->timers[i].event, when);
970 } else {
971 gba->timers[i].event.when = when + mTimingCurrentTime(&gba->timing);
972 }
973
974 LOAD_16(gba->memory.dma[i].reg, (REG_DMA0CNT_HI + i * 12), state->io);
975 LOAD_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
976 LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
977 LOAD_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
978 LOAD_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
979 }
980 GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
981
982 LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
983 LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC);
984
985 GBADMAUpdate(gba);
986 GBAHardwareDeserialize(&gba->memory.hw, state);
987}