all repos — mgba @ c99450c51b3cc4144eebd69906abb944c4cdd72f

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