all repos — mgba @ 2fe2c80ae5aec5cddfe31d0f804cc5a0c58a521f

mGBA Game Boy Advance Emulator

Add dummy renderer + frame counting infrastructure from GBA.js
Jeffrey Pfau jeffrey@endrift.com
Mon, 15 Apr 2013 23:01:40 -0700
commit

2fe2c80ae5aec5cddfe31d0f804cc5a0c58a521f

parent

9b5d5d64782d103125da2d8c4eff04832b9f220a

4 files changed, 115 insertions(+), 5 deletions(-)

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

@@ -100,7 +100,7 @@ cpu->cpsr.packed = MODE_SYSTEM;

cpu->spsr.packed = 0; cpu->cycles = 0; - cpu->nextEvent = INT_MAX; + cpu->nextEvent = 0; cpu->shifterOperand = 0; cpu->shifterCarryOut = 0;
M src/gba/gba-video.csrc/gba/gba-video.c

@@ -2,7 +2,23 @@ #include "gba-video.h"

#include <limits.h> +static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer); +static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer); +static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); +static void GBAVideoDummyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); +static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer); + +static struct GBAVideoRenderer dummyRenderer = { + .init = GBAVideoDummyRendererInit, + .deinit = GBAVideoDummyRendererDeinit, + .writeVideoRegister = GBAVideoDummyRendererWriteVideoRegister, + .drawScanline = GBAVideoDummyRendererDrawScanline, + .finishFrame = GBAVideoDummyRendererFinishFrame +}; + void GBAVideoInit(struct GBAVideo* video) { + video->renderer = &dummyRenderer; + video->inHblank = 0; video->inVblank = 0; video->vcounter = 0;

@@ -23,5 +39,94 @@ video->nextVcounterIRQ = 0;

} int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) { - return INT_MAX; + video->nextEvent -= cycles; + if (video->nextEvent <= 0) { + video->lastHblank -= video->eventDiff; + video->nextHblank -= video->eventDiff; + video->nextHblankIRQ -= video->eventDiff; + video->nextVcounterIRQ -= video->eventDiff; + + if (video->inHblank) { + // End Hblank + video->inHblank = 0; + video->nextEvent = video->nextHblank; + + ++video->vcount; + + switch (video->vcount) { + case VIDEO_VERTICAL_PIXELS: + video->inVblank = 1; + video->renderer->finishFrame(video->renderer); + video->nextVblankIRQ = video->nextEvent + VIDEO_TOTAL_LENGTH; + //video->cpu.mmu.runVblankDmas(); + if (video->vblankIRQ) { + //video->cpu.irq.raiseIRQ(video->cpu.irq.IRQ_VBLANK); + } + //video->vblankCallback(); + break; + case VIDEO_VERTICAL_TOTAL_PIXELS - 1: + video->inVblank = 0; + break; + case VIDEO_VERTICAL_TOTAL_PIXELS: + video->vcount = 0; + //video->renderPath.startDraw(); + break; + } + + video->vcounter = video->vcount == video->vcountSetting; + if (video->vcounter && video->vcounterIRQ) { + //video->cpu.irq.raiseIRQ(video->cpu.irq.IRQ_VCOUNTER); + video->nextVcounterIRQ += VIDEO_TOTAL_LENGTH; + } + + if (video->vcount < VIDEO_VERTICAL_PIXELS) { + video->renderer->drawScanline(video->renderer, video->vcount); + } + } else { + // Begin Hblank + video->inHblank = 1; + video->lastHblank = video->nextHblank; + video->nextEvent = video->lastHblank + VIDEO_HBLANK_LENGTH; + video->nextHblank = video->nextEvent + VIDEO_HDRAW_LENGTH; + video->nextHblankIRQ = video->nextHblank; + + if (video->vcount < VIDEO_VERTICAL_PIXELS) { + //video->cpu.mmu.runHblankDmas(); + } + if (video->hblankIRQ) { + //video->cpu.irq.raiseIRQ(video->cpu.irq.IRQ_HBLANK); + } + } + + video->eventDiff = video->nextEvent; + } + return video->nextEvent; +} + + +static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer) { + (void)(renderer); + // Nothing to do +} + +static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer) { + (void)(renderer); + // Nothing to do +} +static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { + (void)(renderer); + (void)(address); + return value; +} + +static void GBAVideoDummyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { + (void)(renderer); + (void)(y); + // Nothing to do +} + +static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer) { + (void)(renderer); + printf("Drawing a frame\n"); + // Nothing to do }
M src/gba/gba-video.hsrc/gba/gba-video.h

@@ -26,12 +26,13 @@ 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); + void (*drawScanline)(struct GBAVideoRenderer* renderer, int y); + void (*finishFrame)(struct GBAVideoRenderer* renderer); }; struct GBAVideo { - struct GBAVideoRenderer renderer; + struct GBA* p; + struct GBAVideoRenderer* renderer; // DISPSTAT int inHblank;

@@ -49,6 +50,7 @@

int32_t lastHblank; int32_t nextHblank; int32_t nextEvent; + int32_t eventDiff; int32_t nextHblankIRQ; int32_t nextVblankIRQ;
M src/gba/gba.csrc/gba/gba.c

@@ -33,6 +33,9 @@ gba->board.p = gba;

GBABoardInit(&gba->board); ARMAssociateBoard(&gba->cpu, &gba->board.d); + gba->video.p = gba; + GBAVideoInit(&gba->video); + ARMReset(&gba->cpu); }