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