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}