summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2018-05-26 09:26:37 -0400
committerPaul Duncan <pabs@pablotron.org>2018-05-26 09:26:37 -0400
commitf9008bcfed2537bf2e4d6d33a98a72a115388d93 (patch)
tree9771e10dd915aa44be1c461ee3afdb25d53a29fc
parent9ac78d307fda9bc6ea0ed2684d60dd86ecd89429 (diff)
downloadgb-c-f9008bcfed2537bf2e4d6d33a98a72a115388d93.tar.bz2
gb-c-f9008bcfed2537bf2e4d6d33a98a72a115388d93.zip
separate op switches, remove inline op code, strip whitespace
-rw-r--r--gen.rb17
-rw-r--r--ops.yaml681
2 files changed, 368 insertions, 330 deletions
diff --git a/gen.rb b/gen.rb
index 4b02320..6d579ca 100644
--- a/gen.rb
+++ b/gen.rb
@@ -6,14 +6,15 @@ require 'erb'
# load template data
DATA = YAML.load_file(File.join(__dir__, 'ops.yaml'))
-switches = DATA['ops'].reduce([]) do |r, set|
- prefix = (set.first == 'cb') ? 0xCB00 : 0x0000
-
- set.last.reduce(r) do |r, op|
+switches = Hash.new { |h, k| h[k] = [] }
+DATA['ops'].each do |set_id, ops|
+ switches[set_id] = ops.select { |op|
+ op['op'] != 'PREFIX'
+ }.map { |op|
# op hex string
- hex = (prefix + op['hex']).to_s(16).upcase.rjust(4, '0')
+ hex = op['hex'].to_s(16).upcase.rjust(2, '0')
- r << case op['op']
+ case op['op']
when 'XX'
[
"case 0x%s: /* op: %s, cat: %s */",
@@ -50,8 +51,8 @@ switches = DATA['ops'].reduce([]) do |r, set|
time_expr,
]
end
- end
-end.join("\n")
+ }.join("\n")
+end
t = ERB.new(DATA['templates']['main'])
puts t.run(binding)
diff --git a/ops.yaml b/ops.yaml
index 496e701..ed60519 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -366,13 +366,7 @@ ops:
h:
c:
code: |
- {
- // get offset
- const int8_t ofs = (int8_t) mmu_rb(ctx, old_pc + 1);
-
- // jump
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + ofs);
- }
+ jr(ctx, old_pc + 1);
- id: ADD HL, DE
hex: 0x19
cat: "16-bit math"
@@ -491,17 +485,9 @@ ops:
h:
c:
code: |
- {
- if (!FLAG(ctx, Z)) {
- // get offset
- const int8_t ofs = (int8_t) mmu_rb(ctx, old_pc + 1);
-
- // jump
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + ofs);
-
- // add true time
- ctx->cpu.clock += 4; // FIXME: 4 should not be hard-coded
- }
+ if (!FLAG(ctx, Z)) {
+ jr(ctx, old_pc + 1);
+ ctx->cpu.clock += 4; // FIXME
}
- id: LD HL, d16
hex: 0x21
@@ -618,17 +604,9 @@ ops:
h: "0"
c: C
code: |
- {
- if (FLAG(ctx, Z)) {
- // get offset
- const int8_t ofs = (int8_t) mmu_rb(ctx, old_pc + 1);
-
- // jump
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + ofs);
-
- // add true time
- ctx->cpu.clock += 4; // FIXME: 4 should not be hard-coded
- }
+ if (FLAG(ctx, Z)) {
+ jr(ctx, old_pc + 1);
+ ctx->cpu.clock += 4; // FIXME: 4 should not be hard-coded
}
- id: ADD HL, HL
hex: 0x29
@@ -749,17 +727,9 @@ ops:
h:
c:
code: |
- {
- if (!(cpu_rb(ctx, RB_C) & F_Z)) {
- // get offset
- const int8_t ofs = (int8_t) mmu_rb(ctx, old_pc + 1);
-
- // jump
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + ofs);
-
- // add true time
- ctx->cpu.clock += 4; // FIXME: 4 should not be hard-coded
- }
+ if (!FLAG(ctx, C)) {
+ jr(ctx, old_pc + 1);
+ ctx->cpu.clock += 4; // FIXME
}
- id: LD SP, d16
hex: 0x31
@@ -790,10 +760,8 @@ ops:
h:
c:
code: |
- {
- mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_A));
- cpu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rw(ctx, RW_HL) - 1);
- }
+ mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_A));
+ cpu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rw(ctx, RW_HL) - 1);
- id: INC SP
hex: 0x33
cat: "16-bit math"
@@ -821,21 +789,7 @@ ops:
h: H
c:
code: |
- {
- // write flags
- const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- n = o + 1;
-
- // write value
- mmu_wb(ctx, addr, n);
-
- // write flags
- cpu_wf(ctx, F_Z | F_N | F_H, (
- (n ? 0 : F_Z) |
- (((o & 0x0F) == 0x0F) ? F_H : 0)
- ));
- }
+ inc_hl_ptr(ctx);
- id: DEC (HL)
hex: 0x35
cat: "8-bit math"
@@ -849,22 +803,7 @@ ops:
h: H
c:
code: |
- {
- // write flags
- const uint16_t addr = cpu_rw(ctx, RW_HL);
- const uint8_t o = mmu_rb(ctx, addr),
- n = o - 1;
-
- // write value
- mmu_wb(ctx, addr, n);
-
- // write flags
- cpu_wf(ctx, F_Z | F_N | F_H, (
- (n ? 0 : F_Z) |
- F_N |
- (((o & 0x0F) == 0x00) ? F_H : 0)
- ));
- }
+ dec_hl_ptr(ctx);
- id: LD (HL), d8
hex: 0x36
cat: "8-bit load/store/move"
@@ -911,17 +850,9 @@ ops:
h:
c:
code: |
- {
- if (cpu_rb(ctx, RB_C) & F_Z) {
- // get offset
- const int8_t ofs = (int8_t) mmu_rb(ctx, old_pc + 1);
-
- // jump
- cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + ofs);
-
- // add true time
- ctx->cpu.clock += 4; // FIXME: 4 should not be hard-coded
- }
+ if (FLAG(ctx, C)) {
+ jr(ctx, old_pc + 1);
+ ctx->cpu.clock += 4;
}
- id: ADD HL, SP
hex: 0x39
@@ -1024,9 +955,7 @@ ops:
h: "0"
c: C
code: |
- cpu_wf(ctx, F_N | F_H | F_C, (
- (FLAG(ctx, C) ? 0 : F_C)
- ));
+ cpu_wf(ctx, F_N | F_H | F_C, FLAG(ctx, C) ? 0 : F_C);
- id: LD B, B
hex: 0x40
cat: "8-bit load/store/move"
@@ -2090,22 +2019,7 @@ ops:
h: H
c: C
code: |
- {
- // 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_hl_ptr(ctx);
- id: ADD A, A
hex: 0x87
cat: "8-bit math"
@@ -2225,23 +2139,7 @@ ops:
h: H
c: C
code: |
- {
- // 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_hl_ptr(ctx);
- id: ADC A, A
hex: 0x8F
cat: "8-bit math"
@@ -2361,23 +2259,7 @@ ops:
h: H
c: C
code: |
- {
- // 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_hl_ptr(ctx);
- id: SUB A
hex: 0x97
cat: "8-bit math"
@@ -2495,24 +2377,7 @@ ops:
h: H
c: C
code: |
- {
- // 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) |
- ((n > o) ? F_C : 0) // FIXME: is this right for sub/sbc?
- ));
- }
+ sbc_hl_ptr(ctx);
- id: SBC A, A
hex: 0x9F
cat: "8-bit math"
@@ -2625,19 +2490,7 @@ ops:
h: "1"
c: "0"
code: |
- {
- // 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_hl_ptr(ctx);
- id: AND A
hex: 0xA7
cat: "8-bit math"
@@ -2749,18 +2602,7 @@ ops:
h: "0"
c: "0"
code: |
- {
- // 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_hl_ptr(ctx);
- id: XOR A
hex: 0xAF
cat: "8-bit math"
@@ -2872,18 +2714,7 @@ ops:
h: "0"
c: "0"
code: |
- {
- // 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_hl_ptr(ctx);
- id: OR A
hex: 0xB7
cat: "8-bit math"
@@ -3002,20 +2833,7 @@ ops:
h: H
c: C
code: |
- {
- // 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_hl_ptr(ctx);
- id: CP A
hex: 0xBF
cat: "8-bit math"
@@ -3050,7 +2868,6 @@ ops:
code: |
if (!FLAG(ctx, Z)) {
pop_rw(ctx, RW_PC);
-
ctx->cpu.clock += 12;
}
- id: POP BC
@@ -3086,9 +2903,7 @@ ops:
c:
code: |
if (!FLAG(ctx, Z)) {
- // jump
cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
ctx->cpu.clock -= 16; // FIXME
}
- id: JP a16
@@ -3125,12 +2940,7 @@ ops:
c:
code: |
if (!FLAG(ctx, Z)) {
- // push pc
- push_rw(ctx, RW_PC);
-
- // jump
- cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
+ call_a16(ctx, old_pc + 1);
ctx->cpu.clock += 12; // FIXME
}
- id: PUSH BC
@@ -3162,23 +2972,7 @@ ops:
h: H
c: C
code: |
- {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, old_pc + 1);
- 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_d8(ctx, old_pc + 1);
- id: RST 00H
hex: 0xC7
cat: "jumps/calls"
@@ -3192,6 +2986,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x00);
- id: RET Z
hex: 0xC8
cat: "jumps/calls"
@@ -3210,10 +3006,7 @@ ops:
c:
code: |
if (FLAG(ctx, Z)) {
- // pop pc
pop_rw(ctx, RW_PC);
-
- // update clock
ctx->cpu.clock += 12;
}
- id: RET
@@ -3250,9 +3043,7 @@ ops:
c:
code: |
if (FLAG(ctx, Z)) {
- // jump
cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
ctx->cpu.clock -= 16; // FIXME
}
- id: PREFIX CB
@@ -3282,12 +3073,7 @@ ops:
c:
code: |
if (FLAG(ctx, Z)) {
- // push pc
- push_rw(ctx, RW_PC);
-
- // jump
- cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
+ call_a16(ctx, old_pc + 1);
ctx->cpu.clock += 12;
}
- id: CALL a16
@@ -3302,11 +3088,7 @@ ops:
h:
c:
code: |
- // push pc
- push_rw(ctx, RW_PC);
-
- // jump
- cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
+ call_a16(ctx, old_pc + 1);
- id: ADC A, d8
hex: 0xCE
cat: "8-bit math"
@@ -3332,6 +3114,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x08);
- id: RET NC
hex: 0xD0
cat: "jumps/calls"
@@ -3345,10 +3129,7 @@ ops:
f: 8
code: |
if (!FLAG(ctx, C)) {
- // pop pc
pop_rw(ctx, RW_PC);
-
- // update clock
ctx->cpu.clock += 12;
}
flags:
@@ -3390,15 +3171,15 @@ ops:
c:
code: |
if (!FLAG(ctx, C)) {
- // jump
cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
ctx->cpu.clock -= 16; // FIXME
}
- id: XX
hex: 0xD3
cat: "invalid"
op: XX
+ code: |
+ invalid(ctx, old_pc);
- id: CALL NC, a16
hex: 0xD4
cat: "jumps/calls"
@@ -3416,7 +3197,10 @@ ops:
h:
c:
code: |
- invalid(ctx, old_pc);
+ if (!FLAG(ctx, C)) {
+ call_a16(ctx, old_pc + 1);
+ ctx->cpu.clock += 12; // FIXME
+ }
- id: PUSH DE
hex: 0xD5
cat: "16-bit load/store/move"
@@ -3460,6 +3244,8 @@ ops:
n: "1"
h: H
c: C
+ code: |
+ rst(ctx, 0x10);
- id: RET C
hex: 0xD8
cat: "jumps/calls"
@@ -3477,10 +3263,7 @@ ops:
c:
code: |
if (FLAG(ctx, C)) {
- // pop pc
pop_rw(ctx, RW_PC);
-
- // update clock
ctx->cpu.clock += 12;
}
- id: RETI
@@ -3497,11 +3280,9 @@ ops:
h:
c:
code: |
- // enable interrupts
- ctx->cpu.ei = true;
-
- // pop pc
+ // pop pc, enable interrupts
pop_rw(ctx, RW_PC);
+ ctx->cpu.ei = true;
- id: JP C, a16
hex: 0xDA
cat: "jumps/calls"
@@ -3520,10 +3301,7 @@ ops:
c:
code: |
if (FLAG(ctx, C)) {
- // jump
cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
- // update clock
ctx->cpu.clock -= 16;
}
- id: XX
@@ -3550,13 +3328,7 @@ ops:
c:
code: |
if (FLAG(ctx, C)) {
- // push pc
- push_rw(ctx, RW_PC);
-
- // jump
- cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1));
-
- // update clock
+ call_a16(ctx, old_pc + 1);
ctx->cpu.clock += 12;
}
- id: XX
@@ -3591,6 +3363,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x16);
- id: LDH (a8), A
hex: 0xE0
cat: "8-bit load/store/move"
@@ -3686,6 +3460,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x20);
- id: ADD SP, r8
hex: 0xE8
cat: "misc"
@@ -3769,6 +3545,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x28);
- id: LDH A, (a8)
hex: 0xF0
cat: "8-bit load/store/move"
@@ -3862,18 +3640,7 @@ ops:
h: "0"
c: "0"
code: |
- {
- // get value
- const uint8_t v = cpu_rb(ctx, RB_A) ^ mmu_rb(ctx, old_pc + 1);
-
- // 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_d8(ctx, old_pc + 1);
- id: RST 30H
hex: 0xF7
cat: "jumps/calls"
@@ -3886,6 +3653,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x30);
- id: LD HL, SP+r8
hex: 0xF8
cat: "16-bit load/store/move"
@@ -3967,20 +3736,7 @@ ops:
h: H
c: C
code: |
- {
- // get old and new value
- const uint8_t o = cpu_rb(ctx, RB_A),
- n = mmu_rb(ctx, old_pc + 1),
- 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_d8(ctx, old_pc + 1);
- id: RST 38H
hex: 0xFF
cat: "jumps/calls"
@@ -3994,6 +3750,8 @@ ops:
n:
h:
c:
+ code: |
+ rst(ctx, 0x38);
cb:
- id: RLC B
@@ -7941,9 +7699,9 @@ templates:
) {
const uint8_t of = cpu_rb(ctx, RB_F);
cpu_wb(ctx, RB_F, (
- (((mask & F_Z) ? flags : of) & F_Z) |
- (((mask & F_N) ? flags : of) & F_N) |
- (((mask & F_H) ? flags : of) & F_H) |
+ (((mask & F_Z) ? flags : of) & F_Z) |
+ (((mask & F_N) ? flags : of) & F_N) |
+ (((mask & F_H) ? flags : of) & F_H) |
(((mask & F_C) ? flags : of) & F_C)
));
}
@@ -7959,8 +7717,8 @@ templates:
static void
not_implemented(
- gb_t * const ctx,
- const uint16_t pc,
+ gb_t * const ctx,
+ const uint16_t pc,
const uint16_t op
) {
UNUSED(op);
@@ -7968,15 +7726,6 @@ templates:
cpu_ww(ctx, RW_PC, pc); // FIXME?
}
- static uint16_t
- gb_next_op(
- const gb_t * const ctx
- ) {
- const uint16_t addr = cpu_rw(ctx, RW_PC);
- const uint8_t op = mmu_rb(ctx, addr);
- return (op == 0xCB) ? 0xCB00 | mmu_rb(ctx, addr + 1) : op;
- }
-
static void
inc_rb(
gb_t * const ctx,
@@ -7991,7 +7740,26 @@ templates:
// set flags
cpu_wf(ctx, F_Z | F_N | F_H, (
- (n ? F_Z : 0) |
+ (n ? F_Z : 0) |
+ (((o & 0x0F) == 0x0F) ? F_H : 0)
+ ));
+ }
+
+ static void
+ inc_hl_ptr(
+ gb_t * const ctx
+ ) {
+ // write flags
+ const uint16_t addr = cpu_rw(ctx, RW_HL);
+ const uint8_t o = mmu_rb(ctx, addr),
+ n = o + 1;
+
+ // write value
+ mmu_wb(ctx, addr, n);
+
+ // write flags
+ cpu_wf(ctx, F_Z | F_N | F_H, (
+ (n ? 0 : F_Z) |
(((o & 0x0F) == 0x0F) ? F_H : 0)
));
}
@@ -8010,13 +7778,33 @@ templates:
// set flags
cpu_wf(ctx, F_Z | F_N | F_H, (
- (n ? F_Z : 0) |
- F_N |
+ (n ? F_Z : 0) |
+ F_N |
(((o ^ n) & 0x10) ? F_H : 0)
));
}
static void
+ dec_hl_ptr(
+ gb_t * const ctx
+ ) {
+ // write flags
+ const uint16_t addr = cpu_rw(ctx, RW_HL);
+ const uint8_t o = mmu_rb(ctx, addr),
+ n = o - 1;
+
+ // write value
+ mmu_wb(ctx, addr, n);
+
+ // write flags
+ cpu_wf(ctx, F_Z | F_N | F_H, (
+ (n ? 0 : F_Z) |
+ F_N |
+ (((o & 0x0F) == 0x00) ? F_H : 0)
+ ));
+ }
+
+ static void
add_rw_rw(
gb_t * const ctx,
const rw_t dst_reg,
@@ -8026,7 +7814,7 @@ templates:
const uint16_t dst_val = cpu_rw(ctx, dst_reg),
src_val = cpu_rw(ctx, src_reg);
const uint32_t n = ((uint32_t) dst_val) + ((uint32_t) src_val);
-
+
// set new value
cpu_ww(ctx, dst_reg, (uint16_t) (n & 0xFFFF));
@@ -8059,6 +7847,47 @@ templates:
}
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)
+ ));
+ }
+
+ 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)
+ ));
+ }
+
+ static void
adc_rb(
gb_t * const ctx,
const rb_t reg
@@ -8081,6 +7910,27 @@ templates:
}
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)
+ ));
+ }
+
+ static void
sub_rb(
gb_t * const ctx,
const rb_t reg
@@ -8103,6 +7953,27 @@ templates:
}
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)
+ ));
+ }
+
+ static void
sub_d8(
gb_t * const ctx,
const uint16_t addr
@@ -8148,6 +8019,28 @@ templates:
}
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) |
+ ((n > o) ? F_C : 0) // FIXME: is this right for sub/sbc?
+ ));
+ }
+
+ static void
and_rb(
gb_t * const ctx,
const rb_t reg
@@ -8160,7 +8053,24 @@ templates:
// set flags
cpu_wf(ctx, F_Z | F_N | F_H | F_C, (
- (v ? 0 : F_Z) |
+ (v ? 0 : F_Z) |
+ F_H
+ ));
+ }
+
+ 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
));
}
@@ -8183,6 +8093,22 @@ templates:
}
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)
+ ));
+ }
+
+ static void
or_rb(
gb_t * const ctx,
const rb_t reg
@@ -8198,6 +8124,39 @@ templates:
}
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)
+ ));
+ }
+
+ static void
+ or_d8(
+ 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)
+ ));
+ }
+
+ static void
cp_rb(
gb_t * const ctx,
const rb_t reg
@@ -8217,6 +8176,43 @@ templates:
}
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)
+ ));
+ }
+
+ static void
+ cp_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),
+ 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)
+ ));
+ }
+
+ static void
push_rw(
gb_t * const ctx,
const rw_t reg
@@ -8405,7 +8401,7 @@ templates:
// set flags
cpu_wf(ctx, F_Z | F_N | F_H, (
(v ? 0 : F_Z) |
- 0 |
+ 0 |
F_H
));
}
@@ -8422,7 +8418,7 @@ templates:
// set flags
cpu_wf(ctx, F_Z | F_N | F_H, (
(v ? 0 : F_Z) |
- 0 |
+ 0 |
F_H
));
}
@@ -8485,17 +8481,58 @@ templates:
));
}
+ static void
+ jr(
+ gb_t * const ctx,
+ const uint16_t ofs_addr
+ ) {
+ // get offset
+ const int8_t ofs = (int8_t) mmu_rb(ctx, ofs_addr);
+
+ // jump
+ cpu_ww(ctx, RW_PC, cpu_rw(ctx, RW_PC) + ofs);
+ }
+
+ static void
+ rst(
+ gb_t * const ctx,
+ const uint8_t val
+ ) {
+ UNUSED(ctx);
+ UNUSED(val);
+ }
+
+ static void
+ call_a16(
+ gb_t * const ctx,
+ const uint16_t addr
+ ) {
+ // push pc
+ push_rw(ctx, RW_PC);
+
+ // jump
+ cpu_ww(ctx, RW_PC, mmu_rw(ctx, addr));
+ }
+
void
gb_step(
gb_t * const ctx
) {
const uint16_t old_pc = cpu_rw(ctx, RW_PC),
- op = gb_next_op(ctx);
+ op = mmu_rb(ctx, old_pc);
// TODO: handle interrupts
switch (op) {
- <%= switches %>
+ <%= switches['main'] %>
+ case 0xCB:
+ switch (mmu_rb(ctx, old_pc + 1)) {
+ <%= switches['cb'] %>
+ default:
+ not_implemented(ctx, old_pc, op);
+ }
+
+ break;
default:
not_implemented(ctx, old_pc, op);
}