all repos — mgba @ e2d6bc38ffa991717dfffbce115ab6f60b4546b2

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_BIT;
 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			return;
 580		}
 581		// Fall through
 582	default:
 583		if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
 584			STORE_16LE(value, address - REG_DEBUG_STRING, gba->debugString);
 585			return;
 586		}
 587		mLOG(GBA_IO, STUB, "Stub I/O register write: %03X", address);
 588		if (address >= REG_MAX) {
 589			mLOG(GBA_IO, GAME_ERROR, "Write to unused I/O register: %03X", address);
 590			return;
 591		}
 592		break;
 593	}
 594	gba->memory.io[address >> 1] = value;
 595}
 596
 597void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
 598	if (address == REG_HALTCNT) {
 599		value &= 0x80;
 600		if (!value) {
 601			GBAHalt(gba);
 602		} else {
 603			GBAStop(gba);
 604		}
 605		return;
 606	}
 607	if (address == REG_POSTFLG) {
 608		gba->memory.io[(address & (SIZE_IO - 1)) >> 1] = value;
 609		return;
 610	}
 611	if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
 612		gba->debugString[address - REG_DEBUG_STRING] = value;
 613		return;
 614	}
 615	if (address > SIZE_IO) {
 616		return;
 617	}
 618	uint16_t value16 = value << (8 * (address & 1));
 619	value16 |= (gba->memory.io[(address & (SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1)));
 620	GBAIOWrite(gba, address & 0xFFFFFFFE, value16);
 621}
 622
 623void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
 624	switch (address) {
 625	// Wave RAM can be written and read even if the audio hardware is disabled.
 626	// However, it is not possible to switch between the two banks because it
 627	// isn't possible to write to register SOUND3CNT_LO.
 628	case REG_WAVE_RAM0_LO:
 629		GBAAudioWriteWaveRAM(&gba->audio, 0, value);
 630		break;
 631	case REG_WAVE_RAM1_LO:
 632		GBAAudioWriteWaveRAM(&gba->audio, 1, value);
 633		break;
 634	case REG_WAVE_RAM2_LO:
 635		GBAAudioWriteWaveRAM(&gba->audio, 2, value);
 636		break;
 637	case REG_WAVE_RAM3_LO:
 638		GBAAudioWriteWaveRAM(&gba->audio, 3, value);
 639		break;
 640	case REG_FIFO_A_LO:
 641	case REG_FIFO_B_LO:
 642		value = GBAAudioWriteFIFO(&gba->audio, address, value);
 643		break;
 644	case REG_DMA0SAD_LO:
 645		value = GBADMAWriteSAD(gba, 0, value);
 646		break;
 647	case REG_DMA0DAD_LO:
 648		value = GBADMAWriteDAD(gba, 0, value);
 649		break;
 650	case REG_DMA1SAD_LO:
 651		value = GBADMAWriteSAD(gba, 1, value);
 652		break;
 653	case REG_DMA1DAD_LO:
 654		value = GBADMAWriteDAD(gba, 1, value);
 655		break;
 656	case REG_DMA2SAD_LO:
 657		value = GBADMAWriteSAD(gba, 2, value);
 658		break;
 659	case REG_DMA2DAD_LO:
 660		value = GBADMAWriteDAD(gba, 2, value);
 661		break;
 662	case REG_DMA3SAD_LO:
 663		value = GBADMAWriteSAD(gba, 3, value);
 664		break;
 665	case REG_DMA3DAD_LO:
 666		value = GBADMAWriteDAD(gba, 3, value);
 667		break;
 668	default:
 669		if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
 670			STORE_32LE(value, address - REG_DEBUG_STRING, gba->debugString);
 671			return;
 672		}
 673		GBAIOWrite(gba, address, value & 0xFFFF);
 674		GBAIOWrite(gba, address | 2, value >> 16);
 675		return;
 676	}
 677	gba->memory.io[address >> 1] = value;
 678	gba->memory.io[(address >> 1) + 1] = value >> 16;
 679}
 680
 681bool GBAIOIsReadConstant(uint32_t address) {
 682	switch (address) {
 683	default:
 684		return false;
 685	case REG_BG0CNT:
 686	case REG_BG1CNT:
 687	case REG_BG2CNT:
 688	case REG_BG3CNT:
 689	case REG_WININ:
 690	case REG_WINOUT:
 691	case REG_BLDCNT:
 692	case REG_BLDALPHA:
 693	case REG_SOUND1CNT_LO:
 694	case REG_SOUND1CNT_HI:
 695	case REG_SOUND1CNT_X:
 696	case REG_SOUND2CNT_LO:
 697	case REG_SOUND2CNT_HI:
 698	case REG_SOUND3CNT_LO:
 699	case REG_SOUND3CNT_HI:
 700	case REG_SOUND3CNT_X:
 701	case REG_SOUND4CNT_LO:
 702	case REG_SOUND4CNT_HI:
 703	case REG_SOUNDCNT_LO:
 704	case REG_SOUNDCNT_HI:
 705	case REG_TM0CNT_HI:
 706	case REG_TM1CNT_HI:
 707	case REG_TM2CNT_HI:
 708	case REG_TM3CNT_HI:
 709	case REG_KEYINPUT:
 710	case REG_KEYCNT:
 711	case REG_IE:
 712		return true;
 713	}
 714}
 715
 716uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
 717	if (!GBAIOIsReadConstant(address)) {
 718		// Most IO reads need to disable idle removal
 719		gba->haltPending = false;
 720	}
 721
 722	switch (address) {
 723	// Reading this takes two cycles (1N+1I), so let's remove them preemptively
 724	case REG_TM0CNT_LO:
 725		GBATimerUpdateRegister(gba, 0, 2);
 726		break;
 727	case REG_TM1CNT_LO:
 728		GBATimerUpdateRegister(gba, 1, 2);
 729		break;
 730	case REG_TM2CNT_LO:
 731		GBATimerUpdateRegister(gba, 2, 2);
 732		break;
 733	case REG_TM3CNT_LO:
 734		GBATimerUpdateRegister(gba, 3, 2);
 735		break;
 736
 737	case REG_KEYINPUT: {
 738			size_t c;
 739			for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
 740				struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
 741				if (callbacks->keysRead) {
 742					callbacks->keysRead(callbacks->context);
 743				}
 744			}
 745			uint16_t input = 0;
 746			if (gba->keyCallback) {
 747				input = gba->keyCallback->readKeys(gba->keyCallback);
 748				if (gba->keySource) {
 749					*gba->keySource = input;
 750				}
 751			} else if (gba->keySource) {
 752				input = *gba->keySource;
 753				if (!gba->allowOpposingDirections) {
 754					unsigned rl = input & 0x030;
 755					unsigned ud = input & 0x0C0;
 756					input &= 0x30F;
 757					if (rl != 0x030) {
 758						input |= rl;
 759					}
 760					if (ud != 0x0C0) {
 761						input |= ud;
 762					}
 763				}
 764			}
 765			return 0x3FF ^ input;
 766		}
 767	case REG_SIOCNT:
 768		return gba->sio.siocnt;
 769	case REG_RCNT:
 770		return gba->sio.rcnt;
 771
 772	case REG_BG0HOFS:
 773	case REG_BG0VOFS:
 774	case REG_BG1HOFS:
 775	case REG_BG1VOFS:
 776	case REG_BG2HOFS:
 777	case REG_BG2VOFS:
 778	case REG_BG3HOFS:
 779	case REG_BG3VOFS:
 780	case REG_BG2PA:
 781	case REG_BG2PB:
 782	case REG_BG2PC:
 783	case REG_BG2PD:
 784	case REG_BG2X_LO:
 785	case REG_BG2X_HI:
 786	case REG_BG2Y_LO:
 787	case REG_BG2Y_HI:
 788	case REG_BG3PA:
 789	case REG_BG3PB:
 790	case REG_BG3PC:
 791	case REG_BG3PD:
 792	case REG_BG3X_LO:
 793	case REG_BG3X_HI:
 794	case REG_BG3Y_LO:
 795	case REG_BG3Y_HI:
 796	case REG_WIN0H:
 797	case REG_WIN1H:
 798	case REG_WIN0V:
 799	case REG_WIN1V:
 800	case REG_MOSAIC:
 801	case REG_BLDY:
 802	case REG_FIFO_A_LO:
 803	case REG_FIFO_A_HI:
 804	case REG_FIFO_B_LO:
 805	case REG_FIFO_B_HI:
 806	case REG_DMA0SAD_LO:
 807	case REG_DMA0SAD_HI:
 808	case REG_DMA0DAD_LO:
 809	case REG_DMA0DAD_HI:
 810	case REG_DMA1SAD_LO:
 811	case REG_DMA1SAD_HI:
 812	case REG_DMA1DAD_LO:
 813	case REG_DMA1DAD_HI:
 814	case REG_DMA2SAD_LO:
 815	case REG_DMA2SAD_HI:
 816	case REG_DMA2DAD_LO:
 817	case REG_DMA2DAD_HI:
 818	case REG_DMA3SAD_LO:
 819	case REG_DMA3SAD_HI:
 820	case REG_DMA3DAD_LO:
 821	case REG_DMA3DAD_HI:
 822		// Write-only register
 823		mLOG(GBA_IO, GAME_ERROR, "Read from write-only I/O register: %03X", address);
 824		return GBALoadBad(gba->cpu);
 825
 826	case REG_DMA0CNT_LO:
 827	case REG_DMA1CNT_LO:
 828	case REG_DMA2CNT_LO:
 829	case REG_DMA3CNT_LO:
 830		// Many, many things read from the DMA register
 831	case REG_MAX:
 832		// Some bad interrupt libraries will read from this
 833		// (Silent) write-only register
 834		return 0;
 835
 836	case REG_JOY_RECV_LO:
 837	case REG_JOY_RECV_HI:
 838		gba->memory.io[REG_JOYSTAT >> 1] &= ~JOYSTAT_RECV_BIT;
 839		break;
 840
 841	case REG_SOUNDBIAS:
 842	case REG_POSTFLG:
 843		mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address);
 844		break;
 845
 846	// Wave RAM can be written and read even if the audio hardware is disabled.
 847	// However, it is not possible to switch between the two banks because it
 848	// isn't possible to write to register SOUND3CNT_LO.
 849	case REG_WAVE_RAM0_LO:
 850		return GBAAudioReadWaveRAM(&gba->audio, 0) & 0xFFFF;
 851	case REG_WAVE_RAM0_HI:
 852		return GBAAudioReadWaveRAM(&gba->audio, 0) >> 16;
 853	case REG_WAVE_RAM1_LO:
 854		return GBAAudioReadWaveRAM(&gba->audio, 1) & 0xFFFF;
 855	case REG_WAVE_RAM1_HI:
 856		return GBAAudioReadWaveRAM(&gba->audio, 1) >> 16;
 857	case REG_WAVE_RAM2_LO:
 858		return GBAAudioReadWaveRAM(&gba->audio, 2) & 0xFFFF;
 859	case REG_WAVE_RAM2_HI:
 860		return GBAAudioReadWaveRAM(&gba->audio, 2) >> 16;
 861	case REG_WAVE_RAM3_LO:
 862		return GBAAudioReadWaveRAM(&gba->audio, 3) & 0xFFFF;
 863	case REG_WAVE_RAM3_HI:
 864		return GBAAudioReadWaveRAM(&gba->audio, 3) >> 16;
 865
 866	case REG_SOUND1CNT_LO:
 867	case REG_SOUND1CNT_HI:
 868	case REG_SOUND1CNT_X:
 869	case REG_SOUND2CNT_LO:
 870	case REG_SOUND2CNT_HI:
 871	case REG_SOUND3CNT_LO:
 872	case REG_SOUND3CNT_HI:
 873	case REG_SOUND3CNT_X:
 874	case REG_SOUND4CNT_LO:
 875	case REG_SOUND4CNT_HI:
 876	case REG_SOUNDCNT_LO:
 877		if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) {
 878			// TODO: Is writing allowed when the circuit is disabled?
 879			return 0;
 880		}
 881		// Fall through
 882	case REG_DISPCNT:
 883	case REG_GREENSWP:
 884	case REG_DISPSTAT:
 885	case REG_VCOUNT:
 886	case REG_BG0CNT:
 887	case REG_BG1CNT:
 888	case REG_BG2CNT:
 889	case REG_BG3CNT:
 890	case REG_WININ:
 891	case REG_WINOUT:
 892	case REG_BLDCNT:
 893	case REG_BLDALPHA:
 894	case REG_SOUNDCNT_HI:
 895	case REG_SOUNDCNT_X:
 896	case REG_DMA0CNT_HI:
 897	case REG_DMA1CNT_HI:
 898	case REG_DMA2CNT_HI:
 899	case REG_DMA3CNT_HI:
 900	case REG_TM0CNT_HI:
 901	case REG_TM1CNT_HI:
 902	case REG_TM2CNT_HI:
 903	case REG_TM3CNT_HI:
 904	case REG_KEYCNT:
 905	case REG_SIOMULTI0:
 906	case REG_SIOMULTI1:
 907	case REG_SIOMULTI2:
 908	case REG_SIOMULTI3:
 909	case REG_SIOMLT_SEND:
 910	case REG_JOYCNT:
 911	case REG_JOY_TRANS_LO:
 912	case REG_JOY_TRANS_HI:
 913	case REG_JOYSTAT:
 914	case REG_IE:
 915	case REG_IF:
 916	case REG_WAITCNT:
 917	case REG_IME:
 918		// Handled transparently by registers
 919		break;
 920	case 0x066:
 921	case 0x06E:
 922	case 0x076:
 923	case 0x07A:
 924	case 0x07E:
 925	case 0x086:
 926	case 0x08A:
 927	case 0x136:
 928	case 0x142:
 929	case 0x15A:
 930	case 0x206:
 931		mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
 932		return 0;
 933	case REG_DEBUG_ENABLE:
 934		if (gba->debug) {
 935			return 0x1DEA;
 936		}
 937		// Fall through
 938	default:
 939		mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
 940		return GBALoadBad(gba->cpu);
 941	}
 942	return gba->memory.io[address >> 1];
 943}
 944
 945void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
 946	int i;
 947	for (i = 0; i < REG_MAX; i += 2) {
 948		if (_isRSpecialRegister[i >> 1]) {
 949			STORE_16(gba->memory.io[i >> 1], i, state->io);
 950		} else if (_isValidRegister[i >> 1]) {
 951			uint16_t reg = GBAIORead(gba, i);
 952			STORE_16(reg, i, state->io);
 953		}
 954	}
 955
 956	for (i = 0; i < 4; ++i) {
 957		STORE_16(gba->memory.io[(REG_DMA0CNT_LO + i * 12) >> 1], (REG_DMA0CNT_LO + i * 12), state->io);
 958		STORE_16(gba->timers[i].reload, 0, &state->timers[i].reload);
 959		STORE_32(gba->timers[i].lastEvent - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].lastEvent);
 960		STORE_32(gba->timers[i].event.when - mTimingCurrentTime(&gba->timing), 0, &state->timers[i].nextEvent);
 961		STORE_32(gba->timers[i].flags, 0, &state->timers[i].flags);
 962		STORE_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
 963		STORE_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
 964		STORE_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
 965		STORE_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
 966	}
 967
 968	STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
 969	STORE_32(gba->dmaPC, 0, &state->dmaBlockPC);
 970
 971	GBAHardwareSerialize(&gba->memory.hw, state);
 972}
 973
 974void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
 975	int i;
 976	for (i = 0; i < REG_MAX; i += 2) {
 977		if (_isWSpecialRegister[i >> 1]) {
 978			LOAD_16(gba->memory.io[i >> 1], i, state->io);
 979		} else if (_isValidRegister[i >> 1]) {
 980			uint16_t reg;
 981			LOAD_16(reg, i, state->io);
 982			GBAIOWrite(gba, i, reg);
 983		}
 984	}
 985
 986	uint32_t when;
 987	for (i = 0; i < 4; ++i) {
 988		LOAD_16(gba->timers[i].reload, 0, &state->timers[i].reload);
 989		LOAD_32(gba->timers[i].flags, 0, &state->timers[i].flags);
 990		LOAD_32(when, 0, &state->timers[i].lastEvent);
 991		gba->timers[i].lastEvent = when + mTimingCurrentTime(&gba->timing);
 992		LOAD_32(when, 0, &state->timers[i].nextEvent);
 993		if ((i < 1 || !GBATimerFlagsIsCountUp(gba->timers[i].flags)) && GBATimerFlagsIsEnable(gba->timers[i].flags)) {
 994			mTimingSchedule(&gba->timing, &gba->timers[i].event, when);
 995		} else {
 996			gba->timers[i].event.when = when + mTimingCurrentTime(&gba->timing);
 997		}
 998
 999		LOAD_16(gba->memory.dma[i].reg, (REG_DMA0CNT_HI + i * 12), state->io);
1000		LOAD_32(gba->memory.dma[i].nextSource, 0, &state->dma[i].nextSource);
1001		LOAD_32(gba->memory.dma[i].nextDest, 0, &state->dma[i].nextDest);
1002		LOAD_32(gba->memory.dma[i].nextCount, 0, &state->dma[i].nextCount);
1003		LOAD_32(gba->memory.dma[i].when, 0, &state->dma[i].when);
1004	}
1005	GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
1006	gba->sio.siocnt = gba->memory.io[REG_SIOCNT >> 1];
1007	GBASIOWriteRCNT(&gba->sio, gba->memory.io[REG_RCNT >> 1]);
1008
1009	LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
1010	LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC);
1011
1012	GBADMAUpdate(gba);
1013	GBAHardwareDeserialize(&gba->memory.hw, state);
1014}