all repos — mgba @ 6eadd35ee6b0670b0bc4e348df5b5edde5707fea

mGBA Game Boy Advance Emulator

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