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}