From 2fe2c80ae5aec5cddfe31d0f804cc5a0c58a521f Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 15 Apr 2013 23:01:40 -0700 Subject: [PATCH] Add dummy renderer + frame counting infrastructure from GBA.js --- src/arm/arm.c | 2 +- src/gba/gba-video.c | 107 +++++++++++++++++++++++++++++++++++++++++++- src/gba/gba-video.h | 8 ++-- src/gba/gba.c | 3 ++ 4 files changed, 115 insertions(+), 5 deletions(-) diff --git a/src/arm/arm.c b/src/arm/arm.c index 885a1bdcb..559a4aee4 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -100,7 +100,7 @@ void ARMReset(struct ARMCore* cpu) { cpu->spsr.packed = 0; cpu->cycles = 0; - cpu->nextEvent = INT_MAX; + cpu->nextEvent = 0; cpu->shifterOperand = 0; cpu->shifterCarryOut = 0; diff --git a/src/gba/gba-video.c b/src/gba/gba-video.c index 052fc031b..6a66835d9 100644 --- a/src/gba/gba-video.c +++ b/src/gba/gba-video.c @@ -2,7 +2,23 @@ #include +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 @@ void GBAVideoInit(struct GBAVideo* video) { } 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 } diff --git a/src/gba/gba-video.h b/src/gba/gba-video.h index d04f2d5cc..0c59141ff 100644 --- a/src/gba/gba-video.h +++ b/src/gba/gba-video.h @@ -26,12 +26,13 @@ struct GBAVideoRenderer { 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 @@ struct GBAVideo { int32_t lastHblank; int32_t nextHblank; int32_t nextEvent; + int32_t eventDiff; int32_t nextHblankIRQ; int32_t nextVblankIRQ; diff --git a/src/gba/gba.c b/src/gba/gba.c index daec554f5..1294ca33a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -33,6 +33,9 @@ void GBAInit(struct GBA* gba) { GBABoardInit(&gba->board); ARMAssociateBoard(&gba->cpu, &gba->board.d); + gba->video.p = gba; + GBAVideoInit(&gba->video); + ARMReset(&gba->cpu); }