all repos — mgba @ 573fcead5df408ec38950c4158b657648e896a6f

mGBA Game Boy Advance Emulator

src/gba/gba-io.c (view raw)

  1#include "gba-io.h"
  2
  3#include "gba-video.h"
  4
  5void GBAIOInit(struct GBA* gba) {
  6	gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF;
  7}
  8
  9void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
 10	switch (address) {
 11	// Video
 12	case REG_DISPSTAT:
 13		GBAVideoWriteDISPSTAT(&gba->video, value);
 14		break;
 15
 16	// DMA
 17	case REG_DMA0CNT_LO:
 18		GBAMemoryWriteDMACNT_LO(&gba->memory, 0, value);
 19		break;
 20	case REG_DMA0CNT_HI:
 21		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value);
 22		break;
 23	case REG_DMA1CNT_LO:
 24		GBAMemoryWriteDMACNT_LO(&gba->memory, 1, value);
 25		break;
 26	case REG_DMA1CNT_HI:
 27		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value);
 28		break;
 29	case REG_DMA2CNT_LO:
 30		GBAMemoryWriteDMACNT_LO(&gba->memory, 2, value);
 31		break;
 32	case REG_DMA2CNT_HI:
 33		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value);
 34		break;
 35	case REG_DMA3CNT_LO:
 36		GBAMemoryWriteDMACNT_LO(&gba->memory, 3, value);
 37		break;
 38	case REG_DMA3CNT_HI:
 39		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value);
 40		break;
 41
 42	// Timers
 43	case REG_TM0CNT_LO:
 44		GBATimerWriteTMCNT_LO(gba, 0, value);
 45		return;
 46	case REG_TM1CNT_LO:
 47		GBATimerWriteTMCNT_LO(gba, 1, value);
 48		return;
 49	case REG_TM2CNT_LO:
 50		GBATimerWriteTMCNT_LO(gba, 2, value);
 51		return;
 52	case REG_TM3CNT_LO:
 53		GBATimerWriteTMCNT_LO(gba, 3, value);
 54		return;
 55
 56	case REG_TM0CNT_HI:
 57		value &= 0x00C7;
 58		GBATimerWriteTMCNT_HI(gba, 0, value);
 59		break;
 60	case REG_TM1CNT_HI:
 61		value &= 0x00C7;
 62		GBATimerWriteTMCNT_HI(gba, 1, value);
 63		break;
 64	case REG_TM2CNT_HI:
 65		value &= 0x00C7;
 66		GBATimerWriteTMCNT_HI(gba, 2, value);
 67		break;
 68	case REG_TM3CNT_HI:
 69		value &= 0x00C7;
 70		GBATimerWriteTMCNT_HI(gba, 3, value);
 71		break;
 72
 73	// Interrupts and misc
 74	case REG_WAITCNT:
 75		GBAAdjustWaitstates(&gba->memory, value);
 76		break;
 77	case REG_IE:
 78		GBAWriteIE(gba, value);
 79		break;
 80	case REG_IF:
 81		value = gba->memory.io[REG_IF >> 1] & ~value;
 82		break;
 83	case REG_IME:
 84		GBAWriteIME(gba, value);
 85		break;
 86	case REG_HALTCNT:
 87		value &= 0x80;
 88		if (!value) {
 89			GBAHalt(gba);
 90		} else {
 91			GBALog(GBA_LOG_STUB, "Stop unimplemented");
 92		}
 93		return;
 94	default:
 95		GBALog(GBA_LOG_STUB, "Stub I/O register write: %03x", address);
 96		break;
 97	}
 98	gba->memory.io[address >> 1] = value;
 99}
100
101void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
102	switch (address) {
103	case REG_DMA0SAD_LO:
104		GBAMemoryWriteDMASAD(&gba->memory, 0, value);
105		break;
106	case REG_DMA0DAD_LO:
107		GBAMemoryWriteDMADAD(&gba->memory, 0, value);
108		break;
109	case REG_DMA1SAD_LO:
110		GBAMemoryWriteDMASAD(&gba->memory, 1, value);
111		break;
112	case REG_DMA1DAD_LO:
113		GBAMemoryWriteDMADAD(&gba->memory, 1, value);
114		break;
115	case REG_DMA2SAD_LO:
116		GBAMemoryWriteDMASAD(&gba->memory, 2, value);
117		break;
118	case REG_DMA2DAD_LO:
119		GBAMemoryWriteDMADAD(&gba->memory, 2, value);
120		break;
121	case REG_DMA3SAD_LO:
122		GBAMemoryWriteDMASAD(&gba->memory, 3, value);
123		break;
124	case REG_DMA3DAD_LO:
125		GBAMemoryWriteDMADAD(&gba->memory, 3, value);
126		break;
127	default:
128		GBAIOWrite(gba, address, value & 0xFFFF);
129		GBAIOWrite(gba, address | 2, value >> 16);
130		break;
131	}
132}
133
134uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
135	switch (address) {
136	case REG_DISPSTAT:
137		return gba->memory.io[REG_DISPSTAT >> 1] | GBAVideoReadDISPSTAT(&gba->video);
138		break;
139
140	case REG_TM0CNT_LO:
141		GBATimerUpdateRegister(gba, 0);
142		break;
143	case REG_TM1CNT_LO:
144		GBATimerUpdateRegister(gba, 1);
145		break;
146	case REG_TM2CNT_LO:
147		GBATimerUpdateRegister(gba, 2);
148		break;
149	case REG_TM3CNT_LO:
150		GBATimerUpdateRegister(gba, 3);
151		break;
152
153	case REG_KEYINPUT:
154		if (gba->keySource) {
155			return 0x3FF ^ *gba->keySource;
156		}
157		break;
158
159	case REG_DMA0CNT_LO:
160	case REG_DMA1CNT_LO:
161	case REG_DMA2CNT_LO:
162	case REG_DMA3CNT_LO:
163		// Write-only register
164		return 0;
165	case REG_VCOUNT:
166	case REG_DMA0CNT_HI:
167	case REG_DMA1CNT_HI:
168	case REG_DMA2CNT_HI:
169	case REG_DMA3CNT_HI:
170	case REG_IE:
171	case REG_IF:
172	case REG_WAITCNT:
173	case REG_IME:
174		// Handled transparently by registers
175		break;
176	default:
177		GBALog(GBA_LOG_STUB, "Stub I/O register read: %03x", address);
178		break;
179	}
180	return gba->memory.io[address >> 1];
181}