From f9008bcfed2537bf2e4d6d33a98a72a115388d93 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Sat, 26 May 2018 09:26:37 -0400 Subject: separate op switches, remove inline op code, strip whitespace --- gen.rb | 17 +- ops.yaml | 681 +++++++++++++++++++++++++++++++++------------------------------ 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,12 +7778,32 @@ 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, @@ -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)); @@ -8058,6 +7846,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, @@ -8080,6 +7909,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, @@ -8102,6 +7952,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, @@ -8147,6 +8018,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, @@ -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 )); } @@ -8182,6 +8092,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, @@ -8197,6 +8123,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, @@ -8216,6 +8175,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, @@ -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); } -- cgit v1.2.3