summaryrefslogtreecommitdiff
path: root/ops.yaml
diff options
context:
space:
mode:
Diffstat (limited to 'ops.yaml')
-rw-r--r--ops.yaml159
1 files changed, 91 insertions, 68 deletions
diff --git a/ops.yaml b/ops.yaml
index 61db5ee..6bf9870 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -1890,7 +1890,7 @@ ops:
h:
c:
code: |
- mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_H));
+ mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_L));
- id: HALT
hex: 0x76
cat: misc
@@ -2022,7 +2022,7 @@ ops:
cat: "8-bit load/store/move"
op: LD
dst: A
- src: L
+ src: (HL)
len: 1
pc: true
time: 8
@@ -2144,7 +2144,7 @@ ops:
h: H
c: C
code: |
- add_rb(ctx, RB_H);
+ add_rb(ctx, RB_L);
- id: ADD A, (HL)
hex: 0x86
cat: "8-bit math"
@@ -3067,6 +3067,7 @@ ops:
h:
c:
code: |
+ cpu_ww(ctx, RW_PC, old_pc + 1);
if (!FLAG(ctx, Z)) {
pop_rw(ctx, RW_PC);
clock = 20;
@@ -3197,7 +3198,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x00);
- id: RET Z
hex: 0xC8
@@ -3340,7 +3341,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x08);
- id: RET NC
hex: 0xD0
@@ -3429,7 +3430,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 3);
+ cpu_ww(ctx, RW_PC, old_pc + 3);
if (!FLAG(ctx, C)) {
call_a16(ctx, old_pc + 1);
clock = 24;
@@ -3481,7 +3482,7 @@ ops:
h: H
c: C
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x10);
- id: RET C
hex: 0xD8
@@ -3521,8 +3522,8 @@ ops:
c:
code: |
// pop pc, enable interrupts
- pop_rw(ctx, RW_PC);
ctx->cpu.ime = true;
+ pop_rw(ctx, RW_PC);
- id: JP C, a16
hex: 0xDA
cat: "jumps/calls"
@@ -3612,7 +3613,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x18);
- id: LDH (a8), A
hex: 0xE0
@@ -3666,6 +3667,8 @@ ops:
hex: 0xE3
cat: "invalid"
op: XX
+ code: |
+ cpu_set_state(ctx, old_pc, GB_CPU_STATE_INVALID);
- id: XX
hex: 0xE4
cat: "invalid"
@@ -3718,7 +3721,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x20);
- id: ADD SP, r8
hex: 0xE8
@@ -3815,7 +3818,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x28);
- id: LDH A, (a8)
hex: 0xF0
@@ -3931,7 +3934,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x30);
- id: LD HL, SP+r8
hex: 0xF8
@@ -4039,7 +4042,7 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + 1);
+ cpu_ww(ctx, RW_PC, old_pc + 1);
rst(ctx, 0x38);
cb:
@@ -8561,6 +8564,7 @@ templates:
static void gpu_set_line(gb_t * const ctx, const uint8_t line);
static void gpu_set_mode(gb_t * const ctx, const uint8_t mode);
static bool gpu_is_active(const gb_t * const ctx);
+ static uint8_t gpu_get_mode(const gb_t * const ctx);
static uint8_t
mmu_rp(
@@ -8820,7 +8824,7 @@ templates:
const gb_t * const ctx,
const uint16_t addr
) {
- switch (ctx->gpu.mode & 0x3) {
+ switch (gpu_get_mode(ctx)) {
case GPU_MODE_VRAM:
return 0xFF;
default:
@@ -8834,7 +8838,7 @@ templates:
const gb_t * const ctx,
const uint16_t addr
) {
- switch (ctx->gpu.mode & 0x3) {
+ switch (gpu_get_mode(ctx)) {
case GPU_MODE_HBLANK:
case GPU_MODE_VBLANK:
// oam memory (160 bytes):
@@ -8954,7 +8958,7 @@ templates:
const uint16_t addr,
const uint8_t val
) {
- switch (ctx->gpu.mode & 0x3) {
+ switch (gpu_get_mode(ctx)) {
case GPU_MODE_HBLANK:
case GPU_MODE_VBLANK:
case GPU_MODE_OAM:
@@ -8973,13 +8977,14 @@ templates:
const uint16_t addr,
const uint8_t val
) {
- switch (ctx->gpu.mode & 0x3) {
+ switch (gpu_get_mode(ctx) & 0x3) {
case GPU_MODE_HBLANK:
case GPU_MODE_VBLANK:
// oam memory (160 bytes):
ctx->mmu.oam[addr & 0xFF] = val;
- // TODO: invalidate OAM cache
+ // invalidate oam cache
+ ctx->gpu.oam_dirty = true;
break;
default:
@@ -10115,7 +10120,7 @@ templates:
gpu_get_mode(
const gb_t * const ctx
) {
- return ctx->gpu.mode & 0x3;
+ return gpu_is_active(ctx) ? (ctx->gpu.mode & 0x3) : GPU_MODE_VBLANK;
}
static void
@@ -10166,86 +10171,94 @@ templates:
}
static void
- gpu_draw_line(
+ gpu_oam_cache(
gb_t * const ctx
) {
- struct {
- uint8_t x, y, tile;
- bool priority,
- y_flip,
- x_flip,
- palette;
- } objs[40];
+ if (!ctx->gpu.oam_dirty) {
+ return;
+ }
// decode oam
- for (int i = 0; i < 40; i++) {
- objs[i].y = (ctx->mmu.oam[i * 4 + 0] + 16) & 0xFF;
- objs[i].x = (ctx->mmu.oam[i * 4 + 1] + 8) & 0xFF;
- objs[i].tile = ctx->mmu.oam[i * 4 + 2];
+ 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];
const uint8_t flags = ctx->mmu.oam[i * 4 + 3];
- objs[i].priority = flags & (1 << 7);
- objs[i].y_flip = flags & (1 << 6);
- objs[i].x_flip = flags & (1 << 5);
- objs[i].palette = flags & (1 << 4);
+ 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);
+ ctx->gpu.oam_cache[i].palette = flags & (1 << 4);
}
+ // clear dirty flag
+ ctx->gpu.oam_dirty = false;
+ }
+
+ static void
+ gpu_draw_line(
+ gb_t * const ctx
+ ) {
+ gpu_oam_cache(ctx);
+
// draw sprites behind bg
- for (int i = 0; i < 40; i++) {
+ for (uint8_t i = 0; i < 40; i++) {
if (
// sprite is below bg
- objs[i].priority &&
+ ctx->gpu.oam_cache[i].priority &&
// sprite is on screen
- objs[i].y < 144 && objs[i].x < 160 &&
+ ctx->gpu.oam_cache[i].y < 144 &&
+ ctx->gpu.oam_cache[i].x < 160 &&
// sprite is on current line
- ctx->gpu.line >= objs[i].y &&
- ctx->gpu.line <= objs[i].y
+ 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 - objs[i].x);
+ 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 * (objs[i].y * 160 + objs[i].x + 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.rgb[ofs + 0] = 0xff;
- ctx->gpu.rgb[ofs + 1] = 0xff;
- ctx->gpu.rgb[ofs + 2] = 0xff;
+ ctx->gpu.fb[ofs + 0] = 0xff;
+ ctx->gpu.fb[ofs + 1] = 0xff;
+ ctx->gpu.fb[ofs + 2] = 0xff;
}
}
}
// TODO: draw background
- for (int i = 0; i < 160; i++) {
+ for (uint8_t i = 0; i < 160; i++) {
// interim: set line to red
- ctx->gpu.rgb[3 * (ctx->gpu.line * 160 + i) + 0] = 0xff;
- ctx->gpu.rgb[3 * (ctx->gpu.line * 160 + i) + 1] = 0x00;
- ctx->gpu.rgb[3 * (ctx->gpu.line * 160 + i) + 2] = 0x00;
+ 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 (int i = 0; i < 40; i++) {
+ for (uint8_t i = 0; i < 40; i++) {
if (
// sprite is above bg
- !objs[i].priority &&
+ !ctx->gpu.oam_cache[i].priority &&
// sprite is on screen
- objs[i].y < 144 && objs[i].x < 160 &&
+ ctx->gpu.oam_cache[i].y < 144 &&
+ ctx->gpu.oam_cache[i].x < 160 &&
// sprite is on current line
- ctx->gpu.line >= objs[i].y &&
- ctx->gpu.line <= objs[i].y
+ 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 - objs[i].x);
+ 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 * (objs[i].y * 160 + objs[i].x + 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.rgb[ofs + 0] = 0xff;
- ctx->gpu.rgb[ofs + 1] = 0xff;
- ctx->gpu.rgb[ofs + 2] = 0xff;
+ ctx->gpu.fb[ofs + 0] = 0xff;
+ ctx->gpu.fb[ofs + 1] = 0xff;
+ ctx->gpu.fb[ofs + 2] = 0xff;
}
}
}
@@ -10286,7 +10299,7 @@ templates:
break;
case GPU_MODE_HBLANK:
if (ctx->gpu.clock >= 204) {
- // clear clock, draw line, increment line
+ // clear clock
ctx->gpu.clock -= 204;
// draw and increment line
@@ -10565,10 +10578,10 @@ templates:
}
const uint8_t *
- gb_get_rgb_frame(
+ gb_get_frame(
const gb_t * const ctx
) {
- return ctx->gpu.rgb;
+ return ctx->gpu.fb;
}
static void
@@ -10589,6 +10602,21 @@ templates:
cpu_set_state(ctx, 0, GB_CPU_STATE_RUN);
}
+ static void
+ gpu_init(
+ gb_t * const ctx
+ ) {
+ gpu_set_mode(ctx, GPU_MODE_OAM);
+ gpu_set_line(ctx, 0);
+ ctx->gpu.lcdc = 0x91;
+ ctx->gpu.bgp = 0xFC;
+ ctx->gpu.obp0 = 0xFF;
+ ctx->gpu.obp1 = 0xFF;
+
+ // flag oam as dirty
+ ctx->gpu.oam_dirty = true;
+ }
+
void gb_init(
gb_t * const ctx,
const gb_config_t * const config,
@@ -10609,10 +10637,5 @@ templates:
ctx->mmu.rom_size = rom_size;
// init gpu
- gpu_set_mode(ctx, GPU_MODE_OAM);
- gpu_set_line(ctx, 0);
- ctx->gpu.lcdc = 0x91;
- ctx->gpu.bgp = 0xFC;
- ctx->gpu.obp0 = 0xFF;
- ctx->gpu.obp1 = 0xFF;
+ gpu_init(ctx);
}