diff options
-rw-r--r-- | ops.yaml | 204 | ||||
-rw-r--r-- | test.c | 12 |
2 files changed, 120 insertions, 96 deletions
@@ -8089,12 +8089,14 @@ templates: #define UNUSED(a) ((void) (a)) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) + // cpu flags #define FLAG(ctx, f) (cpu_rb(ctx, RB_F) & (F_##f)) #define F_Z (1 << 7) #define F_N (1 << 6) #define F_H (1 << 5) #define F_C (1 << 4) + // interrupts #define IRQ_VBLANK (1) #define IRQ_LCDC (1 << 1) #define IRQ_TIMER (1 << 2) @@ -8830,10 +8832,9 @@ templates: const gb_t * const ctx, const uint16_t addr ) { - switch (gpu_get_mode(ctx)) { - case GPU_MODE_VRAM: + if (gpu_is_active(ctx) && gpu_get_mode(ctx) == GPU_MODE_VRAM) { return 0xFF; - default: + } else { // return vram (8k) return ctx->mmu.vram[addr & 0x1FFF]; } @@ -8844,13 +8845,18 @@ templates: const gb_t * const ctx, const uint16_t addr ) { - switch (gpu_get_mode(ctx)) { - case GPU_MODE_HBLANK: - case GPU_MODE_VBLANK: + if (gpu_is_active(ctx)) { + switch (gpu_get_mode(ctx)) { + case GPU_MODE_HBLANK: + case GPU_MODE_VBLANK: + // oam memory (160 bytes): + return ctx->mmu.oam[addr & 0xFF]; + default: + return 0; + } + } else { // oam memory (160 bytes): return ctx->mmu.oam[addr & 0xFF]; - default: - return 0; } } @@ -8964,16 +8970,21 @@ templates: const uint16_t addr, const uint8_t val ) { - switch (gpu_get_mode(ctx)) { - case GPU_MODE_HBLANK: - case GPU_MODE_VBLANK: - case GPU_MODE_OAM: + if (gpu_is_active(ctx)) { + switch (gpu_get_mode(ctx)) { + case GPU_MODE_HBLANK: + case GPU_MODE_VBLANK: + case GPU_MODE_OAM: + // vram (8k) + ctx->mmu.vram[addr & 0x1FFF] = val; + break; + default: + // do nothing + break; + } + } else { // vram (8k) ctx->mmu.vram[addr & 0x1FFF] = val; - break; - default: - // do nothing - break; } } @@ -8983,19 +8994,21 @@ templates: const uint16_t addr, const uint8_t val ) { - switch (gpu_get_mode(ctx) & 0x3) { - case GPU_MODE_HBLANK: - case GPU_MODE_VBLANK: - // oam memory (160 bytes): - ctx->mmu.oam[addr & 0xFF] = val; + if (gpu_is_active(ctx)) { + switch (gpu_get_mode(ctx) & 0x3) { + case GPU_MODE_HBLANK: + case GPU_MODE_VBLANK: + // oam memory (160 bytes): + ctx->mmu.oam[addr & 0xFF] = val; - // invalidate oam cache - ctx->gpu.oam_dirty = true; + // invalidate oam cache + ctx->gpu.oam_dirty = true; - break; - default: - // do nothing - break; + break; + default: + // do nothing + break; + } } } @@ -10180,7 +10193,7 @@ templates: // trigger vblank interrupt cpu_irq(ctx, IRQ_VBLANK); - if (ctx->cpu.ime && (mmu_rb(ctx, PORT_IE) & 1)) { + if (gpu_is_active(ctx) && ctx->cpu.ime && (mmu_rb(ctx, PORT_IE) & 1)) { if (ctx->config && ctx->config->on_vblank) { ctx->config->on_vblank(ctx); } @@ -10200,11 +10213,11 @@ templates: // decode oam for (uint8_t i = 0; i < 40; i++) { - ctx->gpu.oam_cache[i].y = (ctx->mmu.oam[i * 4 + 0] + 16) & 0xFF; - ctx->gpu.oam_cache[i].x = (ctx->mmu.oam[i * 4 + 1] + 8) & 0xFF; - ctx->gpu.oam_cache[i].tile = ctx->mmu.oam[i * 4 + 2]; + ctx->gpu.oam_cache[i].y = (ctx->mmu.oam[4 * i + 0] + 16) & 0xFF; + ctx->gpu.oam_cache[i].x = (ctx->mmu.oam[4 * i + 1] + 8) & 0xFF; + ctx->gpu.oam_cache[i].tile = ctx->mmu.oam[4 * i + 2]; - const uint8_t flags = ctx->mmu.oam[i * 4 + 3]; + const uint8_t flags = ctx->mmu.oam[4 * i + 3]; ctx->gpu.oam_cache[i].priority = flags & (1 << 7); ctx->gpu.oam_cache[i].y_flip = flags & (1 << 6); ctx->gpu.oam_cache[i].x_flip = flags & (1 << 5); @@ -10219,68 +10232,77 @@ templates: gpu_draw_line( gb_t * const ctx ) { - gpu_oam_cache(ctx); + if (gpu_is_active(ctx)) { + gpu_oam_cache(ctx); - // draw sprites behind bg - for (uint8_t i = 0; i < 40; i++) { - if ( - // sprite is below bg - ctx->gpu.oam_cache[i].priority && - - // sprite is on screen - ctx->gpu.oam_cache[i].y < 144 && - ctx->gpu.oam_cache[i].x < 160 && - - // sprite is on current line - ctx->gpu.line >= ctx->gpu.oam_cache[i].y && - ctx->gpu.line <= ctx->gpu.oam_cache[i].y - ) { - const uint8_t max_j = MIN(8, 160 - ctx->gpu.oam_cache[i].x); - - for (uint8_t j = 0; j < max_j; j++) { - const uint32_t ofs = 3 * (ctx->gpu.oam_cache[i].y * 160 + ctx->gpu.oam_cache[i].x + j); - - // TODO: draw sprite scanline - ctx->gpu.fb[ofs + 0] = 0xff; - ctx->gpu.fb[ofs + 1] = 0xff; - ctx->gpu.fb[ofs + 2] = 0xff; + // draw sprites behind bg + for (uint8_t i = 0; i < 40; i++) { + if ( + // sprite is below bg + ctx->gpu.oam_cache[i].priority && + + // sprite is on screen + ctx->gpu.oam_cache[i].y < 144 && + ctx->gpu.oam_cache[i].x < 160 && + + // sprite is on current line + ctx->gpu.line >= ctx->gpu.oam_cache[i].y && + ctx->gpu.line <= ctx->gpu.oam_cache[i].y + ) { + const uint8_t max_j = MIN(8, 160 - ctx->gpu.oam_cache[i].x); + + for (uint8_t j = 0; j < max_j; j++) { + const uint32_t ofs = 3 * (ctx->gpu.oam_cache[i].y * 160 + ctx->gpu.oam_cache[i].x + j); + + // TODO: draw sprite scanline + ctx->gpu.fb[ofs + 0] = 0xff; + ctx->gpu.fb[ofs + 1] = 0xff; + ctx->gpu.fb[ofs + 2] = 0xff; + } } } - } - // TODO: draw background - for (uint8_t i = 0; i < 160; i++) { - // interim: set line to red - ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 0] = 0xff; - ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 1] = 0x00; - ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 2] = 0x00; - } + // TODO: draw background + for (uint8_t i = 0; i < 160; i++) { + // interim: set line to red + ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 0] = 0xff; + ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 1] = 0x00; + ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 2] = 0x00; + } - // draw foreground sprites - for (uint8_t i = 0; i < 40; i++) { - if ( - // sprite is above bg - !ctx->gpu.oam_cache[i].priority && - - // sprite is on screen - ctx->gpu.oam_cache[i].y < 144 && - ctx->gpu.oam_cache[i].x < 160 && - - // sprite is on current line - ctx->gpu.line >= ctx->gpu.oam_cache[i].y && - ctx->gpu.line <= ctx->gpu.oam_cache[i].y - ) { - const uint8_t max_j = MIN(8, 160 - ctx->gpu.oam_cache[i].x); - - for (int j = 0; j < max_j; j++) { - const uint32_t ofs = 3 * (ctx->gpu.oam_cache[i].y * 160 + ctx->gpu.oam_cache[i].x + j); - - // TODO: draw sprite scanline - ctx->gpu.fb[ofs + 0] = 0xff; - ctx->gpu.fb[ofs + 1] = 0xff; - ctx->gpu.fb[ofs + 2] = 0xff; + // draw foreground sprites + for (uint8_t i = 0; i < 40; i++) { + if ( + // sprite is above bg + !ctx->gpu.oam_cache[i].priority && + + // sprite is on screen + ctx->gpu.oam_cache[i].y < 144 && + ctx->gpu.oam_cache[i].x < 160 && + + // sprite is on current line + ctx->gpu.line >= ctx->gpu.oam_cache[i].y && + ctx->gpu.line <= ctx->gpu.oam_cache[i].y + ) { + const uint8_t max_j = MIN(8, 160 - ctx->gpu.oam_cache[i].x); + + for (int j = 0; j < max_j; j++) { + const uint32_t ofs = 3 * (ctx->gpu.oam_cache[i].y * 160 + ctx->gpu.oam_cache[i].x + j); + + // TODO: draw sprite scanline + ctx->gpu.fb[ofs + 0] = 0xff; + ctx->gpu.fb[ofs + 1] = 0xff; + ctx->gpu.fb[ofs + 2] = 0xff; + } } } + } else { + // write blank line + for (uint8_t i = 0; i < 160; i++) { + ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 0] = 0xff; + ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 1] = 0xff; + ctx->gpu.fb[3 * (ctx->gpu.line * 160 + i) + 2] = 0xff; + } } } @@ -10289,10 +10311,6 @@ templates: gb_t * const ctx, const uint16_t clock ) { - if (!gpu_is_active(ctx)) { - return; - } - // increment clock ctx->gpu.clock += clock; @@ -10326,7 +10344,7 @@ templates: gpu_draw_line(ctx); gpu_set_line(ctx, ctx->gpu.line + 1); - if (ctx->gpu.line < 144) { + if (ctx->gpu.line < 143) { // set mode gpu_set_mode(ctx, GPU_MODE_OAM); } else { @@ -10344,7 +10362,7 @@ templates: // clear clock ctx->gpu.clock -= 204; - if (ctx->gpu.line < 154) { + if (ctx->gpu.line < 153) { // increment line gpu_set_line(ctx, ctx->gpu.line + 1); } else { @@ -9,7 +9,8 @@ #include "lodepng.h" #include "gb.h" -#define NUM_FRAMES 600 +#define SKIP_FRAMES 600 +#define NUM_FRAMES 60 // #define SKIP_STEPS 1000000 #define NUM_STEPS 300000 #define UNUSED(a) ((void) (a)) @@ -187,13 +188,18 @@ test_render_frames( gb_init(&ctx, NULL, rom_data, rom_size); fprintf(stderr, "gb context initialized\n"); + for (size_t i = 0; i < SKIP_FRAMES; i++) { + // render frame + gb_frame(&ctx); + } + // render frames - for (size_t j = 0; j < NUM_FRAMES; j++) { + for (size_t i = 0; i < NUM_FRAMES; i++) { // render frame gb_frame(&ctx); // copy frame to buffer - memcpy(frames + GB_FB_SIZE * j, gb_get_frame(&ctx), GB_FB_SIZE); + memcpy(frames + GB_FB_SIZE * i, gb_get_frame(&ctx), GB_FB_SIZE); } // save png |