summaryrefslogtreecommitdiff
path: root/ops.yaml
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2018-06-24 23:31:28 -0400
committerPaul Duncan <pabs@pablotron.org>2018-06-24 23:31:28 -0400
commit39f6ddc3e27b80c17efe4f2d81ce99ed3a297b9a (patch)
tree96203bbe5881906bca3965f7a488427e3ee9a59e /ops.yaml
parent969e25bb466c2673b46e1345434a71423f4b9fe0 (diff)
downloadgb-c-39f6ddc3e27b80c17efe4f2d81ce99ed3a297b9a.tar.bz2
gb-c-39f6ddc3e27b80c17efe4f2d81ce99ed3a297b9a.zip
add gb_config_t, gb_disasm(), refactor logic, misc cleanups
Diffstat (limited to 'ops.yaml')
-rw-r--r--ops.yaml750
1 files changed, 358 insertions, 392 deletions
diff --git a/ops.yaml b/ops.yaml
index 9266820..b1d2ad3 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -761,6 +761,7 @@ ops:
c:
code: |
cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_A) ^ 0xFF);
+ cpu_wf(ctx, F_N | F_H, F_N | F_H);
- id: JR NC, r8
hex: 0x30
cat: "jumps/calls"
@@ -3746,7 +3747,8 @@ ops:
h:
c:
code: |
- cpu_ww(ctx, RW_PC, mmu_rw(ctx, cpu_rw(ctx, RW_HL)));
+ // cpu_ww(ctx, RW_PC, mmu_rw(ctx, cpu_rw(ctx, RW_HL)));
+ cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_HL));
- id: LD (a16), A
hex: 0xEA
cat: "8-bit load/store/move"
@@ -8073,6 +8075,7 @@ templates:
#include <string.h> // memset()
#include <stdint.h> // uint8_t ,etc
#include <stdbool.h> // bool
+ #include <stdio.h> // snprintf()
#include "gb.h"
#define UNUSED(a) ((void) (a))
@@ -8227,7 +8230,7 @@ templates:
(((ctx->mmu.mbc1.rom_ram_mode ? 0 : ctx->mmu.mbc1.ram_bank) & 0x3) << 19) |
// B: rom_bank (5 bits, low bit set)
- (((ctx->mmu.mbc1.rom_bank & 0x1F) | 0x1) << 15) |
+ (((ctx->mmu.mbc1.rom_bank & 0x1F) | 0x1) << 14) |
// C: address (14 bits)
((addr - 0x4000) & 0x3FFF)
@@ -8262,9 +8265,11 @@ templates:
case 0x6000:
case 0x7000:
// ROM1 (16k, banked)
- // FIXME: clamp to rom size?
- // mbc1 rom1 banking (TCAGBD.pdf, 11.2.2)
- return ctx->mmu.rom[mbc1_rom_get_addr(ctx, addr)];
+ {
+ // mbc1 rom1 banking (TCAGBD.pdf, 11.2.2)
+ const uint32_t addr_ofs = mbc1_rom_get_addr(ctx, addr);
+ return addr_ofs < ctx->mmu.rom_size ? ctx->mmu.rom[addr_ofs] : 0;
+ }
default:
// never reached
return 0;
@@ -8285,13 +8290,24 @@ templates:
break;
case 0x2000:
case 0x3000:
- // set rom bank
ctx->mmu.mbc1.rom_bank = val & 0x1F;
+
+ if (ctx->config && ctx->config->on_set_rom_bank) {
+ // notify callback
+ ctx->config->on_set_rom_bank(ctx, val & 0x1F);
+ }
+
break;
case 0x4000:
case 0x5000:
// set ram_bank/upper_rom_bank bits
- ctx->mmu.mbc1.ram_bank = val & 0x3;
+ ctx->mmu.mbc1.ram_bank = val & 0x03;
+
+ if (ctx->config && ctx->config->on_set_ram_bank) {
+ // notify callback
+ ctx->config->on_set_ram_bank(ctx, val & 0x03);
+ }
+
break;
case 0x6000:
case 0x7000:
@@ -8393,8 +8409,10 @@ templates:
case 0x6000:
case 0x7000:
// ROM1 (16k, banked)
- // FIXME: clamp to rom size?
- return ctx->mmu.rom[mbc2_rom_get_addr(ctx, addr)];
+ {
+ const uint32_t addr_ofs = mbc2_rom_get_addr(ctx, addr);
+ return addr_ofs < ctx->mmu.rom_size ? ctx->mmu.rom[addr_ofs] : 0;
+ }
default:
// never reached
return 0;
@@ -8633,6 +8651,9 @@ templates:
}
}
+ // forward reference for mmu_wp()
+ static void gpu_set_line(gb_t * const ctx, const uint8_t line);
+
static void
mmu_wp(
gb_t * const ctx,
@@ -8700,8 +8721,9 @@ templates:
break;
case PORT_LY:
- // FIXME: according to URL below writing to this register zeroes it:
+ // NOTE: according to URL below writing to this register zeroes it:
// (src: http://gbdev.gg8.se/wiki/articles/Video_Display)
+ gpu_set_line(ctx, 0);
break;
case PORT_LYC:
@@ -8782,7 +8804,7 @@ templates:
const gb_t * const ctx,
const uint16_t addr
) {
- switch (ctx->gpu.mode) {
+ switch (ctx->gpu.mode & 0x3) {
case GPU_MODE_VRAM:
return 0xFF;
default:
@@ -8796,7 +8818,7 @@ templates:
const gb_t * const ctx,
const uint16_t addr
) {
- switch (ctx->gpu.mode) {
+ switch (ctx->gpu.mode & 0x3) {
case GPU_MODE_HBLANK:
case GPU_MODE_VBLANK:
// oam memory (160 bytes):
@@ -8932,7 +8954,7 @@ templates:
const uint16_t addr,
const uint8_t val
) {
- switch (ctx->gpu.mode) {
+ switch (ctx->gpu.mode & 0x3) {
case GPU_MODE_HBLANK:
case GPU_MODE_VBLANK:
case GPU_MODE_OAM:
@@ -8951,7 +8973,7 @@ templates:
const uint16_t addr,
const uint8_t val
) {
- switch (ctx->gpu.mode) {
+ switch (ctx->gpu.mode & 0x3) {
case GPU_MODE_HBLANK:
case GPU_MODE_VBLANK:
// oam memory (160 bytes):
@@ -9171,7 +9193,12 @@ templates:
const gb_cpu_state_t state
) {
ctx->cpu.state = state;
+
UNUSED(pc);
+
+ if (ctx->config && ctx->config->on_set_cpu_state) {
+ ctx->config->on_set_cpu_state(ctx, state);
+ }
}
static void
@@ -9274,13 +9301,12 @@ templates:
}
static void
- add_rb(
+ add(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t n
) {
// get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = cpu_rb(ctx, reg);
+ const uint8_t o = cpu_rb(ctx, RB_A);
const uint16_t v = o + n;
// write value
@@ -9295,44 +9321,26 @@ templates:
}
static void
+ add_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ add(ctx, cpu_rb(ctx, reg));
+ }
+
+ static void
add_d8(
gb_t * const ctx,
const uint16_t addr
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, addr);
- const uint16_t v = o + n;
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- ((v & 0xFF) ? 0 : F_Z) |
- ((((o & 0x0F) + (n & 0x0F)) & 0xF0) ? F_H : 0) |
- ((v & 0x100) ? F_C : 0)
- ));
+ add(ctx, mmu_rb(ctx, addr));
}
static void
add_hl_ptr(
gb_t * const ctx
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rw(ctx, cpu_rw(ctx, RW_HL));
- const uint16_t v = o + n;
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- ((v & 0xFF) ? 0 : F_Z) |
- ((((o & 0x0F) + (n & 0x0F)) & 0xF0) ? F_H : 0) |
- ((v & 0x100) ? F_C : 0)
- ));
+ add(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
@@ -9359,11 +9367,11 @@ templates:
static void
ld_hl_sp_r8(
gb_t * const ctx,
- const uint16_t addr
+ const uint16_t ofs_addr
) {
// get src values
const uint16_t a = cpu_rw(ctx, RW_SP);
- const int8_t b = (int8_t) mmu_rb(ctx, addr);
+ const int8_t b = (int8_t) mmu_rb(ctx, ofs_addr);
const uint16_t v = a + b;
// write dst value
@@ -9377,13 +9385,12 @@ templates:
}
static void
- adc_rb(
+ adc(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t n
) {
- // get old and new value
+ // get old value and carry flag
const uint8_t o = cpu_rb(ctx, RB_A),
- n = cpu_rb(ctx, reg),
c = FLAG(ctx, C) ? 1 : 0;
const uint16_t v = o + n + c;
@@ -9399,24 +9406,18 @@ templates:
}
static void
+ adc_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ adc(ctx, cpu_rb(ctx, reg));
+ }
+
+ static void
adc_hl_ptr(
gb_t * const ctx
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = cpu_rb(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL))),
- c = FLAG(ctx, C) ? 1 : 0;
- const uint16_t v = o + n + c;
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- ((v & 0xFF) ? 0 : F_Z) |
- ((((o & 0x0F) + (n & 0x0F) + c) & 0xF0) ? F_H : 0) |
- ((v & 0x100) ? F_C : 0)
- ));
+ adc(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
@@ -9424,31 +9425,16 @@ templates:
gb_t * const ctx,
const uint16_t addr
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, addr),
- c = FLAG(ctx, C) ? 1 : 0;
- const uint16_t v = o + n + c;
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- ((v & 0xFF) ? 0 : F_Z) |
- ((((o & 0x0F) + (n & 0x0F) + c) & 0xF0) ? F_H : 0) |
- ((v & 0x100) ? F_C : 0)
- ));
+ adc(ctx, mmu_rb(ctx, addr));
}
static void
- sub_rb(
+ sub(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t n
) {
// get old and new value
const uint8_t o = cpu_rb(ctx, RB_A),
- n = cpu_rb(ctx, reg),
v = o - n;
// write value
@@ -9464,24 +9450,18 @@ templates:
}
static void
+ sub_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ sub(ctx, cpu_rb(ctx, reg));
+ }
+
+ static void
sub_hl_ptr(
gb_t * const ctx
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, cpu_rw(ctx, RW_HL)),
- v = o - n;
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- F_N |
- ((((o & 0x0F) - (n & 0x0F)) & 0xF0) ? F_H : 0) |
- ((n > o) ? F_C : 0)
- ));
+ sub(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
@@ -9489,31 +9469,16 @@ templates:
gb_t * const ctx,
const uint16_t addr
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, addr),
- v = o - n;
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- F_N |
- ((((o & 0x0F) - (n & 0x0F)) & 0xF0) ? F_H : 0) |
- ((n > o) ? F_C : 0)
- ));
+ sub(ctx, mmu_rb(ctx, addr));
}
static void
- sbc_rb(
+ sbc(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t n
) {
// get old and new value
const uint8_t o = cpu_rb(ctx, RB_A),
- n = cpu_rb(ctx, reg),
c = FLAG(ctx, C) ? 1 : 0,
v = o - (n + c);
@@ -9530,34 +9495,27 @@ templates:
}
static void
+ sbc_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ sbc(ctx, cpu_rb(ctx, reg));
+ }
+
+ static void
sbc_hl_ptr(
gb_t * const ctx
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, cpu_rw(ctx, RW_HL)),
- c = FLAG(ctx, C) ? 1 : 0,
- v = o - (n + c);
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- F_N |
- ((((o & 0x0F) - (n & 0x0F)) & 0xF0) ? F_H : 0) |
- (((((uint16_t) n) + c) > o) ? F_C : 0) // FIXME: is this right for sub/sbc?
- ));
+ sbc(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
- and_rb(
+ and(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t val
) {
// get value
- const uint8_t v = cpu_rb(ctx, RB_A) & cpu_rb(ctx, reg);
+ const uint8_t v = cpu_rb(ctx, RB_A) & val;
// write value
cpu_wb(ctx, RB_A, v);
@@ -9570,20 +9528,18 @@ templates:
}
static void
+ and_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ and(ctx, cpu_rb(ctx, reg));
+ }
+
+ static void
and_hl_ptr(
gb_t * const ctx
) {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) & mmu_rb(ctx, cpu_rb(ctx, RW_HL));
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- F_H
- ));
+ and(ctx, mmu_rb(ctx, cpu_rb(ctx, RW_HL)));
}
static void
@@ -9591,8 +9547,16 @@ templates:
gb_t * const ctx,
const uint16_t addr
) {
+ and(ctx, mmu_rb(ctx, addr));
+ }
+
+ static void
+ xor(
+ gb_t * const ctx,
+ const uint8_t val
+ ) {
// get value
- const uint8_t v = cpu_rb(ctx, RB_A) & mmu_rb(ctx, addr);
+ const uint8_t v = cpu_rb(ctx, RB_A) ^ val;
// write value
cpu_wb(ctx, RB_A, v);
@@ -9608,32 +9572,14 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) ^ cpu_rb(ctx, reg);
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z)
- ));
+ xor(ctx, cpu_rb(ctx, reg));
}
static void
xor_hl_ptr(
gb_t * const ctx
) {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) ^ mmu_rb(ctx, cpu_rw(ctx, RW_HL));
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z)
- ));
+ xor(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
@@ -9641,8 +9587,15 @@ templates:
gb_t * const ctx,
const uint16_t addr
) {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) ^ mmu_rb(ctx, addr);
+ xor(ctx, mmu_rb(ctx, addr));
+ }
+
+ static void
+ or(
+ gb_t * const ctx,
+ const uint8_t val
+ ) {
+ const uint8_t v = cpu_rb(ctx, RB_A) | val;
// write value
cpu_wb(ctx, RB_A, v);
@@ -9658,30 +9611,14 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- const uint8_t v = cpu_rb(ctx, RB_A) | cpu_rb(ctx, reg);
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z)
- ));
+ or(ctx, cpu_rb(ctx, reg));
}
static void
or_hl_ptr(
gb_t * const ctx
) {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) | mmu_rb(ctx, cpu_rw(ctx, RW_HL));
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z)
- ));
+ or(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
@@ -9689,26 +9626,16 @@ templates:
gb_t * const ctx,
const uint16_t addr
) {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) | mmu_rb(ctx, addr);
-
- // write value
- cpu_wb(ctx, RB_A, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z)
- ));
+ or(ctx, mmu_rb(ctx, addr));
}
static void
- cp_rb(
+ cp(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t n
) {
// get old and new value
const uint8_t o = cpu_rb(ctx, RB_A),
- n = cpu_rb(ctx, reg),
v = o - n;
// set flags
@@ -9721,21 +9648,18 @@ templates:
}
static void
+ cp_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ cp(ctx, cpu_rb(ctx, reg));
+ }
+
+ static void
cp_hl_ptr(
gb_t * const ctx
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, cpu_rw(ctx, RW_HL)),
- v = o - n;
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- F_N |
- ((((o & 0x0F) - (n & 0x0F)) & 0xF0) ? F_H : 0) |
- ((n > o) ? F_C : 0)
- ));
+ cp(ctx, mmu_rb(ctx, cpu_rw(ctx, RW_HL)));
}
static void
@@ -9743,18 +9667,7 @@ templates:
gb_t * const ctx,
const uint16_t addr
) {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, addr),
- v = o - n;
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- F_N |
- ((((o & 0x0F) - (n & 0x0F)) & 0xF0) ? F_H : 0) |
- ((n > o) ? F_C : 0)
- ));
+ cp(ctx, mmu_rb(ctx, addr));
}
static void
@@ -9787,42 +9700,56 @@ templates:
cpu_ww(ctx, RW_SP, sp + 2);
}
- static void
- rlc_rb(
+ static uint8_t
+ rlc(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t o
) {
- // get old value, carry bit, and new value
- const uint8_t o = cpu_rb(ctx, reg),
- c = (o & 0x80) ? 1 : 0,
+ // get carry bit and new value
+ const uint8_t c = (o & 0x80) ? 1 : 0,
n = ((o & 0x7F) << 1) + c;
- // set value
- cpu_wb(ctx, reg, n);
-
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(n ? 0 : F_Z) |
(c ? F_C : 0)
));
+
+ // return new value
+ return n;
+ }
+
+ static void
+ rlc_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ cpu_wb(ctx, reg, rlc(ctx, cpu_rb(ctx, reg)));
}
static void
rlc_hl(
gb_t * const ctx
) {
- // get old value, carry bit, and new value
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- c = (o & 0x80) ? 1 : 0,
- n = ((o & 0x7F) << 1) + c;
- // set value
- mmu_wb(ctx, addr, n);
+ mmu_wb(ctx, addr, rlc(ctx, mmu_rb(ctx, addr)));
+ }
+ static uint8_t
+ rrc(
+ gb_t * const ctx,
+ const uint8_t o
+ ) {
+ // get carry bit and new value
+ const uint8_t c = (o & 0x01) ? 1 : 0,
+ n = (o >> 1) | (c ? 0x80 : 0);
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(n ? 0 : F_Z) |
(c ? F_C : 0)
));
+
+ // return new value
+ return n;
}
static void
@@ -9830,37 +9757,32 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- // get old value, carry bit, and new value
- const uint8_t o = cpu_rb(ctx, reg),
- c = (o & 0x01) ? 1 : 0,
- n = (o >> 1) | (c ? 0x80 : 0);
- // set value
- cpu_wb(ctx, reg, n);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (n ? 0 : F_Z) |
- (c ? F_C : 0)
- ));
+ cpu_wb(ctx, reg, rrc(ctx, cpu_rb(ctx, reg)));
}
static void
rrc_hl_ptr(
gb_t * const ctx
) {
- // get old value, carry bit, and new value
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- c = (o & 0x01) ? 1 : 0,
- n = (o >> 1) | (c ? 0x80 : 0);
- // set value
- mmu_wb(ctx, addr, n);
+ mmu_wb(ctx, addr, rrc(ctx, mmu_rb(ctx, addr)));
+ }
+
+ static uint8_t
+ rl(
+ gb_t * const ctx,
+ const uint8_t o
+ ) {
+ const uint8_t n = (o << 1) + (FLAG(ctx, C) ? 1 : 0);
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(n ? 0 : F_Z) |
- (c ? F_C : 0)
+ ((o & 0x80) ? F_C : 0)
));
+
+ // return result
+ return n;
}
static void
@@ -9868,35 +9790,32 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- // get old value and new value
- const uint8_t o = cpu_rb(ctx, reg),
- n = (o << 1) + (FLAG(ctx, C) ? 1 : 0);
- // set value
- cpu_wb(ctx, reg, n);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (n ? 0 : F_Z) |
- ((o & 0x80) ? F_C : 0)
- ));
+ cpu_wb(ctx, reg, rl(ctx, cpu_rb(ctx, reg)));
}
static void
rl_hl_ptr(
gb_t * const ctx
) {
- // get old value and new value
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- n = (o << 1) + (FLAG(ctx, C) ? 1 : 0);
- // set value
- mmu_wb(ctx, addr, n);
+ mmu_wb(ctx, addr, rl(ctx, mmu_rb(ctx, addr)));
+ }
+
+ static uint8_t
+ rr(
+ gb_t * const ctx,
+ const uint8_t o
+ ) {
+ const uint8_t n = (FLAG(ctx, C) ? 0x80 : 0) | (o >> 1);
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(n ? 0 : F_Z) |
- ((o & 0x80) ? F_C : 0)
+ ((o & 0x01) ? F_C : 0)
));
+
+ // return result
+ return n;
}
static void
@@ -9904,35 +9823,32 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- // get old value and new value
- const uint8_t o = cpu_rb(ctx, reg),
- n = (FLAG(ctx, C) ? 0x80 : 0) | (o >> 1);
- // set value
- cpu_wb(ctx, reg, n);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (n ? 0 : F_Z) |
- ((o & 0x01) ? F_C : 0)
- ));
+ cpu_wb(ctx, reg, rr(ctx, cpu_rb(ctx, reg)));
}
static void
rr_hl_ptr(
gb_t * const ctx
) {
- // get old value and new value
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- n = (FLAG(ctx, C) ? 0x80 : 0) | (o >> 1);
- // set value
- mmu_wb(ctx, addr, n);
+ mmu_wb(ctx, addr, rr(ctx, mmu_rb(ctx, addr)));
+ }
+
+ static uint8_t
+ sla(
+ gb_t * const ctx,
+ const uint8_t o
+ ) {
+ const uint8_t v = o << 1;
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (n ? 0 : F_Z) |
- ((o & 0x01) ? F_C : 0)
+ (v ? 0 : F_Z) |
+ ((o & 0x80) ? F_C : 0)
));
+
+ // return value
+ return v;
}
static void
@@ -9940,17 +9856,7 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- const uint8_t o = cpu_rb(ctx, reg),
- v = o << 1;
-
- // set value
- cpu_wb(ctx, reg, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- ((o & 0x80) ? F_C : 0)
- ));
+ cpu_wb(ctx, reg, sla(ctx, cpu_rb(ctx, reg)));
}
static void
@@ -9958,17 +9864,24 @@ templates:
gb_t * const ctx
) {
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- v = o << 1;
+ mmu_wb(ctx, addr, sla(ctx, mmu_rb(ctx, addr)));
+ }
- // set value
- mmu_wb(ctx, addr, v);
+ static uint8_t
+ sra(
+ gb_t * const ctx,
+ const uint8_t o
+ ) {
+ const uint8_t v = ((o & 0x80) ? 0x80 : 0) | (o >> 1);
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(v ? 0 : F_Z) |
- ((o & 0x80) ? F_C : 0)
+ ((o & 0x01) ? F_C : 0)
));
+
+ // return result
+ return v;
}
static void
@@ -9976,17 +9889,7 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- const uint8_t o = cpu_rb(ctx, reg),
- v = ((o & 0x80) ? 0x80 : 0) | (o >> 1);
-
- // set value
- cpu_wb(ctx, reg, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- ((o & 0x01) ? F_C : 0)
- ));
+ cpu_wb(ctx, reg, sra(ctx, cpu_rb(ctx, reg)));
}
static void
@@ -9994,17 +9897,24 @@ templates:
gb_t * const ctx
) {
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- v = ((o & 0x80) ? 0x80 : 0) | (o >> 1);
+ mmu_wb(ctx, addr, sra(ctx, mmu_rb(ctx, addr)));
+ }
- // set value
- mmu_wb(ctx, addr, v);
+ static uint8_t
+ srl(
+ gb_t * const ctx,
+ const uint8_t o
+ ) {
+ const uint8_t v = (o >> 1);
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(v ? 0 : F_Z) |
((o & 0x01) ? F_C : 0)
));
+
+ // return result
+ return v;
}
static void
@@ -10012,17 +9922,7 @@ templates:
gb_t * const ctx,
const rb_t reg
) {
- const uint8_t o = cpu_rb(ctx, reg),
- v = (o >> 1);
-
- // set value
- cpu_wb(ctx, reg, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- ((o & 0x01) ? F_C : 0)
- ));
+ cpu_wb(ctx, reg, srl(ctx, cpu_rb(ctx, reg)));
}
static void
@@ -10030,17 +9930,7 @@ templates:
gb_t * const ctx
) {
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- v = (o >> 1);
-
- // set value
- mmu_wb(ctx, addr, v);
-
- // set flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
- ((o & 0x01) ? F_C : 0)
- ));
+ mmu_wb(ctx, addr, srl(ctx, mmu_rb(ctx, addr)));
}
static void
@@ -10121,21 +10011,25 @@ templates:
mmu_wb(ctx, addr, mmu_rb(ctx, addr) | ~(bit ? (1 << bit) : 1));
}
- static void
- swap_rb(
+ static uint8_t
+ swap(
gb_t * const ctx,
- const rb_t reg
+ const uint8_t v
) {
- // get old value
- const uint8_t v = cpu_rb(ctx, reg);
-
- // write value
- cpu_wb(ctx, reg, ((v & (0x0F)) << 4) | ((v & 0xF0) >> 4));
-
// write flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
(v ? 0 : F_Z)
));
+
+ return ((v & (0x0F)) << 4) | ((v & 0xF0) >> 4);
+ }
+
+ static void
+ swap_rb(
+ gb_t * const ctx,
+ const rb_t reg
+ ) {
+ cpu_wb(ctx, reg, swap(ctx, cpu_rb(ctx, reg)));
}
static void
@@ -10143,15 +10037,7 @@ templates:
gb_t * const ctx
) {
const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t v = mmu_rb(ctx, addr);
-
- // write value
- mmu_wb(ctx, addr, ((v & (0x0F)) << 4) | ((v & 0xF0) >> 4));
-
- // write flags
- cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z)
- ));
+ mmu_wb(ctx, addr, swap(ctx, mmu_rb(ctx, addr)));
}
static void
@@ -10203,6 +10089,13 @@ templates:
}
}
+ static uint8_t
+ gpu_get_mode(
+ const gb_t * const ctx
+ ) {
+ return ctx->gpu.mode & 0x3;
+ }
+
static void
gpu_set_mode(
gb_t * const ctx,
@@ -10210,18 +10103,29 @@ templates:
) {
ctx->gpu.mode = mode;
- switch (mode) {
+ if (ctx->config && ctx->config->on_gpu_set_mode) {
+ ctx->config->on_gpu_set_mode(ctx, mode);
+ }
+
+ switch (gpu_get_mode(ctx)) {
case GPU_MODE_OAM:
if (ctx->gpu.stat & (1 << 5)) {
- // vblank interrupt is enabled, trigger LCDC interrupt
+ // lcd status interrupt is enabled, trigger LCDC interrupt
mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 1));
}
break;
+ case GPU_MODE_VRAM:
+ // do nothing
+ break;
case GPU_MODE_HBLANK:
if (ctx->gpu.stat & (1 << 3)) {
- // hblank interrupt is enabled, trigger LCDC interrupt
+ // lcd status interrupt is enabled, trigger LCDC interrupt
mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 1));
+
+ if (ctx->config && ctx->config->on_hblank) {
+ ctx->config->on_hblank(ctx);
+ }
}
break;
@@ -10229,12 +10133,13 @@ templates:
if (ctx->gpu.stat & (1 << 4)) {
// vblank interrupt is enabled, trigger vblank interrupt
mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & 1);
+
+ if (ctx->config && ctx->config->on_vblank) {
+ ctx->config->on_vblank(ctx);
+ }
}
break;
- default:
- // do nothing
- break;
}
}
@@ -10332,19 +10237,21 @@ templates:
// increment clock
ctx->gpu.clock += clock;
- switch (ctx->gpu.mode) {
+ if (ctx->config && ctx->config->on_gpu_step) {
+ ctx->config->on_gpu_step(ctx);
+ }
+
+ switch (gpu_get_mode(ctx)) {
case GPU_MODE_OAM:
- if (ctx->gpu.clock > 80) {
+ if (ctx->gpu.clock > 79) {
// clear clock, set mode
ctx->gpu.clock = 0;
- ctx->gpu.mode = GPU_MODE_VRAM;
+ gpu_set_mode(ctx, GPU_MODE_VRAM);
}
break;
case GPU_MODE_VRAM:
- if (ctx->gpu.clock > 172) {
- // TODO: write scanline
-
+ if (ctx->gpu.clock > 171) {
// clear clock, set mode
ctx->gpu.clock = 0;
gpu_set_mode(ctx, GPU_MODE_HBLANK);
@@ -10352,13 +10259,13 @@ templates:
break;
case GPU_MODE_HBLANK:
- if (ctx->gpu.clock > 204) {
+ if (ctx->gpu.clock > 203) {
// clear clock, draw line, increment line
ctx->gpu.clock = 0;
gpu_draw(ctx);
gpu_set_line(ctx, ctx->gpu.line + 1);
- if (ctx->gpu.line < 143) {
+ if (ctx->gpu.line < 144) {
// set mode
gpu_set_mode(ctx, GPU_MODE_OAM);
} else {
@@ -10386,9 +10293,6 @@ templates:
}
break;
- default:
- /* do nothing, unknown gpu mode */
- break;
}
}
@@ -10412,6 +10316,11 @@ templates:
// trigger timer interrupt
mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 2));
+
+ if (ctx->config && ctx->config->on_timer) {
+ // notify callback
+ ctx->config->on_timer(ctx);
+ }
}
}
}
@@ -10450,8 +10359,8 @@ templates:
// return 4 clock step
return 4;
} else {
- // return 4 clock step
- return 0;
+ // return 0 clock step
+ return 1;
}
}
@@ -10461,7 +10370,7 @@ templates:
) {
if (ctx->cpu.state == GB_CPU_STATE_RUN) {
if (ctx->cpu.ime) {
- // get interrupt vector (masked against enabled interrupts)
+ // get interrupt flags, masked against enabled interrupts
const uint8_t iv = mmu_rb(ctx, PORT_IE) & mmu_rb(ctx, PORT_IF);
bool done = false;
@@ -10546,6 +10455,59 @@ templates:
gpu_step(ctx, clock);
}
+ static const struct {
+ const char * const name;
+ const uint8_t len;
+ } OPS[] = {
+ <%= ops %>
+ };
+
+ bool
+ gb_disasm(
+ gb_t * const ctx,
+ char * const dst_buf,
+ size_t * const dst_len
+ ) {
+ if (!dst_buf || !dst_len) {
+ return false;
+ }
+
+ const uint8_t op = mmu_rb(ctx, cpu_rw(ctx, RW_PC));
+ const uint16_t ofs = (op == 0xCB) ? (255 + mmu_rb(ctx, cpu_rw(ctx, RW_PC) + 1)) : op;
+ int len = -1;
+
+ switch (OPS[ofs].len) {
+ case 1:
+ len = snprintf(dst_buf, *dst_len, "%s; %02x",
+ OPS[ofs].name,
+ op
+ );
+
+ break;
+ case 2:
+ len = snprintf(dst_buf, *dst_len, "%s; %02x %02x",
+ OPS[ofs].name,
+ op,
+ mmu_rb(ctx, cpu_rw(ctx, RW_PC) + 1)
+ );
+
+ break;
+ case 3:
+ len = snprintf(dst_buf, *dst_len, "%s; %02x %02x %02x",
+ OPS[ofs].name,
+ op,
+ mmu_rb(ctx, cpu_rw(ctx, RW_PC) + 1),
+ mmu_rb(ctx, cpu_rw(ctx, RW_PC) + 2)
+ );
+
+ break;
+ default:
+ len = snprintf(dst_buf, *dst_len, "%s", OPS[ofs].name);
+ }
+
+ return (len > 0) && (len < (int) *dst_len);
+ }
+
void
gb_set_buttons(
gb_t * const ctx,
@@ -10584,9 +10546,6 @@ templates:
cpu_init(
gb_t * const ctx
) {
- // set cpu state
- cpu_set_state(ctx, 0, GB_CPU_STATE_RUN);
-
// init cpu registers
// (src: TCAGBD.pdf, 3.2)
// TODO: this varies by model (DGB/CGB/SGB/GBA/etc)
@@ -10596,16 +10555,23 @@ templates:
ctx->cpu.rs[RW_HL] = 0x014D;
ctx->cpu.rs[RW_SP] = 0xFFFE;
ctx->cpu.rs[RW_PC] = 0x0100;
+
+ // set cpu state
+ cpu_set_state(ctx, 0, GB_CPU_STATE_RUN);
}
void gb_init(
gb_t * const ctx,
- const uint8_t * const rom,
+ const gb_config_t * const config,
+ const uint8_t *rom,
const uint32_t rom_size
) {
// clear context
memset(ctx, 0, sizeof(gb_t));
+ // save config
+ ctx->config = config;
+
// init cpu
cpu_init(ctx);
@@ -10614,6 +10580,6 @@ templates:
ctx->mmu.rom_size = rom_size;
// init gpu
- ctx->gpu.mode = GPU_MODE_OAM;
- ctx->gpu.line = 0;
+ gpu_set_mode(ctx, GPU_MODE_OAM);
+ gpu_set_line(ctx, 0);
}