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 break;
133 case BASE_CART_SRAM:
134 break;
135 default:
136 break;
137 }
138
139 return 0;
140}
141
142uint16_t GBALoadU16(struct ARMMemory* memory, uint32_t address) {
143 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
144
145 switch (address & ~OFFSET_MASK) {
146 case BASE_BIOS:
147 break;
148 case BASE_WORKING_RAM:
149 break;
150 case BASE_WORKING_IRAM:
151 break;
152 case BASE_IO:
153 break;
154 case BASE_PALETTE_RAM:
155 break;
156 case BASE_VRAM:
157 break;
158 case BASE_OAM:
159 break;
160 case BASE_CART0:
161 case BASE_CART0_EX:
162 case BASE_CART1:
163 case BASE_CART1_EX:
164 case BASE_CART2:
165 case BASE_CART2_EX:
166 break;
167 case BASE_CART_SRAM:
168 break;
169 default:
170 break;
171 }
172
173 return 0;
174}
175
176int8_t GBALoad8(struct ARMMemory* memory, uint32_t address) {
177 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
178
179 switch (address & ~OFFSET_MASK) {
180 case BASE_BIOS:
181 break;
182 case BASE_WORKING_RAM:
183 break;
184 case BASE_WORKING_IRAM:
185 break;
186 case BASE_IO:
187 break;
188 case BASE_PALETTE_RAM:
189 break;
190 case BASE_VRAM:
191 break;
192 case BASE_OAM:
193 break;
194 case BASE_CART0:
195 case BASE_CART0_EX:
196 case BASE_CART1:
197 case BASE_CART1_EX:
198 case BASE_CART2:
199 case BASE_CART2_EX:
200 break;
201 case BASE_CART_SRAM:
202 break;
203 default:
204 break;
205 }
206
207 return 0;
208}
209
210uint8_t GBALoadU8(struct ARMMemory* memory, uint32_t address) {
211 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
212
213 switch (address & ~OFFSET_MASK) {
214 case BASE_BIOS:
215 break;
216 case BASE_WORKING_RAM:
217 break;
218 case BASE_WORKING_IRAM:
219 break;
220 case BASE_IO:
221 break;
222 case BASE_PALETTE_RAM:
223 break;
224 case BASE_VRAM:
225 break;
226 case BASE_OAM:
227 break;
228 case BASE_CART0:
229 case BASE_CART0_EX:
230 case BASE_CART1:
231 case BASE_CART1_EX:
232 case BASE_CART2:
233 case BASE_CART2_EX:
234 break;
235 case BASE_CART_SRAM:
236 break;
237 default:
238 break;
239 }
240
241 return 0;
242}
243
244void GBAStore32(struct ARMMemory* memory, uint32_t address, int32_t value) {
245 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
246
247 switch (address & ~OFFSET_MASK) {
248 case BASE_WORKING_RAM:
249 break;
250 case BASE_WORKING_IRAM:
251 break;
252 case BASE_IO:
253 break;
254 case BASE_PALETTE_RAM:
255 break;
256 case BASE_VRAM:
257 break;
258 case BASE_OAM:
259 break;
260 case BASE_CART0:
261 break;
262 case BASE_CART2_EX:
263 break;
264 case BASE_CART_SRAM:
265 break;
266 default:
267 break;
268 }
269}
270
271void GBAStore16(struct ARMMemory* memory, uint32_t address, int16_t value) {
272 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
273
274 switch (address & ~OFFSET_MASK) {
275 case BASE_WORKING_RAM:
276 break;
277 case BASE_WORKING_IRAM:
278 break;
279 case BASE_IO:
280 break;
281 case BASE_PALETTE_RAM:
282 break;
283 case BASE_VRAM:
284 break;
285 case BASE_OAM:
286 break;
287 case BASE_CART0:
288 break;
289 case BASE_CART2_EX:
290 break;
291 case BASE_CART_SRAM:
292 break;
293 default:
294 break;
295 }
296}
297
298void GBAStore8(struct ARMMemory* memory, uint32_t address, int8_t value) {
299 struct GBAMemory* gbaMemory = (struct GBAMemory*) memory;
300
301 switch (address & ~OFFSET_MASK) {
302 case BASE_WORKING_RAM:
303 break;
304 case BASE_WORKING_IRAM:
305 break;
306 case BASE_IO:
307 break;
308 case BASE_PALETTE_RAM:
309 break;
310 case BASE_VRAM:
311 break;
312 case BASE_OAM:
313 break;
314 case BASE_CART0:
315 break;
316 case BASE_CART2_EX:
317 break;
318 case BASE_CART_SRAM:
319 break;
320 default:
321 break;
322 }
323}