all repos — mgba @ fa64310e83f00f8ead49dace975036022f0faed5

mGBA Game Boy Advance Emulator

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}