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