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