src/gba/gba.c (view raw)
1#include "gba.h"
2
3#include "gba-bios.h"
4
5#include "debugger.h"
6
7#include <stdarg.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <sys/mman.h>
11
12enum {
13 SP_BASE_SYSTEM = 0x03FFFF00,
14 SP_BASE_IRQ = 0x03FFFFA0,
15 SP_BASE_SUPERVISOR = 0x03FFFFE0
16};
17
18static void GBAHitStub(struct ARMBoard* board, uint32_t opcode);
19
20static void _GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value);
21
22void GBAInit(struct GBA* gba) {
23 gba->errno = GBA_NO_ERROR;
24 gba->errstr = 0;
25
26 ARMInit(&gba->cpu);
27
28 gba->memory.p = gba;
29 GBAMemoryInit(&gba->memory);
30 ARMAssociateMemory(&gba->cpu, &gba->memory.d);
31
32 gba->board.p = gba;
33 GBABoardInit(&gba->board);
34 ARMAssociateBoard(&gba->cpu, &gba->board.d);
35
36 ARMReset(&gba->cpu);
37}
38
39void GBADeinit(struct GBA* gba) {
40 GBAMemoryDeinit(&gba->memory);
41}
42
43void GBABoardInit(struct GBABoard* board) {
44 board->d.reset = GBABoardReset;
45 board->d.swi16 = GBASwi16;
46 board->d.swi32 = GBASwi32;
47 board->d.hitStub = GBAHitStub;
48}
49
50void GBABoardReset(struct ARMBoard* board) {
51 struct ARMCore* cpu = board->cpu;
52 ARMSetPrivilegeMode(cpu, MODE_IRQ);
53 cpu->gprs[ARM_SP] = SP_BASE_IRQ;
54 ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
55 cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR;
56 ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
57 cpu->gprs[ARM_SP] = SP_BASE_SYSTEM;
58}
59
60void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger) {
61 ARMDebuggerInit(debugger, &gba->cpu);
62 gba->debugger = debugger;
63}
64
65void GBALoadROM(struct GBA* gba, int fd) {
66 gba->memory.rom = mmap(0, SIZE_CART0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
67 // TODO: error check
68}
69
70void GBALog(int level, const char* format, ...) {
71 va_list args;
72 va_start(args, format);
73 vprintf(format, args);
74 va_end(args);
75 printf("\n");
76}
77
78void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
79 GBALog(GBA_LOG_STUB, "Stub opcode: %08x", opcode);
80 struct GBABoard* gbaBoard = (struct GBABoard*) board;
81 if (!gbaBoard->p->debugger) {
82 abort();
83 } else {
84 ARMDebuggerEnter(gbaBoard->p->debugger);
85 }
86}