all repos — mgba @ a5890bfea5dfdb956d3464d0b6c4076e963dffab

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