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 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 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_DISPSTAT)) {
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 return;
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 return;
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_SIODATA32_LO:
531 case REG_SIODATA32_HI:
532 case REG_SIOMLT_SEND:
533 case REG_JOYCNT:
534 case REG_JOYSTAT:
535 case REG_JOY_RECV_LO:
536 case REG_JOY_RECV_HI:
537 value = GBASIOWriteRegister(&gba->sio, address, value);
538 break;
539
540 // Interrupts and misc
541 case REG_KEYCNT:
542 value &= 0xC3FF;
543 gba->memory.io[address >> 1] = value;
544 GBATestKeypadIRQ(gba);
545 return;
546 case REG_WAITCNT:
547 value &= 0x5FFF;
548 GBAAdjustWaitstates(gba, value);
549 break;
550 case REG_IE:
551 gba->memory.io[REG_IE >> 1] = value;
552 GBATestIRQ(gba, 1);
553 return;
554 case REG_IF:
555 value = gba->memory.io[REG_IF >> 1] & ~value;
556 gba->memory.io[REG_IF >> 1] = value;
557 GBATestIRQ(gba, 1);
558 return;
559 case REG_IME:
560 gba->memory.io[REG_IME >> 1] = value;
561 GBATestIRQ(gba, 1);
562 return;
563 case REG_MAX:
564 // Some bad interrupt libraries will write to this
565 break;
566 case REG_DEBUG_ENABLE:
567 gba->debug = value == 0xC0DE;
568 return;
569 case REG_DEBUG_FLAGS:
570 if (gba->debug) {
571 GBADebug(gba, value);
572 return;
573 }
574 // Fall through
575 default:
576 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
577 STORE_16LE(value, address - REG_DEBUG_STRING, gba->debugString);
578 return;
579 }
580 mLOG(GBA_IO, STUB, "Stub I/O register write: %03X", address);
581 if (address >= REG_MAX) {
582 mLOG(GBA_IO, GAME_ERROR, "Write to unused I/O register: %03X", address);
583 return;
584 }
585 break;
586 }
587 }
588 gba->memory.io[address >> 1] = value;
589}
590
591void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
592 if (address == REG_HALTCNT) {
593 value &= 0x80;
594 if (!value) {
595 GBAHalt(gba);
596 } else {
597 GBAStop(gba);
598 }
599 return;
600 }
601 if (address == REG_POSTFLG) {
602 gba->memory.io[(address & (SIZE_IO - 1)) >> 1] = value;
603 return;
604 }
605 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
606 gba->debugString[address - REG_DEBUG_STRING] = value;
607 return;
608 }
609 if (address > SIZE_IO) {
610 return;
611 }
612 uint16_t value16 = value << (8 * (address & 1));
613 value16 |= (gba->memory.io[(address & (SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1)));
614 GBAIOWrite(gba, address & 0xFFFFFFFE, value16);
615}
616
617void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
618 switch (address) {
619 case REG_WAVE_RAM0_LO:
620 GBAAudioWriteWaveRAM(&gba->audio, 0, value);
621 break;
622 case REG_WAVE_RAM1_LO:
623 GBAAudioWriteWaveRAM(&gba->audio, 1, value);
624 break;
625 case REG_WAVE_RAM2_LO:
626 GBAAudioWriteWaveRAM(&gba->audio, 2, value);
627 break;
628 case REG_WAVE_RAM3_LO:
629 GBAAudioWriteWaveRAM(&gba->audio, 3, value);
630 break;
631 case REG_FIFO_A_LO:
632 case REG_FIFO_B_LO:
633 value = GBAAudioWriteFIFO(&gba->audio, address, value);
634 break;
635 case REG_DMA0SAD_LO:
636 value = GBADMAWriteSAD(gba, 0, value);
637 break;
638 case REG_DMA0DAD_LO:
639 value = GBADMAWriteDAD(gba, 0, value);
640 break;
641 case REG_DMA1SAD_LO:
642 value = GBADMAWriteSAD(gba, 1, value);
643 break;
644 case REG_DMA1DAD_LO:
645 value = GBADMAWriteDAD(gba, 1, value);
646 break;
647 case REG_DMA2SAD_LO:
648 value = GBADMAWriteSAD(gba, 2, value);
649 break;
650 case REG_DMA2DAD_LO:
651 value = GBADMAWriteDAD(gba, 2, value);
652 break;
653 case REG_DMA3SAD_LO:
654 value = GBADMAWriteSAD(gba, 3, value);
655 break;
656 case REG_DMA3DAD_LO:
657 value = GBADMAWriteDAD(gba, 3, value);
658 break;
659 default:
660 if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
661 STORE_32LE(value, address - REG_DEBUG_STRING, gba->debugString);
662 return;
663 }
664 GBAIOWrite(gba, address, value & 0xFFFF);
665 GBAIOWrite(gba, address | 2, value >> 16);
666 return;
667 }
668 gba->memory.io[address >> 1] = value;
669 gba->memory.io[(address >> 1) + 1] = value >> 16;
670}
671
672bool GBAIOIsReadConstant(uint32_t address) {
673 switch (address) {
674 default:
675 return false;
676 case REG_BG0CNT:
677 case REG_BG1CNT:
678 case REG_BG2CNT:
679 case REG_BG3CNT:
680 case REG_WININ:
681 case REG_WINOUT:
682 case REG_BLDCNT:
683 case REG_BLDALPHA:
684 case REG_SOUND1CNT_LO:
685 case REG_SOUND1CNT_HI:
686 case REG_SOUND1CNT_X:
687 case REG_SOUND2CNT_LO:
688 case REG_SOUND2CNT_HI:
689 case REG_SOUND3CNT_LO:
690 case REG_SOUND3CNT_HI:
691 case REG_SOUND3CNT_X:
692 case REG_SOUND4CNT_LO:
693 case REG_SOUND4CNT_HI:
694 case REG_SOUNDCNT_LO:
695 case REG_SOUNDCNT_HI:
696 case REG_TM0CNT_HI:
697 case REG_TM1CNT_HI:
698 case REG_TM2CNT_HI:
699 case REG_TM3CNT_HI:
700 case REG_KEYINPUT:
701 case REG_KEYCNT:
702 case REG_IE:
703 return true;
704 }
705}
706
707uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
708 if (!GBAIOIsReadConstant(address)) {
709 // Most IO reads need to disable idle removal
710 gba->haltPending = false;
711 }
712
713 switch (address) {
714 // Reading this takes two cycles (1N+1I), so let's remove them preemptively
715 case REG_TM0CNT_LO:
716 GBATimerUpdateRegister(gba, 0, 2);
717 break;
718 case REG_TM1CNT_LO:
719 GBATimerUpdateRegister(gba, 1, 2);
720 break;
721 case REG_TM2CNT_LO:
722 GBATimerUpdateRegister(gba, 2, 2);
723 break;
724 case REG_TM3CNT_LO:
725 GBATimerUpdateRegister(gba, 3, 2);
726 break;
727
728 case REG_KEYINPUT: {
729 size_t c;
730 for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
731 struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
732 if (callbacks->keysRead) {
733 callbacks->keysRead(callbacks->context);
734 }
735 }
736 uint16_t input = 0;
737 if (gba->keyCallback) {
738 input = gba->keyCallback->readKeys(gba->keyCallback);
739 if (gba->keySource) {
740 *gba->keySource = input;
741 }
742 } else if (gba->keySource) {
743 input = *gba->keySource;
744 if (!gba->allowOpposingDirections) {
745 unsigned rl = input & 0x030;
746 unsigned ud = input & 0x0C0;
747 input &= 0x30F;
748 if (rl != 0x030) {
749 input |= rl;
750 }
751 if (ud != 0x0C0) {
752 input |= ud;
753 }
754 }
755 }
756 return 0x3FF ^ input;
757 }
758 case REG_SIOCNT:
759 return gba->sio.siocnt;
760 case REG_RCNT:
761 return gba->sio.rcnt;
762
763 case REG_BG0HOFS:
764 case REG_BG0VOFS:
765 case REG_BG1HOFS:
766 case REG_BG1VOFS:
767 case REG_BG2HOFS:
768 case REG_BG2VOFS:
769 case REG_BG3HOFS:
770 case REG_BG3VOFS:
771 case REG_BG2PA:
772 case REG_BG2PB:
773 case REG_BG2PC:
774 case REG_BG2PD:
775 case REG_BG2X_LO:
776 case REG_BG2X_HI:
777 case REG_BG2Y_LO:
778 case REG_BG2Y_HI:
779 case REG_BG3PA:
780 case REG_BG3PB:
781 case REG_BG3PC:
782 case REG_BG3PD:
783 case REG_BG3X_LO:
784 case REG_BG3X_HI:
785 case REG_BG3Y_LO:
786 case REG_BG3Y_HI:
787 case REG_WIN0H:
788 case REG_WIN1H:
789 case REG_WIN0V:
790 case REG_WIN1V:
791 case REG_MOSAIC:
792 case REG_BLDY:
793 case REG_FIFO_A_LO:
794 case REG_FIFO_A_HI:
795 case REG_FIFO_B_LO:
796 case REG_FIFO_B_HI:
797 case REG_DMA0SAD_LO:
798 case REG_DMA0SAD_HI:
799 case REG_DMA0DAD_LO:
800 case REG_DMA0DAD_HI:
801 case REG_DMA1SAD_LO:
802 case REG_DMA1SAD_HI:
803 case REG_DMA1DAD_LO:
804 case REG_DMA1DAD_HI:
805 case REG_DMA2SAD_LO:
806 case REG_DMA2SAD_HI:
807 case REG_DMA2DAD_LO:
808 case REG_DMA2DAD_HI:
809 case REG_DMA3SAD_LO:
810 case REG_DMA3SAD_HI:
811 case REG_DMA3DAD_LO:
812 case REG_DMA3DAD_HI:
813 // Write-only register
814 mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address);
815 return GBALoadBad(gba->cpu);
816
817 case REG_DMA0CNT_LO:
818 case REG_DMA1CNT_LO:
819 case REG_DMA2CNT_LO:
820 case REG_DMA3CNT_LO:
821 // Many, many things read from the DMA register
822 case REG_MAX:
823 // Some bad interrupt libraries will read from this
824 // (Silent) write-only register
825 return 0;
826
827 case REG_JOY_RECV_LO:
828 case REG_JOY_RECV_HI:
829 gba->memory.io[REG_JOYSTAT >> 1] &= ~JOYSTAT_RECV_BIT;
830 break;
831
832 case REG_SOUNDBIAS:
833 case REG_POSTFLG:
834 mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address);
835 break;
836 case REG_SOUND1CNT_LO:
837 case REG_SOUND1CNT_HI:
838 case REG_SOUND1CNT_X:
839 case REG_SOUND2CNT_LO:
840 case REG_SOUND2CNT_HI:
841 case REG_SOUND3CNT_LO:
842 case REG_SOUND3CNT_HI:
843 case REG_SOUND3CNT_X:
844 case REG_SOUND4CNT_LO:
845 case REG_SOUND4CNT_HI:
846 case REG_SOUNDCNT_LO:
847 if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
848 // TODO: Is writing allowed when the circuit is disabled?
849 return 0;
850 }
851 // Fall through
852 case REG_DISPCNT:
853 case REG_GREENSWP:
854 case REG_DISPSTAT:
855 case REG_VCOUNT:
856 case REG_BG0CNT:
857 case REG_BG1CNT:
858 case REG_BG2CNT:
859 case REG_BG3CNT:
860 case REG_WININ:
861 case REG_WINOUT:
862 case REG_BLDCNT:
863 case REG_BLDALPHA:
864 case REG_SOUNDCNT_HI:
865 case REG_SOUNDCNT_X:
866 case REG_WAVE_RAM0_LO:
867 case REG_WAVE_RAM0_HI:
868 case REG_WAVE_RAM1_LO:
869 case REG_WAVE_RAM1_HI:
870 case REG_WAVE_RAM2_LO:
871 case REG_WAVE_RAM2_HI:
872 case REG_WAVE_RAM3_LO:
873 case REG_WAVE_RAM3_HI:
874 case REG_DMA0CNT_HI:
875 case REG_DMA1CNT_HI:
876 case REG_DMA2CNT_HI:
877 case REG_DMA3CNT_HI:
878 case REG_TM0CNT_HI:
879 case REG_TM1CNT_HI:
880 case REG_TM2CNT_HI:
881 case REG_TM3CNT_HI:
882 case REG_KEYCNT:
883 case REG_SIOMULTI0:
884 case REG_SIOMULTI1:
885 case REG_SIOMULTI2:
886 case REG_SIOMULTI3:
887 case REG_SIOMLT_SEND:
888 case REG_JOYCNT:
889 case REG_JOY_TRANS_LO:
890 case REG_JOY_TRANS_HI:
891 case REG_JOYSTAT:
892 case REG_IE:
893 case REG_IF:
894 case REG_WAITCNT:
895 case REG_IME:
896 // Handled transparently by registers
897 break;
898 case 0x066:
899 case 0x06E:
900 case 0x076:
901 case 0x07A:
902 case 0x07E:
903 case 0x086:
904 case 0x08A:
905 case 0x136:
906 case 0x142:
907 case 0x15A:
908 case 0x206:
909 mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
910 return 0;
911 case REG_DEBUG_ENABLE:
912 if (gba->debug) {
913 return 0x1DEA;
914 }
915 // Fall through
916 default:
917 mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
918 return GBALoadBad(gba->cpu);
919 }
920 return gba->memory.io[address >> 1];
921}
922
923void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
924 int i;
925 for (i = 0; i < REG_MAX; i += 2) {
926 if (_isRSpecialRegister[i >> 1]) {
927 STORE_16(gba->memory.io[i >> 1], i, state->io);
928 } else if (_isValidRegister[i >> 1]) {
929 uint16_t reg = GBAIORead(gba, i);
930 STORE_16(reg, i, state->io);
931 }
932 }
933
934 for (i = 0; i < 4; ++i) {
935 STORE_16(gba->memory.io[(REG_DMA0CNT_LO + i * 12) >> 1], (REG_DMA0CNT_LO + i * 12), state->io);
936 STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload);
937 STORE_32(gba->timers[i].lastEvent - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].lastEvent);
938 STORE_32(gba->timers[i].event.when - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].nextEvent);
939 STORE_32(gba->timers[i].flags, 0, &state->timers[i].flags);
940 STORE_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
941 STORE_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
942 STORE_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
943 STORE_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
944 }
945
946 STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
947 STORE_32(gba->dmaPC, 0, &state->dmaBlockPC);
948
949 GBAHardwareSerialize(&gba->memory.hw, state);
950}
951
952void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
953 int i;
954 for (i = 0; i < REG_MAX; i += 2) {
955 if (_isWSpecialRegister[i >> 1]) {
956 LOAD_16(gba->memory.io[i >> 1], i, state->io);
957 } else if (_isValidRegister[i >> 1]) {
958 uint16_t reg;
959 LOAD_16(reg, i, state->io);
960 GBAIOWrite(gba, i, reg);
961 }
962 }
963
964 uint32_t when;
965 for (i = 0; i < 4; ++i) {
966 LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload);
967 LOAD_32(gba->timers[i].flags, 0, &state->timers[i].flags);
968 LOAD_32(when, 0, &state->timers[i].lastEvent);
969 gba->timers[i].lastEvent = when + mTimingCurrentTime(&gba->timing);
970 LOAD_32(when, 0, &state->timers[i].nextEvent);
971 if ((i < 1 || !GBATimerFlagsIsCountUp(gba->timers[i].flags)) && GBATimerFlagsIsEnable(gba->timers[i].flags)) {
972 mTimingSchedule(&gba->timing, &gba->timers[i].event, when);
973 } else {
974 gba->timers[i].event.when = when + mTimingCurrentTime(&gba->timing);
975 }
976
977 LOAD_16(gba->memory.dma[i].reg, (REG_DMA0CNT_HI + i * 12), state->io);
978 LOAD_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
979 LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
980 LOAD_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
981 LOAD_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
982 }
983 GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
984 gba->sio.siocnt = gba->memory.io[REG_SIOCNT >> 1];
985 GBASIOWriteRCNT(&gba->sio, gba->memory.io[REG_RCNT >> 1]);
986
987 LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
988 LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC);
989
990 GBADMAUpdate(gba);
991 GBAHardwareDeserialize(&gba->memory.hw, state);
992}