src/gba/gba-memory.c (view raw)
1#include "gba-memory.h"
2
3#include "gba-io.h"
4
5#include <string.h>
6#include <sys/mman.h>
7
8static const char* GBA_CANNOT_MMAP = "Could not map memory";
9
10static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region);
11
12void GBAMemoryInit(struct GBAMemory* memory) {
13 memory->d.load32 = GBALoad32;
14 memory->d.load16 = GBALoad16;
15 memory->d.loadU16 = GBALoadU16;
16 memory->d.load8 = GBALoad8;
17 memory->d.loadU8 = GBALoadU8;
18 memory->d.store32 = GBAStore32;
19 memory->d.store16 = GBAStore16;
20 memory->d.store8 = GBAStore8;
21
22 memory->bios = 0;
23 memory->wram = mmap(0, SIZE_WORKING_RAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
24 memory->iwram = mmap(0, SIZE_WORKING_IRAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
25 memory->rom = 0;
26 memset(memory->io, 0, sizeof(memory->io));
27
28 if (!memory->wram || !memory->iwram) {
29 GBAMemoryDeinit(memory);
30 memory->p->errno = GBA_OUT_OF_MEMORY;
31 memory->p->errstr = GBA_CANNOT_MMAP;
32 }
33
34 memory->d.activeRegion = 0;
35 memory->d.activeMask = 0;
36 memory->d.setActiveRegion = GBASetActiveRegion;
37}
38
39void GBAMemoryDeinit(struct GBAMemory* memory) {
40 munmap(memory->wram, SIZE_WORKING_RAM);
41 munmap(memory->iwram, SIZE_WORKING_IRAM);
42}
43
44static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) {
45 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
46
47 switch (address & ~OFFSET_MASK) {
48 case BASE_BIOS:
49 memory->activeRegion = gbaMemory->bios;
50 memory->activeMask = 0;
51 break;
52 case BASE_WORKING_RAM:
53 memory->activeRegion = gbaMemory->wram;
54 memory->activeMask = SIZE_WORKING_RAM - 1;
55 break;
56 case BASE_WORKING_IRAM:
57 memory->activeRegion = gbaMemory->iwram;
58 memory->activeMask = SIZE_WORKING_IRAM - 1;
59 break;
60 case BASE_CART0:
61 case BASE_CART0_EX:
62 case BASE_CART1:
63 case BASE_CART1_EX:
64 case BASE_CART2:
65 case BASE_CART2_EX:
66 memory->activeRegion = gbaMemory->rom;
67 memory->activeMask = SIZE_CART0 - 1;
68 break;
69 default:
70 memory->activeRegion = 0;
71 memory->activeMask = 0;
72 break;
73 }
74}
75
76int32_t GBALoad32(struct ARMMemory* memory, uint32_t address) {
77 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
78
79 switch (address & ~OFFSET_MASK) {
80 case BASE_BIOS:
81 break;
82 case BASE_WORKING_RAM:
83 return gbaMemory->wram[(address & (SIZE_WORKING_RAM - 1)) >> 2];
84 case BASE_WORKING_IRAM:
85 return gbaMemory->iwram[(address & (SIZE_WORKING_IRAM - 1)) >> 2];
86 case BASE_IO:
87 break;
88 case BASE_PALETTE_RAM:
89 break;
90 case BASE_VRAM:
91 break;
92 case BASE_OAM:
93 break;
94 case BASE_CART0:
95 case BASE_CART0_EX:
96 case BASE_CART1:
97 case BASE_CART1_EX:
98 case BASE_CART2:
99 case BASE_CART2_EX:
100 return gbaMemory->rom[(address & (SIZE_CART0 - 1)) >> 2];
101 case BASE_CART_SRAM:
102 break;
103 default:
104 break;
105 }
106
107 return 0;
108}
109
110int16_t GBALoad16(struct ARMMemory* memory, uint32_t address) {
111 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
112
113 switch (address & ~OFFSET_MASK) {
114 case BASE_BIOS:
115 break;
116 case BASE_WORKING_RAM:
117 return ((int16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1];
118 case BASE_WORKING_IRAM:
119 return ((int16_t*) gbaMemory->iwram)[(address & (SIZE_WORKING_IRAM - 1)) >> 1];
120 case BASE_IO:
121 break;
122 case BASE_PALETTE_RAM:
123 break;
124 case BASE_VRAM:
125 break;
126 case BASE_OAM:
127 break;
128 case BASE_CART0:
129 case BASE_CART0_EX:
130 case BASE_CART1:
131 case BASE_CART1_EX:
132 case BASE_CART2:
133 case BASE_CART2_EX:
134 return ((int16_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1)) >> 1];
135 case BASE_CART_SRAM:
136 break;
137 default:
138 break;
139 }
140
141 return 0;
142}
143
144uint16_t GBALoadU16(struct ARMMemory* memory, uint32_t address) {
145 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
146
147 switch (address & ~OFFSET_MASK) {
148 case BASE_BIOS:
149 break;
150 case BASE_WORKING_RAM:
151 return ((uint16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1];
152 case BASE_WORKING_IRAM:
153 return ((uint16_t*) gbaMemory->iwram)[(address & (SIZE_WORKING_IRAM - 1)) >> 1];
154 case BASE_IO:
155 break;
156 case BASE_PALETTE_RAM:
157 break;
158 case BASE_VRAM:
159 break;
160 case BASE_OAM:
161 break;
162 case BASE_CART0:
163 case BASE_CART0_EX:
164 case BASE_CART1:
165 case BASE_CART1_EX:
166 case BASE_CART2:
167 case BASE_CART2_EX:
168 return ((uint16_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1)) >> 1];
169 case BASE_CART_SRAM:
170 break;
171 default:
172 break;
173 }
174
175 return 0;
176}
177
178int8_t GBALoad8(struct ARMMemory* memory, uint32_t address) {
179 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
180
181 switch (address & ~OFFSET_MASK) {
182 case BASE_BIOS:
183 break;
184 case BASE_WORKING_RAM:
185 return ((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)];
186 case BASE_WORKING_IRAM:
187 return ((int8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
188 case BASE_IO:
189 break;
190 case BASE_PALETTE_RAM:
191 break;
192 case BASE_VRAM:
193 break;
194 case BASE_OAM:
195 break;
196 case BASE_CART0:
197 case BASE_CART0_EX:
198 case BASE_CART1:
199 case BASE_CART1_EX:
200 case BASE_CART2:
201 case BASE_CART2_EX:
202 return ((int8_t*) gbaMemory->rom)[address & (SIZE_CART0 - 1)];
203 case BASE_CART_SRAM:
204 break;
205 default:
206 break;
207 }
208
209 return 0;
210}
211
212uint8_t GBALoadU8(struct ARMMemory* memory, uint32_t address) {
213 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
214
215 switch (address & ~OFFSET_MASK) {
216 case BASE_BIOS:
217 break;
218 case BASE_WORKING_RAM:
219 return ((uint8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)];
220 break;
221 case BASE_WORKING_IRAM:
222 return ((uint8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)];
223 break;
224 case BASE_IO:
225 break;
226 case BASE_PALETTE_RAM:
227 break;
228 case BASE_VRAM:
229 break;
230 case BASE_OAM:
231 break;
232 case BASE_CART0:
233 case BASE_CART0_EX:
234 case BASE_CART1:
235 case BASE_CART1_EX:
236 case BASE_CART2:
237 case BASE_CART2_EX:
238 return ((uint8_t*) gbaMemory->rom)[address & (SIZE_CART0 - 1)];
239 case BASE_CART_SRAM:
240 break;
241 default:
242 break;
243 }
244
245 return 0;
246}
247
248void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value) {
249 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
250
251 switch (address & ~OFFSET_MASK) {
252 case BASE_WORKING_RAM:
253 gbaMemory->wram[(address & (SIZE_WORKING_RAM - 1)) >> 2] = value;
254 break;
255 case BASE_WORKING_IRAM:
256 gbaMemory->iwram[(address & (SIZE_WORKING_IRAM - 1)) >> 2] = value;
257 break;
258 case BASE_IO:
259 break;
260 case BASE_PALETTE_RAM:
261 break;
262 case BASE_VRAM:
263 break;
264 case BASE_OAM:
265 break;
266 case BASE_CART0:
267 break;
268 case BASE_CART2_EX:
269 break;
270 case BASE_CART_SRAM:
271 break;
272 default:
273 break;
274 }
275}
276
277void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value) {
278 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
279
280 switch (address & ~OFFSET_MASK) {
281 case BASE_WORKING_RAM:
282 ((int16_t*) gbaMemory->wram)[(address & (SIZE_WORKING_RAM - 1)) >> 1] = value;
283 break;
284 case BASE_WORKING_IRAM:
285 ((int16_t*) gbaMemory->iwram)[(address & (SIZE_WORKING_IRAM - 1)) >> 1] = value;
286 break;
287 case BASE_IO:
288 GBAIOWrite(gbaMemory->p, address & (SIZE_IO - 1), value);
289 break;
290 case BASE_PALETTE_RAM:
291 break;
292 case BASE_VRAM:
293 break;
294 case BASE_OAM:
295 break;
296 case BASE_CART0:
297 break;
298 case BASE_CART2_EX:
299 break;
300 case BASE_CART_SRAM:
301 break;
302 default:
303 break;
304 }
305}
306
307void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value) {
308 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
309
310 switch (address & ~OFFSET_MASK) {
311 case BASE_WORKING_RAM:
312 ((int8_t*) gbaMemory->wram)[address & (SIZE_WORKING_RAM - 1)] = value;
313 break;
314 case BASE_WORKING_IRAM:
315 ((int8_t*) gbaMemory->iwram)[address & (SIZE_WORKING_IRAM - 1)] = value;
316 break;
317 case BASE_IO:
318 break;
319 case BASE_PALETTE_RAM:
320 break;
321 case BASE_VRAM:
322 break;
323 case BASE_OAM:
324 break;
325 case BASE_CART0:
326 break;
327 case BASE_CART2_EX:
328 break;
329 case BASE_CART_SRAM:
330 break;
331 default:
332 break;
333 }
334}