all repos — mgba @ 6087ad8c5f2fb928b66f128cd581eaf2e98ae7a2

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	case REG_DISPSTAT:
 12		GBAVideoWriteDISPSTAT(&gba->video, value);
 13		break;
 14	case REG_DMA0CNT_LO:
 15		GBAMemoryWriteDMACNT_LO(&gba->memory, 0, value);
 16		break;
 17	case REG_DMA0CNT_HI:
 18		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value);
 19		break;
 20	case REG_DMA1CNT_LO:
 21		GBAMemoryWriteDMACNT_LO(&gba->memory, 1, value);
 22		break;
 23	case REG_DMA1CNT_HI:
 24		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value);
 25		break;
 26	case REG_DMA2CNT_LO:
 27		GBAMemoryWriteDMACNT_LO(&gba->memory, 2, value);
 28		break;
 29	case REG_DMA2CNT_HI:
 30		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value);
 31		break;
 32	case REG_DMA3CNT_LO:
 33		GBAMemoryWriteDMACNT_LO(&gba->memory, 3, value);
 34		break;
 35	case REG_DMA3CNT_HI:
 36		value = GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value);
 37		break;
 38
 39	case REG_WAITCNT:
 40		GBAAdjustWaitstates(&gba->memory, value);
 41		break;
 42	case REG_IE:
 43		GBAWriteIE(gba, value);
 44		break;
 45	case REG_IF:
 46		value = gba->memory.io[REG_IF >> 1] & ~value;
 47		break;
 48	case REG_IME:
 49		GBAWriteIME(gba, value);
 50		break;
 51	case REG_HALTCNT:
 52		value &= 0x80;
 53		if (!value) {
 54			GBAHalt(gba);
 55		} else {
 56			GBALog(GBA_LOG_STUB, "Stop unimplemented");
 57		}
 58		return;
 59	default:
 60		GBALog(GBA_LOG_STUB, "Stub I/O register write: %03x", address);
 61		break;
 62	}
 63	gba->memory.io[address >> 1] = value;
 64}
 65
 66void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
 67	switch (address) {
 68	case REG_DMA0SAD_LO:
 69		GBAMemoryWriteDMASAD(&gba->memory, 0, value);
 70		break;
 71	case REG_DMA0DAD_LO:
 72		GBAMemoryWriteDMADAD(&gba->memory, 0, value);
 73		break;
 74	case REG_DMA1SAD_LO:
 75		GBAMemoryWriteDMASAD(&gba->memory, 1, value);
 76		break;
 77	case REG_DMA1DAD_LO:
 78		GBAMemoryWriteDMADAD(&gba->memory, 1, value);
 79		break;
 80	case REG_DMA2SAD_LO:
 81		GBAMemoryWriteDMASAD(&gba->memory, 2, value);
 82		break;
 83	case REG_DMA2DAD_LO:
 84		GBAMemoryWriteDMADAD(&gba->memory, 2, value);
 85		break;
 86	case REG_DMA3SAD_LO:
 87		GBAMemoryWriteDMASAD(&gba->memory, 3, value);
 88		break;
 89	case REG_DMA3DAD_LO:
 90		GBAMemoryWriteDMADAD(&gba->memory, 3, value);
 91		break;
 92	default:
 93		GBAIOWrite(gba, address, value & 0xFFFF);
 94		GBAIOWrite(gba, address | 2, value >> 16);
 95		break;
 96	}
 97}
 98
 99uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
100	switch (address) {
101	case REG_DISPSTAT:
102		return gba->memory.io[REG_DISPSTAT >> 1] | GBAVideoReadDISPSTAT(&gba->video);
103		break;
104	case REG_DMA0CNT_LO:
105	case REG_DMA1CNT_LO:
106	case REG_DMA2CNT_LO:
107	case REG_DMA3CNT_LO:
108		// Write-only register
109		return 0;
110	case REG_VCOUNT:
111	case REG_DMA0CNT_HI:
112	case REG_DMA1CNT_HI:
113	case REG_DMA2CNT_HI:
114	case REG_DMA3CNT_HI:
115	case REG_IE:
116	case REG_IF:
117	case REG_WAITCNT:
118	case REG_IME:
119		// Handled transparently by registers
120		break;
121	default:
122		GBALog(GBA_LOG_STUB, "Stub I/O register read: %03x", address);
123		break;
124	}
125	return gba->memory.io[address >> 1];
126}