all repos — mgba @ 93a2f160667e0bb29b544f638d224261a0a168f5

mGBA Game Boy Advance Emulator

src/gba.c (view raw)

  1#include "gba.h"
  2
  3#include <sys/mman.h>
  4#include <unistd.h>
  5
  6static const char* GBA_CANNOT_MMAP = "Could not map memory";
  7
  8void GBAInit(struct GBA* gba) {
  9	gba->errno = GBA_NO_ERROR;
 10	gba->errstr = 0;
 11
 12	ARMInit(&gba->cpu);
 13
 14	gba->memory.p = gba;
 15	GBAMemoryInit(&gba->memory);
 16	ARMAssociateMemory(&gba->cpu, &gba->memory.d);
 17
 18	GBABoardInit(&gba->board);
 19	ARMAssociateBoard(&gba->cpu, &gba->board.d);
 20
 21	ARMReset(&gba->cpu);
 22}
 23
 24void GBADeinit(struct GBA* gba) {
 25	GBAMemoryDeinit(&gba->memory);
 26}
 27
 28void GBAMemoryInit(struct GBAMemory* memory) {
 29	memory->d.load32 = GBALoad32;
 30	memory->d.load16 = GBALoad16;
 31	memory->d.loadU16 = GBALoadU16;
 32	memory->d.load8 = GBALoad8;
 33	memory->d.loadU8 = GBALoadU8;
 34	memory->d.store32 = GBAStore32;
 35	memory->d.store16 = GBAStore16;
 36	memory->d.store8 = GBAStore8;
 37
 38	memory->bios = 0;
 39	memory->wram = mmap(0, SIZE_WORKING_RAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 40	memory->iwram = mmap(0, SIZE_WORKING_IRAM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
 41	memory->rom = 0;
 42
 43	if (!memory->wram || !memory->iwram) {
 44		GBAMemoryDeinit(memory);
 45		memory->p->errno = GBA_OUT_OF_MEMORY;
 46		memory->p->errstr = GBA_CANNOT_MMAP;
 47	}
 48}
 49
 50void GBAMemoryDeinit(struct GBAMemory* memory) {
 51	munmap(memory->wram, SIZE_WORKING_RAM);
 52	munmap(memory->iwram, SIZE_WORKING_IRAM);
 53}
 54
 55void GBABoardInit(struct GBABoard* board) {
 56	board->d.reset = GBABoardReset;
 57}
 58
 59void GBABoardReset(struct ARMBoard* board) {
 60	struct ARMCore* cpu = board->cpu;
 61	ARMSetPrivilegeMode(cpu, MODE_IRQ);
 62	cpu->gprs[ARM_SP] = SP_BASE_IRQ;
 63	ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
 64	cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR;
 65	ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
 66	cpu->gprs[ARM_SP] = SP_BASE_SYSTEM;
 67}
 68
 69void GBALoadROM(struct GBA* gba, int fd) {
 70	gba->memory.rom = mmap(0, SIZE_CART0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
 71	// TODO: error check
 72}
 73
 74int32_t GBALoad32(struct ARMMemory* memory, uint32_t address) {
 75	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
 76
 77	switch (address & ~OFFSET_MASK) {
 78	case BASE_BIOS:
 79		break;
 80	case BASE_WORKING_RAM:
 81		break;
 82	case BASE_WORKING_IRAM:
 83		break;
 84	case BASE_IO:
 85		break;
 86	case BASE_PALETTE_RAM:
 87		break;
 88	case BASE_VRAM:
 89		break;
 90	case BASE_OAM:
 91		break;
 92	case BASE_CART0:
 93	case BASE_CART0_EX:
 94	case BASE_CART1:
 95	case BASE_CART1_EX:
 96	case BASE_CART2:
 97	case BASE_CART2_EX:
 98		return gbaMemory->rom[(address & (SIZE_CART0 - 1)) >> 2];
 99	case BASE_CART_SRAM:
100		break;
101	default:
102		break;
103	}
104
105	return 0;
106}
107
108int16_t GBALoad16(struct ARMMemory* memory, uint32_t address) {
109	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
110
111	switch (address & ~OFFSET_MASK) {
112	case BASE_BIOS:
113		break;
114	case BASE_WORKING_RAM:
115		break;
116	case BASE_WORKING_IRAM:
117		break;
118	case BASE_IO:
119		break;
120	case BASE_PALETTE_RAM:
121		break;
122	case BASE_VRAM:
123		break;
124	case BASE_OAM:
125		break;
126	case BASE_CART0:
127	case BASE_CART0_EX:
128	case BASE_CART1:
129	case BASE_CART1_EX:
130	case BASE_CART2:
131	case BASE_CART2_EX:
132		return ((int16_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1)) >> 1];
133		break;
134	case BASE_CART_SRAM:
135		break;
136	default:
137		break;
138	}
139
140	return 0;
141}
142
143uint16_t GBALoadU16(struct ARMMemory* memory, uint32_t address) {
144	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
145
146	switch (address & ~OFFSET_MASK) {
147	case BASE_BIOS:
148		break;
149	case BASE_WORKING_RAM:
150		break;
151	case BASE_WORKING_IRAM:
152		break;
153	case BASE_IO:
154		break;
155	case BASE_PALETTE_RAM:
156		break;
157	case BASE_VRAM:
158		break;
159	case BASE_OAM:
160		break;
161	case BASE_CART0:
162	case BASE_CART0_EX:
163	case BASE_CART1:
164	case BASE_CART1_EX:
165	case BASE_CART2:
166	case BASE_CART2_EX:
167		return ((uint16_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1)) >> 1];
168		break;
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		break;
186	case BASE_WORKING_IRAM:
187		break;
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		break;
204	case BASE_CART_SRAM:
205		break;
206	default:
207		break;
208	}
209
210	return 0;
211}
212
213uint8_t GBALoadU8(struct ARMMemory* memory, uint32_t address) {
214	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
215
216	switch (address & ~OFFSET_MASK) {
217	case BASE_BIOS:
218		break;
219	case BASE_WORKING_RAM:
220		break;
221	case BASE_WORKING_IRAM:
222		break;
223	case BASE_IO:
224		break;
225	case BASE_PALETTE_RAM:
226		break;
227	case BASE_VRAM:
228		break;
229	case BASE_OAM:
230		break;
231	case BASE_CART0:
232	case BASE_CART0_EX:
233	case BASE_CART1:
234	case BASE_CART1_EX:
235	case BASE_CART2:
236	case BASE_CART2_EX:
237		return ((uint8_t*) gbaMemory->rom)[(address & (SIZE_CART0 - 1))];
238		break;
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		break;
254	case BASE_WORKING_IRAM:
255		break;
256	case BASE_IO:
257		break;
258	case BASE_PALETTE_RAM:
259		break;
260	case BASE_VRAM:
261		break;
262	case BASE_OAM:
263		break;
264	case BASE_CART0:
265		break;
266	case BASE_CART2_EX:
267		break;
268	case BASE_CART_SRAM:
269		break;
270	default:
271		break;
272	}
273}
274
275void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value) {
276	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
277
278	switch (address & ~OFFSET_MASK) {
279	case BASE_WORKING_RAM:
280		break;
281	case BASE_WORKING_IRAM:
282		break;
283	case BASE_IO:
284		break;
285	case BASE_PALETTE_RAM:
286		break;
287	case BASE_VRAM:
288		break;
289	case BASE_OAM:
290		break;
291	case BASE_CART0:
292		break;
293	case BASE_CART2_EX:
294		break;
295	case BASE_CART_SRAM:
296		break;
297	default:
298		break;
299	}
300}
301
302void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value) {
303	struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
304
305	switch (address & ~OFFSET_MASK) {
306	case BASE_WORKING_RAM:
307		break;
308	case BASE_WORKING_IRAM:
309		break;
310	case BASE_IO:
311		break;
312	case BASE_PALETTE_RAM:
313		break;
314	case BASE_VRAM:
315		break;
316	case BASE_OAM:
317		break;
318	case BASE_CART0:
319		break;
320	case BASE_CART2_EX:
321		break;
322	case BASE_CART_SRAM:
323		break;
324	default:
325		break;
326	}
327}