all repos — mgba @ 9b5d5d64782d103125da2d8c4eff04832b9f220a

mGBA Game Boy Advance Emulator

Start implementing events + add video stubs
Jeffrey Pfau jeffrey@endrift.com
Mon, 15 Apr 2013 22:18:28 -0700
commit

9b5d5d64782d103125da2d8c4eff04832b9f220a

parent

1838cc0597ed00d5293134eb6af64f83493c889c

6 files changed, 114 insertions(+), 3 deletions(-)

jump to
M src/arm/arm.csrc/arm/arm.c

@@ -117,4 +117,7 @@ ThumbStep(cpu);

} else { ARMStep(cpu); } + if (cpu->cycles >= cpu->nextEvent) { + cpu->board->processEvents(cpu->board); + } }
M src/arm/arm.hsrc/arm/arm.h

@@ -87,7 +87,7 @@

struct ARMBoard { struct ARMCore* cpu; void (*reset)(struct ARMBoard* board); - void (*nextEvent)(struct ARMBoard* board); + void (*processEvents)(struct ARMBoard* board); void (*swi16)(struct ARMBoard* board, int immediate); void (*swi32)(struct ARMBoard* board, int immediate);

@@ -99,8 +99,8 @@ int32_t gprs[16];

union PSR cpsr; union PSR spsr; - uint32_t cycles; - uint32_t nextEvent; + int32_t cycles; + int32_t nextEvent; int32_t bankedRegisters[6][7]; int32_t bankedSPSRs[6];
A src/gba/gba-video.c

@@ -0,0 +1,27 @@

+#include "gba-video.h" + +#include <limits.h> + +void GBAVideoInit(struct GBAVideo* video) { + video->inHblank = 0; + video->inVblank = 0; + video->vcounter = 0; + video->vblankIRQ = 0; + video->hblankIRQ = 0; + video->vcounterIRQ = 0; + video->vcountSetting = 0; + + video->vcount = -1; + + video->lastHblank = 0; + video->nextHblank = VIDEO_HDRAW_LENGTH; + video->nextEvent = video->nextHblank; + + video->nextHblankIRQ = 0; + video->nextVblankIRQ = 0; + video->nextVcounterIRQ = 0; +} + +int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) { + return INT_MAX; +}
A src/gba/gba-video.h

@@ -0,0 +1,61 @@

+#ifndef GBA_VIDEO_H +#define GBA_VIDEO_H + +#include <stdint.h> + +enum { + VIDEO_CYCLES_PER_PIXEL = 4, + + VIDEO_HORIZONTAL_PIXELS = 240, + VIDEO_HBLANK_PIXELS = 68, + VIDEO_HDRAW_LENGTH = 1006, + VIDEO_HBLANK_LENGTH = 226, + VIDEO_HORIZONTAL_LENGTH = 1232, + + VIDEO_VERTICAL_PIXELS = 160, + VIDEO_VBLANK_PIXELS = 68, + VIDEO_VERTICAL_TOTAL_PIXELS = 228, + + VIDEO_TOTAL_LENGTH = 280896, + + REG_DISPSTAT_MASK = 0xFF38 +}; + +struct GBAVideoRenderer { + void (*init)(struct GBAVideoRenderer* renderer); + void (*deinit)(struct GBAVideoRenderer* renderer); + + uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); + void (*drawScanline)(struct GBAVideoRenderer* video, int y); + void (*finishFrame)(struct GBAVideoRenderer* video); +}; + +struct GBAVideo { + struct GBAVideoRenderer renderer; + + // DISPSTAT + int inHblank; + int inVblank; + int vcounter; + int blankIRQ; + int vblankIRQ; + int hblankIRQ; + int vcounterIRQ; + int vcountSetting; + + // VCOUNT + int vcount; + + int32_t lastHblank; + int32_t nextHblank; + int32_t nextEvent; + + int32_t nextHblankIRQ; + int32_t nextVblankIRQ; + int32_t nextVcounterIRQ; +}; + +void GBAVideoInit(struct GBAVideo* video); +int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles); + +#endif
M src/gba/gba.csrc/gba/gba.c

@@ -4,6 +4,7 @@ #include "gba-bios.h"

#include "debugger.h" +#include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h>

@@ -15,6 +16,7 @@ SP_BASE_IRQ = 0x03FFFFA0,

SP_BASE_SUPERVISOR = 0x03FFFFE0 }; +static void GBAProcessEvents(struct ARMBoard* board); static void GBAHitStub(struct ARMBoard* board, uint32_t opcode); void GBAInit(struct GBA* gba) {

@@ -40,6 +42,7 @@ }

void GBABoardInit(struct GBABoard* board) { board->d.reset = GBABoardReset; + board->d.processEvents = GBAProcessEvents; board->d.swi16 = GBASwi16; board->d.swi32 = GBASwi32; board->d.hitStub = GBAHitStub;

@@ -53,6 +56,21 @@ ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);

cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR; ARMSetPrivilegeMode(cpu, MODE_SYSTEM); cpu->gprs[ARM_SP] = SP_BASE_SYSTEM; +} + +static void GBAProcessEvents(struct ARMBoard* board) { + struct GBABoard* gbaBoard = (struct GBABoard*) board; + int32_t cycles = board->cpu->cycles; + int32_t nextEvent = INT_MAX; + int32_t testEvent; + + testEvent = GBAVideoProcessEvents(&gbaBoard->p->video, cycles); + if (testEvent < nextEvent) { + nextEvent = testEvent; + } + + board->cpu->cycles = 0; + board->cpu->nextEvent = nextEvent; } void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger) {
M src/gba/gba.hsrc/gba/gba.h

@@ -4,6 +4,7 @@

#include "arm.h" #include "gba-memory.h" +#include "gba-video.h" enum GBAError { GBA_NO_ERROR = 0,

@@ -23,6 +24,7 @@ struct GBA {

struct ARMCore cpu; struct GBABoard board; struct GBAMemory memory; + struct GBAVideo video; struct ARMDebugger* debugger;