all repos — mgba @ e79963b007a0feee6c241774609808061c288f1b

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