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 | 
