all repos — mgba @ 90e2443ccd0f525d67095d6b2c559d2a1fc245c4

mGBA Game Boy Advance Emulator

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}