From cc9b49d62faff2ffb11d6e32c96b53a1d2b221c1 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Fri, 25 May 2018 22:20:52 -0400 Subject: initial commit --- .gitignore | 2 + gen.rb | 57 + ops.yaml | 8962 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 9021 insertions(+) create mode 100644 .gitignore create mode 100644 gen.rb create mode 100644 ops.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf4fe8f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +gb.c +gb.o diff --git a/gen.rb b/gen.rb new file mode 100644 index 0000000..4b02320 --- /dev/null +++ b/gen.rb @@ -0,0 +1,57 @@ +#!/usr/bin/env ruby + +require 'yaml' +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| + # op hex string + hex = (prefix + op['hex']).to_s(16).upcase.rjust(4, '0') + + r << case op['op'] + when 'XX' + [ + "case 0x%s: /* op: %s, cat: %s */", + " invalid(ctx, old_pc);", + " break;", + ].join("\n") % [ + hex, + op['id'], + op['cat'], + ] + else + # time expr + time_expr = case op['time'] + when Numeric + 'ctx->cpu.clock += %d;' % [op['time']] + when Hash + 'ctx->cpu.clock += %d; // t: %d, f: %d' % %w{f t f}.map { |k| + op['time'][k] + } + else + raise "unknown op time: #{hex}: #{op['time']}" + end + + [ + "case 0x%s: /* op: \"%s\", cat: \"%s\" */", + " %s", # action_expr + " %s", # time_expr + " break;" + ].join("\n") % [ + hex, + op['id'], + op['cat'], + op['code'] || 'not_implemented(ctx, old_pc, op);', + time_expr, + ] + end + end +end.join("\n") + +t = ERB.new(DATA['templates']['main']) +puts t.run(binding) diff --git a/ops.yaml b/ops.yaml new file mode 100644 index 0000000..79ddc77 --- /dev/null +++ b/ops.yaml @@ -0,0 +1,8962 @@ +--- +# src: http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html +# src: http://www.devrs.com/gb/files/opcodes.html +ops: + main: + - id: NOP + hex: 0x00 + cat: misc + op: NOP + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + /* do nothing */ + - id: LD BC, d16 + hex: 0x01 + cat: "16-bit load/store/move" + op: LD + dst: BC + src: d16 + len: 3 + time: 12 + flags: + z: + n: + h: + c: + code: | + cpu_rw(ctx, mmu_rw(ctx, old_pc + 1)); + - id: LD (BC), A + hex: 0x02 + cat: "8-bit load/store/move" + op: LD + dst: (BC) + src: A + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_BC), cpu_rb(ctx, RB_A)); + - id: INC BC + hex: 0x03 + cat: "16-bit math" + op: INC + dst: BC + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_BC, cpu_rw(ctx, RW_BC) + 1); + - id: INC B + hex: 0x04 + cat: "8-bit math" + op: INC + dst: B + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: + code: | + inc_rb(ctx, RB_B); + - id: DEC B + hex: 0x05 + cat: "8-bit math" + op: DEC + dst: B + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_B); + - id: LD B, d8 + hex: 0x06 + cat: "8-bit load/store/move" + op: LD + dst: B + src: d8 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, mmu_rb(ctx, old_pc + 1)); + - id: RLCA + hex: 0x07 + cat: "8-bit rotations/shifts" + op: RLC + dst: A + len: 1 + time: 4 + flags: + z: "0" + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_A); + - id: LD (a16), SP + hex: 0x08 + cat: "16-bit load/store/move" + op: LD + dst: (a16) + src: SP + len: 3 + time: 20 + flags: + z: + n: + h: + c: + code: | + mmu_ww(ctx, mmu_rw(ctx, old_pc + 1), cpu_rw(ctx, RW_SP)); + - id: ADD HL, BC + hex: 0x09 + cat: "16-bit math" + op: ADD + dst: HL + src: BC + len: 1 + time: 8 + flags: + z: + n: "0" + h: H + c: C + code: | + add_rw_rw(ctx, RW_HL, RW_BC); + - id: LD A, (BC) + hex: 0x0A + cat: "8-bit load/store/move" + op: LD + dst: A + src: (BC) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, cpu_rw(ctx, RW_BC))); + - id: DEC BC + hex: 0x0B + cat: "16-bit math" + op: DEC + dst: BC + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_BC, cpu_rw(ctx, RW_BC) - 1); + - id: INC C + hex: 0x0C + cat: "8-bit math" + op: INC + dst: C + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: + code: + inc_rb(ctx, RB_C); + - id: DEC C + hex: 0x0D + cat: "8-bit math" + op: DEC + dst: C + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_C); + - id: LD C, d8 + hex: 0x0E + cat: "8-bit load/store/move" + op: LD + dst: C + src: d8 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, mmu_rb(ctx, old_pc + 1)); + - id: RRCA + hex: 0x0F + cat: "8-bit rotations/shifts" + op: RRC + dst: A + len: 1 + time: 4 + flags: + z: "0" + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_A); + - id: STOP + hex: 0x10 + cat: misc + op: STOP + len: 2 + time: 4 + flags: + z: + n: + h: + c: + code: | + ctx->cpu.state = STATE_STOP; + cpu_ww(ctx, RW_PC, old_pc); // FIXME? + - id: LD DE, d16 + hex: 0x11 + cat: "16-bit load/store/move" + op: LD + dst: DE + src: d16 + len: 3 + time: 12 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_DE, mmu_rw(ctx, old_pc + 1)); + - id: LD (DE), A + hex: 0x12 + cat: "8-bit load/store/move" + op: LD + dst: (DE) + src: A + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_DE), cpu_rb(ctx, RB_A)); + - id: INC DE + hex: 0x13 + cat: "16-bit math" + op: INC + dst: DE + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_DE, cpu_rw(ctx, RW_DE) + 1); + - id: INC D + hex: 0x14 + cat: "8-bit math" + op: INC + dst: D + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: + code: | + inc_rb(ctx, RB_D); + - id: DEC D + hex: 0x15 + cat: "8-bit math" + op: DEC + dst: D + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_D); + - id: LD D, d8 + hex: 0x16 + cat: "8-bit load/store/move" + op: LD + dst: D + src: d8 + len: 2 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, mmu_rb(ctx, old_pc + 1)); + - id: RLA + hex: 0x17 + cat: "8-bit rotations/shifts" + op: RL + dst: A + len: 1 + time: 4 + flags: + z: "0" + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_A); + - id: JR r8 + hex: 0x18 + cat: "jumps/calls" + op: JR + dst: PC + src: r8 + len: 2 + time: 12 + flags: + z: + n: + 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); + } + - id: ADD HL, DE + hex: 0x19 + cat: "16-bit math" + op: ADD + dst: HL + src: DE + len: 1 + time: 8 + flags: + z: + n: "0" + h: H + c: C + code: | + add_rw_rw(ctx, RW_HL, RW_DE); + - id: LD A, (DE) + hex: 0x1A + cat: "8-bit load/store/move" + op: LD + dst: A + src: (DE) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, cpu_rw(ctx, RW_DE))); + - id: DEC DE + hex: 0x1B + cat: "16-bit math" + op: DEC + dst: DE + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_BC, cpu_rw(ctx, RW_BC) - 1); + - id: INC E + hex: 0x1C + cat: "8-bit math" + op: INC + dst: E + len: 1 + time: 4 + flags: + z: "Z" + n: "0" + h: H + c: + code: | + inc_rb(ctx, RB_E); + - id: DEC E + hex: 0x1D + cat: "8-bit math" + op: DEC + dst: E + len: 1 + time: 4 + flags: + z: "Z" + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_E); + - id: LD E, d8 + hex: 0x1E + cat: "8-bit load/store/move" + op: LD + dst: E + src: d8 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, mmu_rb(ctx, old_pc + 1)); + - id: RRA + hex: 0x1F + cat: "8-bit rotations/shifts" + op: RR + dst: A + len: 1 + time: 4 + flags: + z: "0" + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_A); + - id: JR NZ, r8 + hex: 0x20 + cat: "jumps/calls" + op: JR + test: NZ + dst: PC + src: F + len: 2 + time: + t: 12 + f: 8 + flags: + z: + n: + h: + c: + code: | + { + if (!(cpu_rb(ctx, RB_F) & 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 + } + } + - id: LD HL, d16 + hex: 0x21 + cat: "16-bit load/store/move" + op: LD + dst: HL + src: d16 + len: 3 + time: 12 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_HL, mmu_rw(ctx, old_pc + 1)); + - id: LD (HL+), A + hex: 0x22 + cat: "8-bit load/store/move" + op: LD + dst: (HL+) + src: A + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_ww(ctx, RW_HL, mmu_rw(ctx, cpu_rw(ctx, RW_HL)) + cpu_rb(ctx, RB_A)); + - id: INC HL + hex: 0x23 + cat: "16-bit math" + op: INC + dst: HL + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_HL, cpu_rw(ctx, RW_HL) + 1); + - id: INC H + hex: 0x24 + cat: "8-bit math" + op: INC + dst: H + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: + code: | + inc_rb(ctx, RB_H); + - id: DEC H + hex: 0x25 + cat: "8-bit math" + op: DEC + dst: H + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_H); + - id: LD H, d8 + hex: 0x26 + cat: "8-bit load/store/move" + op: LD + dst: H + src: d8 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, mmu_rb(ctx, old_pc + 1)); + - id: DAA + hex: 0x27 + cat: "8-bit math" + op: DAA + dst: A + len: 1 + time: 4 + flags: + z: Z + n: + h: "0" + c: C + - id: JR Z, r8 + hex: 0x28 + cat: "jumps/calls" + op: JR + test: Z + dst: PC + len: 2 + time: + t: 12 + f: 8 + flags: + z: + n: + h: "0" + c: C + code: | + { + if (cpu_rb(ctx, RB_F) & 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 + } + } + - id: ADD HL, HL + hex: 0x29 + cat: "16-bit math" + op: ADD + dst: HL + src: HL + len: 1 + time: 8 + flags: + z: + n: "0" + h: H + c: C + code: | + add_rw_rw(ctx, RW_HL, RW_HL); + - id: LD A, (HL+) + hex: 0x2A + cat: "8-bit load/store/move" + op: LD + dst: A + src: (HL+) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + { + const uint16_t addr = cpu_rw(ctx, RW_HL); + cpu_ww(ctx, RW_HL, addr + 1); + cpu_wb(ctx, RB_A, mmu_rb(ctx, addr)); + } + - id: DEC HL + hex: 0x2B + cat: "16-bit math" + op: DEC + dst: HL + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_HL, cpu_rw(ctx, RW_HL) - 1); + - id: INC L + hex: 0x2C + cat: "8-bit math" + op: INC + dst: L + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: + code: | + inc_rb(ctx, RB_L); + - id: DEC L + hex: 0x2D + cat: "8-bit math" + op: DEC + dst: L + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_L); + - id: LD L, d8 + hex: 0x2E + cat: "8-bit load/store/move" + op: LD + dst: L + src: d8 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, mmu_rb(ctx, old_pc + 1)); + - id: CPL + hex: 0x2F + cat: "8-bit math" + op: CPL + src: d8 + len: 1 + time: 4 + flags: + z: + n: "1" + h: "1" + c: + - id: JR NC, r8 + hex: 0x30 + cat: "jumps/calls" + op: JR + test: NC + dst: PC + len: 2 + time: + t: 12 + f: 8 + flags: + z: + n: + 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 + } + } + - id: LD SP, d16 + hex: 0x31 + cat: "16-bit load/store/move" + op: LD + dst: SP + src: d16 + len: 3 + time: 12 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_SP, mmu_rw(ctx, old_pc + 1)); + - id: LD (HL-), A + hex: 0x32 + cat: "8-bit load/store/move" + op: LD + dst: (HL-) + src: A + len: 1 + time: 8 + flags: + z: + n: + 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); + } + - id: INC SP + hex: 0x33 + cat: "16-bit math" + op: INC + dst: SP + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_SP, cpu_rw(ctx, RW_SP) + 1); + - id: INC (HL) + hex: 0x34 + cat: "8-bit math" + op: INC + dst: (HL) + len: 1 + time: 12 + flags: + z: Z + n: "0" + 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) + )); + } + - id: DEC (HL) + hex: 0x35 + cat: "8-bit math" + op: DEC + dst: (HL) + len: 1 + time: 12 + flags: + z: Z + n: "1" + 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) + )); + } + - id: LD (HL), d8 + hex: 0x36 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: d8 + len: 2 + time: 12 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), old_pc + 1); + - id: SCF + hex: 0x37 + cat: "8-bit math" + op: SCF + dst: F + src: d8 + len: 1 + time: 4 + flags: + z: + n: "0" + h: "0" + c: "1" + code: | + cpu_wf(ctx, F_N | F_H | F_C, F_C); + - id: JR C, r8 + hex: 0x38 + cat: "jumps/calls" + op: JR + test: C + dst: PC + len: 2 + time: + t: 12 + f: 8 + flags: + z: + n: + 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 + } + } + - id: ADD HL, SP + hex: 0x39 + cat: "16-bit math" + op: ADD + dst: HL + src: SP + len: 1 + time: 8 + flags: + z: + n: "0" + h: H + c: C + code: | + add_rw_rw(ctx, RW_HL, RW_SP); + - id: LD A, (HL-) + hex: 0x3A + cat: "8-bit load/store/move" + op: LD + dst: A + src: (HL-) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + cpu_ww(ctx, RW_HL, cpu_rw(ctx, RW_HL) - 1); + - id: DEC SP + hex: 0x3B + cat: "16-bit math" + op: DEC + dst: SP + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_HL, cpu_rw(ctx, RW_HL) - 1); + - id: INC A + hex: 0x3C + cat: "8-bit math" + op: INC + dst: A + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: + code: | + inc_rb(ctx, RB_A); + - id: DEC A + hex: 0x3D + cat: "8-bit math" + op: DEC + dst: A + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: + code: | + dec_rb(ctx, RB_A); + - id: LD A, d8 + hex: 0x3E + cat: "8-bit load/store/move" + op: LD + dst: A + src: d8 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, old_pc + 1)); + - id: CCF + hex: 0x3F + cat: "8-bit math" + op: CCF + dst: F + len: 1 + time: 4 + flags: + z: + n: "0" + h: "0" + c: C + code: | + cpu_wf(ctx, F_N | F_H | F_C, ( + (cpu_rb(ctx, RB_F) & F_C ? 0 : F_C) + )); + - id: LD B, B + hex: 0x40 + cat: "8-bit load/store/move" + op: LD + dst: B + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: LD B, C + hex: 0x41 + cat: "8-bit load/store/move" + op: LD + dst: B + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, cpu_rb(ctx, RB_C)); + - id: LD B, D + hex: 0x42 + cat: "8-bit load/store/move" + op: LD + dst: B + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, cpu_rb(ctx, RB_D)); + - id: LD B, E + hex: 0x43 + cat: "8-bit load/store/move" + op: LD + dst: B + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, cpu_rb(ctx, RB_E)); + - id: LD B, H + hex: 0x44 + cat: "8-bit load/store/move" + op: LD + dst: B + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, cpu_rb(ctx, RB_H)); + - id: LD B, L + hex: 0x45 + cat: "8-bit load/store/move" + op: LD + dst: B + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, cpu_rb(ctx, RB_L)); + - id: LD B, (HL) + hex: 0x46 + cat: "8-bit load/store/move" + op: LD + dst: B + src: (HL) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD B, A + hex: 0x47 + cat: "8-bit load/store/move" + op: LD + dst: B + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_B, cpu_rb(ctx, RB_A)); + - id: LD C, B + hex: 0x48 + cat: "8-bit load/store/move" + op: LD + dst: C + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, cpu_rb(ctx, RB_B)); + - id: LD C, C + hex: 0x49 + cat: "8-bit load/store/move" + op: LD + dst: C + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: LD C, D + hex: 0x4A + cat: "8-bit load/store/move" + op: LD + dst: C + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, cpu_rb(ctx, RB_D)); + - id: LD C, E + hex: 0x4B + cat: "8-bit load/store/move" + op: LD + dst: C + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, cpu_rb(ctx, RB_E)); + - id: LD C, H + hex: 0x4C + cat: "8-bit load/store/move" + op: LD + dst: C + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, cpu_rb(ctx, RB_H)); + - id: LD C, L + hex: 0x4D + cat: "8-bit load/store/move" + op: LD + dst: C + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, cpu_rb(ctx, RB_L)); + - id: LD C, (HL) + hex: 0x4E + cat: "8-bit load/store/move" + op: LD + dst: C + src: (HL) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD C, A + hex: 0x4F + cat: "8-bit load/store/move" + op: LD + dst: C + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_C, cpu_rb(ctx, RB_A)); + - id: LD D, B + hex: 0x50 + cat: "8-bit load/store/move" + op: LD + dst: D + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, cpu_rb(ctx, RB_B)); + - id: LD D, C + hex: 0x51 + cat: "8-bit load/store/move" + op: LD + dst: D + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, cpu_rb(ctx, RB_C)); + - id: LD D, D + hex: 0x52 + cat: "8-bit load/store/move" + op: LD + dst: D + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: LD D, E + hex: 0x53 + cat: "8-bit load/store/move" + op: LD + dst: D + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, cpu_rb(ctx, RB_E)); + - id: LD D, H + hex: 0x54 + cat: "8-bit load/store/move" + op: LD + dst: D + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, cpu_rb(ctx, RB_H)); + - id: LD D, L + hex: 0x55 + cat: "8-bit load/store/move" + op: LD + dst: D + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, cpu_rb(ctx, RB_L)); + - id: LD D, (HL) + hex: 0x56 + cat: "8-bit load/store/move" + op: LD + dst: D + src: (HL) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD D, A + hex: 0x57 + cat: "8-bit load/store/move" + op: LD + dst: D + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_D, cpu_rb(ctx, RB_A)); + - id: LD E, B + hex: 0x58 + cat: "8-bit load/store/move" + op: LD + dst: E + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, cpu_rb(ctx, RB_B)); + - id: LD E, C + hex: 0x59 + cat: "8-bit load/store/move" + op: LD + dst: E + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, cpu_rb(ctx, RB_C)); + - id: LD E, D + hex: 0x5A + cat: "8-bit load/store/move" + op: LD + dst: E + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, cpu_rb(ctx, RB_D)); + - id: LD E, E + hex: 0x5B + cat: "8-bit load/store/move" + op: LD + dst: E + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: LD E, H + hex: 0x5C + cat: "8-bit load/store/move" + op: LD + dst: E + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, cpu_rb(ctx, RB_H)); + - id: LD E, L + hex: 0x5D + cat: "8-bit load/store/move" + op: LD + dst: E + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, cpu_rb(ctx, RB_L)); + - id: LD E, (HL) + hex: 0x5E + cat: "8-bit load/store/move" + op: LD + dst: E + src: (HL) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD E, A + hex: 0x5F + cat: "8-bit load/store/move" + op: LD + dst: E + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_E, cpu_rb(ctx, RB_A)); + - id: LD H, B + hex: 0x60 + cat: "8-bit load/store/move" + op: LD + dst: H + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, cpu_rb(ctx, RB_B)); + - id: LD H, C + hex: 0x61 + cat: "8-bit load/store/move" + op: LD + dst: H + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, cpu_rb(ctx, RB_C)); + - id: LD H, D + hex: 0x62 + cat: "8-bit load/store/move" + op: LD + dst: H + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, cpu_rb(ctx, RB_D)); + - id: LD H, E + hex: 0x63 + cat: "8-bit load/store/move" + op: LD + dst: H + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, cpu_rb(ctx, RB_E)); + - id: LD H, H + hex: 0x64 + cat: "8-bit load/store/move" + op: LD + dst: H + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: LD H, L + hex: 0x65 + cat: "8-bit load/store/move" + op: LD + dst: H + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, cpu_rb(ctx, RB_L)); + - id: LD H, (HL) + hex: 0x66 + cat: "8-bit load/store/move" + op: LD + dst: H + src: (HL) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD H, A + hex: 0x67 + cat: "8-bit load/store/move" + op: LD + dst: H + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_H, cpu_rb(ctx, RB_A)); + - id: LD L, B + hex: 0x68 + cat: "8-bit load/store/move" + op: LD + dst: L + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, cpu_rb(ctx, RB_B)); + - id: LD L, C + hex: 0x69 + cat: "8-bit load/store/move" + op: LD + dst: L + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, cpu_rb(ctx, RB_C)); + - id: LD L, D + hex: 0x6A + cat: "8-bit load/store/move" + op: LD + dst: L + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, cpu_rb(ctx, RB_D)); + - id: LD L, E + hex: 0x6B + cat: "8-bit load/store/move" + op: LD + dst: L + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, cpu_rb(ctx, RB_E)); + - id: LD L, H + hex: 0x6C + cat: "8-bit load/store/move" + op: LD + dst: L + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, cpu_rb(ctx, RB_H)); + - id: LD L, L + hex: 0x6D + cat: "8-bit load/store/move" + op: LD + dst: L + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: LD L, (HL) + hex: 0x6E + cat: "8-bit load/store/move" + op: LD + dst: L + src: (HL) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD L, A + hex: 0x6F + cat: "8-bit load/store/move" + op: LD + dst: L + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_L, cpu_rb(ctx, RB_A)); + - id: LD (HL), B + hex: 0x70 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: B + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_B)); + - id: LD (HL), C + hex: 0x71 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: C + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_C)); + - id: LD (HL), D + hex: 0x72 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: D + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_D)); + - id: LD (HL), E + hex: 0x73 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: E + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_E)); + - id: LD (HL), H + hex: 0x74 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: H + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_H)); + - id: LD (HL), L + hex: 0x75 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: L + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_H)); + - id: HALT + hex: 0x76 + cat: misc + op: HALT + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + ctx->cpu.state = STATE_HALT; + cpu_ww(ctx, RW_PC, old_pc); // FIXME? + - id: LD (HL), A + hex: 0x77 + cat: "8-bit load/store/move" + op: LD + dst: (HL) + src: A + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, cpu_rw(ctx, RW_HL), cpu_rb(ctx, RB_A)); + - id: LD A, B + hex: 0x78 + cat: "8-bit load/store/move" + op: LD + dst: A + src: B + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_B)); + - id: LD A, C + hex: 0x79 + cat: "8-bit load/store/move" + op: LD + dst: A + src: C + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_C)); + - id: LD A, D + hex: 0x7A + cat: "8-bit load/store/move" + op: LD + dst: A + src: D + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_D)); + - id: LD A, E + hex: 0x7B + cat: "8-bit load/store/move" + op: LD + dst: A + src: E + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_E)); + - id: LD A, H + hex: 0x7C + cat: "8-bit load/store/move" + op: LD + dst: A + src: H + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_H)); + - id: LD A, L + hex: 0x7D + cat: "8-bit load/store/move" + op: LD + dst: A + src: L + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, cpu_rb(ctx, RB_L)); + - id: LD A, (HL) + hex: 0x7E + cat: "8-bit load/store/move" + op: LD + dst: A + src: L + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, cpu_rw(ctx, RW_HL))); + - id: LD A, A + hex: 0x7F + cat: "8-bit load/store/move" + op: LD + dst: A + src: A + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // do nothing + - id: ADD A, B + hex: 0x80 + cat: "8-bit math" + op: ADD + dst: A + src: B + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_B); + - id: ADD A, C + hex: 0x81 + cat: "8-bit math" + op: ADD + dst: A + src: C + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_C); + - id: ADD A, D + hex: 0x82 + cat: "8-bit math" + op: ADD + dst: A + src: D + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_D); + - id: ADD A, E + hex: 0x83 + cat: "8-bit math" + op: ADD + dst: A + src: E + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_E); + - id: ADD A, H + hex: 0x84 + cat: "8-bit math" + op: ADD + dst: A + src: H + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_H); + - id: ADD A, L + hex: 0x85 + cat: "8-bit math" + op: ADD + dst: A + src: L + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_H); + - id: ADD A, (HL) + hex: 0x86 + cat: "8-bit math" + op: ADD + dst: A + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "0" + 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) + )); + } + - id: ADD A, A + hex: 0x87 + cat: "8-bit math" + op: ADD + dst: A + src: A + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + add_rb(ctx, RB_A); + - id: ADC A, B + hex: 0x88 + cat: "8-bit math" + op: ADC + dst: A + src: B + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_B); + - id: ADC A, C + hex: 0x89 + cat: "8-bit math" + op: ADC + dst: A + src: C + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_C); + - id: ADC A, D + hex: 0x8A + cat: "8-bit math" + op: ADC + dst: A + src: D + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_D); + - id: ADC A, E + hex: 0x8B + cat: "8-bit math" + op: ADC + dst: A + src: E + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_E); + - id: ADC A, H + hex: 0x8C + cat: "8-bit math" + op: ADC + dst: A + src: H + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_H); + - id: ADC A, L + hex: 0x8D + cat: "8-bit math" + op: ADC + dst: A + src: L + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_L); + - id: ADC A, (HL) + hex: 0x8E + cat: "8-bit math" + op: ADC + dst: A + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "0" + 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 = (cpu_rb(ctx, RB_F) & F_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) + )); + } + - id: ADC A, A + hex: 0x8F + cat: "8-bit math" + op: ADC + dst: A + src: A + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: H + c: C + code: | + adc_rb(ctx, RB_A); + - id: SUB B + hex: 0x90 + cat: "8-bit math" + op: SUB + dst: A + src: B + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_B); + - id: SUB C + hex: 0x91 + cat: "8-bit math" + op: SUB + dst: A + src: C + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_C); + - id: SUB D + hex: 0x92 + cat: "8-bit math" + op: SUB + dst: A + src: D + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_D); + - id: SUB E + hex: 0x93 + cat: "8-bit math" + op: SUB + dst: A + src: E + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_E); + - id: SUB H + hex: 0x94 + cat: "8-bit math" + op: SUB + dst: A + src: H + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_H); + - id: SUB L + hex: 0x95 + cat: "8-bit math" + op: SUB + dst: A + src: L + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_L); + - id: SUB (HL) + hex: 0x96 + cat: "8-bit math" + op: SUB + dst: A + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "1" + 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) + )); + } + - id: SUB A + hex: 0x97 + cat: "8-bit math" + op: SUB + dst: A + src: A + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sub_rb(ctx, RB_A); + - id: SBC A, B + hex: 0x98 + cat: "8-bit math" + op: SBC + dst: A + src: B + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + - id: SBC A, C + hex: 0x99 + cat: "8-bit math" + op: SBC + dst: A + src: C + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sbc_rb(ctx, RB_C); + - id: SBC A, D + hex: 0x9A + cat: "8-bit math" + op: SBC + dst: A + src: D + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sbc_rb(ctx, RB_D); + - id: SBC A, E + hex: 0x9B + cat: "8-bit math" + op: SBC + dst: A + src: E + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sbc_rb(ctx, RB_E); + - id: SBC A, H + hex: 0x9C + cat: "8-bit math" + op: SBC + dst: A + src: H + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sbc_rb(ctx, RB_H); + - id: SBC A, L + hex: 0x9D + cat: "8-bit math" + op: SBC + dst: A + src: L + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sbc_rb(ctx, RB_L); + - id: SBC A, (HL) + hex: 0x9E + cat: "8-bit math" + op: SBC + dst: A + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "1" + 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 = (cpu_rb(ctx, RB_F) & F_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? + )); + } + - id: SBC A, A + hex: 0x9F + cat: "8-bit math" + op: SBC + dst: A + src: A + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + sbc_rb(ctx, RB_A); + - id: AND B + hex: 0xA0 + cat: "8-bit math" + op: AND + src: B + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_B); + - id: AND C + hex: 0xA1 + cat: "8-bit math" + op: AND + src: C + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_C); + - id: AND D + hex: 0xA2 + cat: "8-bit math" + op: AND + src: D + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_D); + - id: AND E + hex: 0xA3 + cat: "8-bit math" + op: AND + src: E + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_E); + - id: AND H + hex: 0xA4 + cat: "8-bit math" + op: AND + src: H + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_H); + - id: AND L + hex: 0xA5 + cat: "8-bit math" + op: AND + src: L + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_L); + - id: AND (HL) + hex: 0xA6 + cat: "8-bit math" + op: AND + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "0" + 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 + )); + } + - id: AND A + hex: 0xA7 + cat: "8-bit math" + op: AND + src: A + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "1" + c: "0" + code: | + and_rb(ctx, RB_A); + - id: XOR B + hex: 0xA8 + cat: "8-bit math" + op: XOR + src: B + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_B); + - id: XOR C + hex: 0xA9 + cat: "8-bit math" + op: XOR + src: C + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_C); + - id: XOR D + hex: 0xAA + cat: "8-bit math" + op: XOR + src: D + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_D); + - id: XOR E + hex: 0xAB + cat: "8-bit math" + op: XOR + src: E + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_E); + - id: XOR H + hex: 0xAC + cat: "8-bit math" + op: XOR + src: H + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_H); + - id: XOR L + hex: 0xAD + cat: "8-bit math" + op: XOR + src: L + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_L); + - id: XOR (HL) + hex: 0xAE + cat: "8-bit math" + op: XOR + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "0" + 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) + )); + } + - id: XOR A + hex: 0xAF + cat: "8-bit math" + op: XOR + src: A + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + xor_rb(ctx, RB_A); + - id: OR B + hex: 0xB0 + cat: "8-bit math" + op: OR + src: B + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_B); + - id: OR C + hex: 0xB1 + cat: "8-bit math" + op: OR + src: C + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_C); + - id: OR D + hex: 0xB2 + cat: "8-bit math" + op: OR + src: D + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_D); + - id: OR E + hex: 0xB3 + cat: "8-bit math" + op: OR + src: E + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_E); + - id: OR H + hex: 0xB4 + cat: "8-bit math" + op: OR + src: H + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_H); + - id: OR L + hex: 0xB5 + cat: "8-bit math" + op: OR + src: L + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_L); + - id: OR (HL) + hex: 0xB6 + cat: "8-bit math" + op: OR + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "0" + 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) + )); + } + - id: OR A + hex: 0xB7 + cat: "8-bit math" + op: OR + src: A + len: 1 + time: 4 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + or_rb(ctx, RB_A); + - id: CP B + hex: 0xB8 + cat: "8-bit math" + op: CP + dst: A + src: B + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_B); + - id: CP C + hex: 0xB9 + cat: "8-bit math" + op: CP + dst: A + src: C + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_C); + - id: CP D + hex: 0xBA + cat: "8-bit math" + op: CP + dst: A + src: D + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_D); + - id: CP E + hex: 0xBB + cat: "8-bit math" + op: CP + dst: A + src: E + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_E); + - id: CP H + hex: 0xBC + cat: "8-bit math" + op: CP + dst: A + src: H + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_H); + - id: CP L + hex: 0xBD + cat: "8-bit math" + op: CP + dst: A + src: L + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_L); + - id: CP (HL) + hex: 0xBE + cat: "8-bit math" + op: CP + dst: A + src: (HL) + len: 1 + time: 8 + flags: + z: Z + n: "1" + 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) + )); + } + - id: CP A + hex: 0xBF + cat: "8-bit math" + op: CP + dst: A + src: A + len: 1 + time: 4 + flags: + z: Z + n: "1" + h: H + c: C + code: | + cp_rb(ctx, RB_A); + - id: RET NZ + hex: 0xC0 + cat: "jumps/calls" + op: RET + test: NZ + dst: PC + src: SP + len: 1 + time: + t: 20 + f: 8 + flags: + z: + n: + h: + c: + code: | + if (~cpu_rb(ctx, RB_F) & F_Z) { + pop_rw(ctx, RW_PC); + + ctx->cpu.clock += 12; + } + - id: POP BC + hex: 0xC1 + cat: "16-bit load/store/move" + op: POP + dst: BC + src: SP + len: 1 + time: 12 + flags: + z: + n: + h: + c: + code: | + pop_rw(ctx, RW_BC); + - id: JP NZ, a16 + hex: 0xC2 + cat: "jumps/calls" + op: JP + test: NZ + dst: PC + src: a16 + len: 3 + time: + t: 16 + f: 32 + flags: + z: + n: + h: + c: + code: | + if (~cpu_rb(ctx, RB_F) & F_Z) { + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + + ctx->cpu.clock -= 16; // FIXME + } + - id: JP a16 + hex: 0xC3 + cat: "jumps/calls" + op: JP + dst: PC + src: a16 + len: 3 + time: 16 + flags: + z: + n: + h: + c: + code: | + // unconditional jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + - id: CALL NZ, a16 + hex: 0xC4 + cat: "jumps/calls" + op: CALL + test: NZ + dst: PC + src: a16 + len: 3 + time: + t: 24 + f: 12 + flags: + z: + n: + h: + c: + code: | + if (~cpu_rb(ctx, RB_F) & F_Z) { + // push pc + push_rw(ctx, RW_PC); + + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + + ctx->cpu.clock += 12; // FIXME + } + - id: PUSH BC + hex: 0xC5 + cat: "16-bit load/store/move" + op: PUSH + dst: SP + src: BC + len: 1 + time: 16 + flags: + z: + n: + h: + c: + code: | + push_rw(ctx, RW_BC); + - id: ADD A, d8 + hex: 0xC6 + cat: "8-bit math" + op: ADD + dst: A + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "0" + 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) + )); + } + + - id: RST 00H + hex: 0xC7 + cat: "jumps/calls" + op: RST + dst: PC + addr: "0x00" + len: 1 + time: 16 + flags: + z: + n: + h: + c: + - id: RET Z + hex: 0xC8 + cat: "jumps/calls" + op: RET + test: Z + dst: PC + src: SP + len: 1 + time: + t: 20 + f: 8 + flags: + z: + n: + h: + c: + code: | + if (cpu_rb(ctx, RB_F) & F_Z) { + // pop pc + pop_rw(ctx, RW_PC); + + // update clock + ctx->cpu.clock += 12; + } + - id: RET + hex: 0xC9 + cat: "jumps/calls" + op: RET + dst: PC + src: SP + len: 1 + time: 16 + flags: + z: + n: + h: + c: + code: | + // pop pc + pop_rw(ctx, RW_PC); + - id: JP Z, a16 + hex: 0xCA + cat: "jumps/calls" + op: JP + test: Z + dst: PC + src: a16 + len: 3 + time: + t: 16 + f: 12 + flags: + z: + n: + h: + c: + code: | + if (cpu_rb(ctx, RB_F) & F_Z) { + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + + ctx->cpu.clock -= 16; // FIXME + } + - id: PREFIX CB + hex: 0xCB + cat: misc + op: PREFIX + len: 1 + time: 4 + flags: + z: + n: + h: + c: + - id: CALL Z, a16 + hex: 0xCC + cat: "jumps/calls" + op: CALL + test: Z + len: 3 + time: + t: 24 + f: 12 + flags: + z: + n: + h: + c: + code: | + if (cpu_rb(ctx, RB_F) & F_Z) { + // push pc + push_rw(ctx, RW_PC); + + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + + ctx->cpu.clock += 12; + } + - id: CALL a16 + hex: 0xCD + cat: "jumps/calls" + op: CALL + len: 3 + time: 24 + flags: + z: + n: + h: + c: + code: | + // push pc + push_rw(ctx, RW_PC); + + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + - id: ADC A, d8 + hex: 0xCE + cat: "8-bit math" + op: ADC + dst: A + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: H + c: C + - id: RST 08H + hex: 0xCF + cat: "jumps/calls" + op: RST + len: 1 + addr: "0x08" + time: 16 + flags: + z: + n: + h: + c: + - id: RET NC + hex: 0xD0 + cat: "jumps/calls" + op: RET + test: NC + dst: PC + src: SP + len: 1 + time: + t: 20 + f: 8 + code: | + if (~cpu_rb(ctx, RB_F) & F_C) { + // pop pc + pop_rw(ctx, RW_PC); + + // update clock + ctx->cpu.clock += 12; + } + flags: + z: + n: + h: + c: + - id: POP DE + hex: 0xD1 + cat: "16-bit load/store/move" + op: POP + dst: DE + src: SP + len: 1 + time: 12 + flags: + z: + n: + h: + c: + code: | + // pop de + pop_rw(ctx, RW_DE); + - id: JP NC, a16 + hex: 0xD2 + cat: "jumps/calls" + op: JP + test: NC + dst: PC + src: a16 + len: 3 + time: + t: 16 + f: 32 + flags: + z: + n: + h: + c: + code: | + if (~cpu_rb(ctx, RB_F) & F_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 + - id: CALL NC, a16 + hex: 0xD4 + cat: "jumps/calls" + op: CALL + test: NC + dst: PC + src: a16 + len: 3 + time: + t: 24 + f: 12 + flags: + z: + n: + h: + c: + code: | + invalid(ctx, old_pc); + - id: PUSH DE + hex: 0xD5 + cat: "16-bit load/store/move" + op: PUSH + dst: SP + src: DE + len: 1 + time: 16 + flags: + z: + n: + h: + c: + code: | + push_rw(ctx, RW_DE); + - id: SUB d8 + hex: 0xD6 + cat: "8-bit math" + op: SUB + dst: A + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "1" + 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; + + // 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) + )); + } + - id: RST 10H + hex: 0xD7 + cat: "jumps/calls" + op: RST + dst: PC + addr: "0x10" + len: 1 + time: 16 + flags: + z: Z + n: "1" + h: H + c: C + - id: RET C + hex: 0xD8 + cat: "jumps/calls" + op: RET + test: C + dst: PC + len: 1 + time: + t: 20 + f: 8 + flags: + z: + n: + h: + c: + code: | + if (cpu_rb(ctx, RB_F) & F_C) { + // pop pc + pop_rw(ctx, RW_PC); + + // update clock + ctx->cpu.clock += 12; + } + - id: RETI + hex: 0xD9 + cat: "jumps/calls" + op: RETI + dst: PC + src: SP + len: 1 + time: 16 + flags: + z: + n: + h: + c: + code: | + // enable interrupts + ctx->cpu.ei = true; + + // pop pc + pop_rw(ctx, RW_PC); + - id: JP C, a16 + hex: 0xDA + cat: "jumps/calls" + op: JP + test: C + dst: PC + src: a16 + len: 3 + time: + t: 16 + f: 32 + flags: + z: + n: + h: + c: + code: | + if (cpu_rb(ctx, RB_F) & F_C) { + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + + // update clock + ctx->cpu.clock -= 16; + } + - id: XX + hex: 0xDB + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: CALL C, a16 + hex: 0xDC + cat: "jumps/calls" + op: CALL + test: C + dst: PC + src: a16 + len: 3 + time: + t: 24 + f: 12 + flags: + z: + n: + h: + c: + code: | + if (cpu_rb(ctx, RB_F) & F_C) { + // push pc + push_rw(ctx, RW_PC); + + // jump + cpu_ww(ctx, RW_PC, mmu_rw(ctx, old_pc + 1)); + + // update clock + ctx->cpu.clock += 12; + } + - id: XX + hex: 0xDD + cat: "invalid" + op: XX + - id: SBC A, d8 + hex: 0xDE + cat: "8-bit math" + op: SBC + dst: A + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "1" + h: H + c: C + code: | + invalid(ctx, old_pc); + - id: RST 16H + hex: 0xDF + cat: "jumps/calls" + op: RST + dst: PC + addr: "0x16" + len: 1 + time: 16 + flags: + z: + n: + h: + c: + - id: LDH (a8), A + hex: 0xE0 + cat: "8-bit load/store/move" + op: LDH + dst: (a8) + src: A + len: 2 + time: 12 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, 0xFF00 + mmu_rb(ctx, old_pc + 1), cpu_rb(ctx, RB_A)); + - id: POP HL + hex: 0xE1 + cat: "16-bit load/store/move" + op: POP + dst: HL + src: SP + len: 1 + time: 12 + flags: + z: + n: + h: + c: + code: | + pop_rw(ctx, RW_HL); + - id: LD (C), A + hex: 0xE2 + cat: "8-bit load/store/move" + op: LD + dst: (C) + src: A + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, 0xFF00 + cpu_rb(ctx, RB_C), cpu_rb(ctx, RB_A)); + - id: XX + hex: 0xE3 + cat: "invalid" + op: XX + - id: XX + hex: 0xE4 + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: PUSH HL + hex: 0xE5 + cat: "16-bit load/store/move" + op: PUSH + dst: SP + src: HL + len: 1 + time: 16 + flags: + z: + n: + h: + c: + code: | + push_rw(ctx, RW_HL); + - id: AND d8 + hex: 0xE6 + cat: "8-bit math" + op: AND + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: "0" + - id: RST 20H + hex: 0xE7 + cat: "jumps/calls" + op: RST + dst: PC + addr: "0x20" + len: 1 + time: 16 + flags: + z: + n: + h: + c: + - id: ADD SP, r8 + hex: 0xE8 + cat: "misc" + op: ADD + dst: SP + src: r8 + len: 2 + time: 16 + flags: + z: "0" + n: "0" + h: H + c: C + - id: JP (HL) + hex: 0xE9 + cat: "jumps/calls" + op: JP + dst: PC + src: (HL) + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_PC, mmu_rw(ctx, cpu_rw(ctx, RW_HL))); + - id: LD (a16), A + hex: 0xEA + cat: "8-bit load/store/move" + op: LD + dst: (a16) + src: A + len: 3 + time: 16 + flags: + z: + n: + h: + c: + code: | + mmu_wb(ctx, mmu_rw(ctx, old_pc + 1), cpu_rb(ctx, RB_A)); + - id: XX + hex: 0xEB + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: XX + hex: 0xEC + cat: "invalid" + op: XX + - id: XX + hex: 0xED + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: XOR d8 + hex: 0xEE + cat: "8-bit math" + op: XOR + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: + h: + c: + - id: RST 28H + hex: 0xEF + cat: "jumps/calls" + op: RST + len: 1 + addr: "0x28" + time: 16 + flags: + z: + n: + h: + c: + - id: LDH A, (a8) + hex: 0xF0 + cat: "8-bit load/store/move" + op: LDH + dst: A + src: (a8) + len: 2 + time: 12 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, 0xFF00 + old_pc + 1)); + - id: POP AF + hex: 0xF1 + cat: "16-bit load/store/move" + op: POP + dst: AF + src: SP + len: 1 + time: 12 + flags: + z: Z + n: N + h: H + c: C + code: | + pop_rw(ctx, RW_AF); + - id: LD A, (C) + hex: 0xF2 + cat: "8-bit load/store/move" + op: LD + dst: A + src: (C) + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_wb(ctx, RB_A, mmu_rb(ctx, 0xFF00 + cpu_rb(ctx, RB_C))); + - id: DI + hex: 0xF3 + cat: "misc" + op: DI + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // disable interrupts + ctx->cpu.ei = false; + - id: XX + hex: 0xF4 + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: PUSH AF + hex: 0xF5 + cat: "16-bit load/store/move" + op: PUSH + dst: SP + src: AF + len: 1 + time: 16 + flags: + z: + n: + h: + c: + code: | + push_rw(ctx, RW_AF); + - id: OR d8 + hex: 0xF6 + cat: "8-bit math" + op: OR + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "0" + 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) + )); + } + - id: RST 30H + hex: 0xF7 + cat: "jumps/calls" + op: RST + addr: "0x30" + len: 1 + time: 16 + flags: + z: + n: + h: + c: + - id: LD HL, SP+r8 + hex: 0xF8 + cat: "16-bit load/store/move" + op: LD + dst: HL + src: SP+r8 + len: 2 + time: 12 + flags: + z: "0" + n: "0" + h: H + c: C + - id: LD SP, HL + hex: 0xF9 + cat: "16-bit load/store/move" + op: LD + dst: SP + src: HL + len: 1 + time: 8 + flags: + z: + n: + h: + c: + code: | + cpu_ww(ctx, RW_SP, cpu_rw(ctx, RW_HL)); + - id: LD A, (a16) + hex: 0xFA + cat: "8-bit load/store/move" + op: LD + dst: A + src: (a16) + len: 3 + time: 16 + flags: + z: + n: + h: + c: + - id: EI + hex: 0xFB + cat: "misc" + op: EI + len: 1 + time: 4 + flags: + z: + n: + h: + c: + code: | + // disable interrupts + ctx->cpu.ei = false; + - id: XX + hex: 0xFC + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: XX + hex: 0xFD + cat: "invalid" + op: XX + code: | + invalid(ctx, old_pc); + - id: CP d8 + hex: 0xFE + cat: "8-bit math" + op: CP + dst: A + src: d8 + len: 2 + time: 8 + flags: + z: Z + n: "1" + 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) + )); + } + - id: RST 38H + hex: 0xFF + cat: "jumps/calls" + op: RST + dst: PC + addr: "0x38" + len: 1 + time: 16 + flags: + z: + n: + h: + c: + + cb: + - id: RLC B + hex: 0x00 + cat: "8-bit rotations/shifts" + op: RLC + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_B); + - id: RLC C + hex: 0x01 + cat: "8-bit rotations/shifts" + op: RLC + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_C); + - id: RLC D + hex: 0x02 + cat: "8-bit rotations/shifts" + op: RLC + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_D); + - id: RLC E + hex: 0x03 + cat: "8-bit rotations/shifts" + op: RLC + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_E); + - id: RLC H + hex: 0x04 + cat: "8-bit rotations/shifts" + op: RLC + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_H); + - id: RLC L + hex: 0x05 + cat: "8-bit rotations/shifts" + op: RLC + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_L); + - id: RLC (HL) + hex: 0x06 + cat: "8-bit rotations/shifts" + op: RLC + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + { + // 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); + + // set flags + cpu_wf(ctx, F_Z | F_N | F_H | F_C, ( + (n ? 0 : F_Z) | + (c ? F_C : 0) + )); + } + - id: RLC A + hex: 0x07 + cat: "8-bit rotations/shifts" + op: RLC + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rlc_rb(ctx, RB_A); + - id: RRC B + hex: 0x08 + cat: "8-bit rotations/shifts" + op: RRC + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_B); + - id: RRC C + hex: 0x09 + cat: "8-bit rotations/shifts" + op: RRC + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_C); + - id: RRC D + hex: 0x0A + cat: "8-bit rotations/shifts" + op: RRC + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_D); + - id: RRC E + hex: 0x0B + cat: "8-bit rotations/shifts" + op: RRC + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_E); + - id: RRC H + hex: 0x0C + cat: "8-bit rotations/shifts" + op: RRC + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_H); + - id: RRC L + hex: 0x0D + cat: "8-bit rotations/shifts" + op: RRC + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_L); + - id: RRC (HL) + hex: 0x0E + cat: "8-bit rotations/shifts" + op: RRC + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: C + - id: RRC A + hex: 0x0F + cat: "8-bit rotations/shifts" + op: RRC + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rrc_rb(ctx, RB_A); + - id: RL B + hex: 0x10 + cat: "8-bit rotations/shifts" + op: RL + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_B); + - id: RL C + hex: 0x11 + cat: "8-bit rotations/shifts" + op: RL + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_C); + - id: RL D + hex: 0x12 + cat: "8-bit rotations/shifts" + op: RL + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_D); + - id: RL E + hex: 0x13 + cat: "8-bit rotations/shifts" + op: RL + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_E); + - id: RL H + hex: 0x14 + cat: "8-bit rotations/shifts" + op: RL + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_H); + - id: RL L + hex: 0x15 + cat: "8-bit rotations/shifts" + op: RL + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_L); + - id: RL (HL) + hex: 0x16 + cat: "8-bit rotations/shifts" + op: RL + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: C + - id: RL A + hex: 0x17 + cat: "8-bit rotations/shifts" + op: RL + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rl_rb(ctx, RB_A); + - id: RR B + hex: 0x18 + cat: "8-bit rotations/shifts" + op: RR + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_B); + - id: RR C + hex: 0x19 + cat: "8-bit rotations/shifts" + op: RR + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_C); + - id: RR D + hex: 0x1A + cat: "8-bit rotations/shifts" + op: RR + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_D); + - id: RR E + hex: 0x1B + cat: "8-bit rotations/shifts" + op: RR + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_E); + - id: RR H + hex: 0x1C + cat: "8-bit rotations/shifts" + op: RR + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_H); + - id: RR L + hex: 0x1D + cat: "8-bit rotations/shifts" + op: RR + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_L); + - id: RR (HL) + hex: 0x1E + cat: "8-bit rotations/shifts" + op: RR + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: C + - id: RR A + hex: 0x1F + cat: "8-bit rotations/shifts" + op: RR + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + rr_rb(ctx, RB_A); + - id: SLA B + hex: 0x20 + cat: "8-bit rotations/shifts" + op: SLA + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_B); + - id: SLA C + hex: 0x21 + cat: "8-bit rotations/shifts" + op: SLA + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_C); + - id: SLA D + hex: 0x22 + cat: "8-bit rotations/shifts" + op: SLA + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_D); + - id: SLA E + hex: 0x23 + cat: "8-bit rotations/shifts" + op: SLA + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_E); + - id: SLA H + hex: 0x24 + cat: "8-bit rotations/shifts" + op: SLA + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_H); + - id: SLA L + hex: 0x25 + cat: "8-bit rotations/shifts" + op: SLA + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_L); + - id: SLA (HL) + hex: 0x26 + cat: "8-bit rotations/shifts" + op: SLA + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: C + - id: SLA A + hex: 0x27 + cat: "8-bit rotations/shifts" + op: SLA + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + sla_rb(ctx, RB_A); + - id: SRA B + hex: 0x28 + cat: "8-bit rotations/shifts" + op: SRA + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_B); + - id: SRA C + hex: 0x29 + cat: "8-bit rotations/shifts" + op: SRA + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_C); + - id: SRA D + hex: 0x2A + cat: "8-bit rotations/shifts" + op: SRA + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_D); + - id: SRA E + hex: 0x2B + cat: "8-bit rotations/shifts" + op: SRA + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_E); + - id: SRA H + hex: 0x2C + cat: "8-bit rotations/shifts" + op: SRA + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_H); + - id: SRA L + hex: 0x2D + cat: "8-bit rotations/shifts" + op: SRA + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_L); + - id: SRA (HL) + hex: 0x2E + cat: "8-bit rotations/shifts" + op: SRA + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: "0" + - id: SRA A + hex: 0x2F + cat: "8-bit rotations/shifts" + op: SRA + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + sra_rb(ctx, RB_A); + - id: SWAP B + hex: 0x30 + cat: "8-bit rotations/shifts" + op: SWAP + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_B); + - id: SWAP C + hex: 0x31 + cat: "8-bit rotations/shifts" + op: SWAP + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_C); + - id: SWAP D + hex: 0x32 + cat: "8-bit rotations/shifts" + op: SWAP + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_D); + - id: SWAP E + hex: 0x33 + cat: "8-bit rotations/shifts" + op: SWAP + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_E); + - id: SWAP H + hex: 0x34 + cat: "8-bit rotations/shifts" + op: SWAP + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_H); + - id: SWAP L + hex: 0x35 + cat: "8-bit rotations/shifts" + op: SWAP + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_L); + - id: SWAP (HL) + hex: 0x36 + cat: "8-bit rotations/shifts" + op: SWAP + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: "0" + - id: SWAP A + hex: 0x37 + cat: "8-bit rotations/shifts" + op: SWAP + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: "0" + code: | + swap_rb(ctx, RB_A); + - id: SRL B + hex: 0x38 + cat: "8-bit rotations/shifts" + op: SRL + dst: B + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_B); + - id: SRL C + hex: 0x39 + cat: "8-bit rotations/shifts" + op: SRL + dst: C + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_C); + - id: SRL D + hex: 0x3A + cat: "8-bit rotations/shifts" + op: SRL + dst: D + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_D); + - id: SRL E + hex: 0x3B + cat: "8-bit rotations/shifts" + op: SRL + dst: E + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_E); + - id: SRL H + hex: 0x3C + cat: "8-bit rotations/shifts" + op: SRL + dst: H + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_H); + - id: SRL L + hex: 0x3D + cat: "8-bit rotations/shifts" + op: SRL + dst: L + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_L); + - id: SRL (HL) + hex: 0x3E + cat: "8-bit rotations/shifts" + op: SRL + dst: (HL) + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "0" + c: C + - id: SRL A + hex: 0x3F + cat: "8-bit rotations/shifts" + op: SRL + dst: A + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "0" + c: C + code: | + srl_rb(ctx, RB_A); + - id: BIT 0, B + hex: 0x40 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 0); + - id: BIT 0, C + hex: 0x41 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 0); + - id: BIT 0, D + hex: 0x42 + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 0); + - id: BIT 0, E + hex: 0x43 + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 0); + - id: BIT 0, H + hex: 0x44 + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 0); + - id: BIT 0, L + hex: 0x45 + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 0); + - id: BIT 0, (HL) + hex: 0x46 + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 0 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 0); + - id: BIT 0, A + hex: 0x47 + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 0 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 0); + - id: BIT 1, B + hex: 0x48 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 1); + - id: BIT 1, C + hex: 0x49 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 1); + - id: BIT 1, D + hex: 0x4A + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 1); + - id: BIT 1, E + hex: 0x4B + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 1); + - id: BIT 1, H + hex: 0x4C + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 1); + - id: BIT 1, L + hex: 0x4D + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 1); + - id: BIT 1, (HL) + hex: 0x4E + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 1 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 1); + - id: BIT 1, A + hex: 0x4F + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 1 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 1); + - id: BIT 2, B + hex: 0x50 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 2); + - id: BIT 2, C + hex: 0x51 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 2); + - id: BIT 2, D + hex: 0x52 + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 2); + - id: BIT 2, E + hex: 0x53 + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 2); + - id: BIT 2, H + hex: 0x54 + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 2); + - id: BIT 2, L + hex: 0x55 + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 2); + - id: BIT 2, (HL) + hex: 0x56 + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 2 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 2); + - id: BIT 2, A + hex: 0x57 + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 2 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 2); + - id: BIT 3, B + hex: 0x58 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 3); + - id: BIT 3, C + hex: 0x59 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 3); + - id: BIT 3, D + hex: 0x5A + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 3); + - id: BIT 3, E + hex: 0x5B + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 3); + - id: BIT 3, H + hex: 0x5C + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 3); + - id: BIT 3, L + hex: 0x5D + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 3); + - id: BIT 3, (HL) + hex: 0x5E + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 3 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 3); + - id: BIT 3, A + hex: 0x5F + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 3 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 3); + - id: BIT 4, B + hex: 0x60 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 4); + - id: BIT 4, C + hex: 0x61 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 4); + - id: BIT 4, D + hex: 0x62 + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 4); + - id: BIT 4, E + hex: 0x63 + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 4); + - id: BIT 4, H + hex: 0x64 + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 4); + - id: BIT 4, L + hex: 0x65 + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 4); + - id: BIT 4, (HL) + hex: 0x66 + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 4 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 4); + - id: BIT 4, A + hex: 0x67 + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 4 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 4); + - id: BIT 5, B + hex: 0x68 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 5); + - id: BIT 5, C + hex: 0x69 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 5); + - id: BIT 5, D + hex: 0x6A + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 5); + - id: BIT 5, E + hex: 0x6B + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 5); + - id: BIT 5, H + hex: 0x6C + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 5); + - id: BIT 5, L + hex: 0x6D + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 5); + - id: BIT 5, (HL) + hex: 0x6E + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 5 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 5); + - id: BIT 5, A + hex: 0x6F + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 5 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 5); + - id: BIT 6, B + hex: 0x70 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 6); + - id: BIT 6, C + hex: 0x71 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 6); + - id: BIT 6, D + hex: 0x72 + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 6); + - id: BIT 6, E + hex: 0x73 + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 6); + - id: BIT 6, H + hex: 0x74 + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 6); + - id: BIT 6, L + hex: 0x75 + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 6); + - id: BIT 6, (HL) + hex: 0x76 + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 6 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 6); + - id: BIT 6, A + hex: 0x77 + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 6 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 6); + - id: BIT 7, B + hex: 0x78 + cat: "8-bit rotations/shifts" + op: BIT + src: B + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_B, 7); + - id: BIT 7, C + hex: 0x79 + cat: "8-bit rotations/shifts" + op: BIT + src: C + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_C, 7); + - id: BIT 7, D + hex: 0x7A + cat: "8-bit rotations/shifts" + op: BIT + src: D + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_D, 7); + - id: BIT 7, E + hex: 0x7B + cat: "8-bit rotations/shifts" + op: BIT + src: E + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_E, 7); + - id: BIT 7, H + hex: 0x7C + cat: "8-bit rotations/shifts" + op: BIT + src: H + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_H, 7); + - id: BIT 7, L + hex: 0x7D + cat: "8-bit rotations/shifts" + op: BIT + src: L + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_L, 7); + - id: BIT 7, (HL) + hex: 0x7E + cat: "8-bit rotations/shifts" + op: BIT + src: (HL) + bit: 7 + len: 2 + time: 16 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_hl(ctx, 7); + - id: BIT 7, A + hex: 0x7F + cat: "8-bit rotations/shifts" + op: BIT + src: A + bit: 7 + len: 2 + time: 8 + flags: + z: Z + n: "0" + h: "1" + c: + code: | + bit_rb(ctx, RB_A, 7); + - id: RES 0, B + hex: 0x80 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 0); + - id: RES 0, C + hex: 0x81 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 0); + - id: RES 0, D + hex: 0x82 + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 0); + - id: RES 0, E + hex: 0x83 + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 0); + - id: RES 0, H + hex: 0x84 + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 0); + - id: RES 0, L + hex: 0x85 + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 0); + - id: RES 0, (HL) + hex: 0x86 + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 0 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 0); + - id: RES 0, A + hex: 0x87 + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 0); + - id: RES 1, B + hex: 0x88 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 1); + - id: RES 1, C + hex: 0x89 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 1); + - id: RES 1, D + hex: 0x8A + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 1); + - id: RES 1, E + hex: 0x8B + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 1); + - id: RES 1, H + hex: 0x8C + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 1); + - id: RES 1, L + hex: 0x8D + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 1); + - id: RES 1, (HL) + hex: 0x8E + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 1 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 1); + - id: RES 1, A + hex: 0x8F + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 1); + - id: RES 2, B + hex: 0x90 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 2); + - id: RES 2, C + hex: 0x91 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 2); + - id: RES 2, D + hex: 0x92 + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 2); + - id: RES 2, E + hex: 0x93 + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 2); + - id: RES 2, H + hex: 0x94 + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 2); + - id: RES 2, L + hex: 0x95 + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 2); + - id: RES 2, (HL) + hex: 0x96 + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 2 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 2); + - id: RES 2, A + hex: 0x97 + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 2); + - id: RES 3, B + hex: 0x98 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 3); + - id: RES 3, C + hex: 0x99 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 3); + - id: RES 3, D + hex: 0x9A + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 3); + - id: RES 3, E + hex: 0x9B + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 3); + - id: RES 3, H + hex: 0x9C + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 3); + - id: RES 3, L + hex: 0x9D + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 3); + - id: RES 3, (HL) + hex: 0x9E + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 3 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 3); + - id: RES 3, A + hex: 0x9F + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 3); + - id: RES 4, B + hex: 0xA0 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 4); + - id: RES 4, C + hex: 0xA1 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 4); + - id: RES 4, D + hex: 0xA2 + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 4); + - id: RES 4, E + hex: 0xA3 + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 4); + - id: RES 4, H + hex: 0xA4 + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 4); + - id: RES 4, L + hex: 0xA5 + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 4); + - id: RES 4, (HL) + hex: 0xA6 + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 4 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 4); + - id: RES 4, A + hex: 0xA7 + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 4); + - id: RES 5, B + hex: 0xA8 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 5); + - id: RES 5, C + hex: 0xA9 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 5); + - id: RES 5, D + hex: 0xAA + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 5); + - id: RES 5, E + hex: 0xAB + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 5); + - id: RES 5, H + hex: 0xAC + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 5); + - id: RES 5, L + hex: 0xAD + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 5); + - id: RES 5, (HL) + hex: 0xAE + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 5 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 5); + - id: RES 5, A + hex: 0xAF + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 5); + - id: RES 6, B + hex: 0xB0 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 6); + - id: RES 6, C + hex: 0xB1 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 6); + - id: RES 6, D + hex: 0xB2 + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 6); + - id: RES 6, E + hex: 0xB3 + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 6); + - id: RES 6, H + hex: 0xB4 + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 6); + - id: RES 6, L + hex: 0xB5 + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 6); + - id: RES 6, (HL) + hex: 0xB6 + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 6 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 6); + - id: RES 6, A + hex: 0xB7 + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 6); + - id: RES 7, B + hex: 0xB8 + cat: "8-bit rotations/shifts" + op: RES + src: B + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_B, 7); + - id: RES 7, C + hex: 0xB9 + cat: "8-bit rotations/shifts" + op: RES + src: C + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_C, 7); + - id: RES 7, D + hex: 0xBA + cat: "8-bit rotations/shifts" + op: RES + src: D + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_D, 7); + - id: RES 7, E + hex: 0xBB + cat: "8-bit rotations/shifts" + op: RES + src: E + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_E, 7); + - id: RES 7, H + hex: 0xBC + cat: "8-bit rotations/shifts" + op: RES + src: H + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_H, 7); + - id: RES 7, L + hex: 0xBD + cat: "8-bit rotations/shifts" + op: RES + src: L + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_L, 7); + - id: RES 7, (HL) + hex: 0xBE + cat: "8-bit rotations/shifts" + op: RES + src: (HL) + bit: 7 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + res_hl(ctx, 7); + - id: RES 7, A + hex: 0xBF + cat: "8-bit rotations/shifts" + op: RES + src: A + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + res_rb(ctx, RB_A, 7); + - id: SET 0, B + hex: 0xC0 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 0); + - id: SET 0, C + hex: 0xC1 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 0); + - id: SET 0, D + hex: 0xC2 + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 0); + - id: SET 0, E + hex: 0xC3 + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 0); + - id: SET 0, H + hex: 0xC4 + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 0); + - id: SET 0, L + hex: 0xC5 + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 0); + - id: SET 0, (HL) + hex: 0xC6 + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 0 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 0); + - id: SET 0, A + hex: 0xC7 + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 0 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 0); + - id: SET 1, B + hex: 0xC8 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 1); + - id: SET 1, C + hex: 0xC9 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 1); + - id: SET 1, D + hex: 0xCA + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 1); + - id: SET 1, E + hex: 0xCB + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 1); + - id: SET 1, H + hex: 0xCC + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 1); + - id: SET 1, L + hex: 0xCD + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 1); + - id: SET 1, (HL) + hex: 0xCE + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 1 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 1); + - id: SET 1, A + hex: 0xCF + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 1 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 1); + - id: SET 2, B + hex: 0xD0 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 2); + - id: SET 2, C + hex: 0xD1 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 2); + - id: SET 2, D + hex: 0xD2 + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 2); + - id: SET 2, E + hex: 0xD3 + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 2); + - id: SET 2, H + hex: 0xD4 + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 2); + - id: SET 2, L + hex: 0xD5 + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 2); + - id: SET 2, (HL) + hex: 0xD6 + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 2 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 2); + - id: SET 2, A + hex: 0xD7 + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 2 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 2); + - id: SET 3, B + hex: 0xD8 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 3); + - id: SET 3, C + hex: 0xD9 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 3); + - id: SET 3, D + hex: 0xDA + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 3); + - id: SET 3, E + hex: 0xDB + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 3); + - id: SET 3, H + hex: 0xDC + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 3); + - id: SET 3, L + hex: 0xDD + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 3); + - id: SET 3, (HL) + hex: 0xDE + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 3 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 3); + - id: SET 3, A + hex: 0xDF + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 3 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 3); + - id: SET 4, B + hex: 0xE0 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 4); + - id: SET 4, C + hex: 0xE1 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 4); + - id: SET 4, D + hex: 0xE2 + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 4); + - id: SET 4, E + hex: 0xE3 + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 4); + - id: SET 4, H + hex: 0xE4 + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 4); + - id: SET 4, L + hex: 0xE5 + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 4); + - id: SET 4, (HL) + hex: 0xE6 + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 4 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 4); + - id: SET 4, A + hex: 0xE7 + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 4 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 4); + - id: SET 5, B + hex: 0xE8 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 5); + - id: SET 5, C + hex: 0xE9 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 5); + - id: SET 5, D + hex: 0xEA + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 5); + - id: SET 5, E + hex: 0xEB + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 5); + - id: SET 5, H + hex: 0xEC + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 5); + - id: SET 5, L + hex: 0xED + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 5); + - id: SET 5, (HL) + hex: 0xEE + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 5 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 5); + - id: SET 5, A + hex: 0xEF + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 5 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 5); + - id: SET 6, B + hex: 0xF0 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 6); + - id: SET 6, C + hex: 0xF1 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 6); + - id: SET 6, D + hex: 0xF2 + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 6); + - id: SET 6, E + hex: 0xF3 + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 6); + - id: SET 6, H + hex: 0xF4 + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 6); + - id: SET 6, L + hex: 0xF5 + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_L, 6); + - id: SET 6, (HL) + hex: 0xF6 + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 6 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 6); + - id: SET 6, A + hex: 0xF7 + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 6 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 6); + - id: SET 7, B + hex: 0xF8 + cat: "8-bit rotations/shifts" + op: SET + src: B + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_B, 7); + - id: SET 7, C + hex: 0xF9 + cat: "8-bit rotations/shifts" + op: SET + src: C + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_C, 7); + - id: SET 7, D + hex: 0xFA + cat: "8-bit rotations/shifts" + op: SET + src: D + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_D, 7); + - id: SET 7, E + hex: 0xFB + cat: "8-bit rotations/shifts" + op: SET + src: E + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_E, 7); + - id: SET 7, H + hex: 0xFC + cat: "8-bit rotations/shifts" + op: SET + src: H + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 7); + - id: SET 7, L + hex: 0xFD + cat: "8-bit rotations/shifts" + op: SET + src: L + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_H, 7); + - id: SET 7, (HL) + hex: 0xFE + cat: "8-bit rotations/shifts" + op: SET + src: (HL) + bit: 7 + len: 2 + time: 16 + flags: + z: + n: + h: + c: + code: | + set_hl(ctx, 7); + - id: SET 7, A + hex: 0xFF + cat: "8-bit rotations/shifts" + op: SET + src: A + bit: 7 + len: 2 + time: 8 + flags: + z: + n: + h: + c: + code: | + set_rb(ctx, RB_A, 7); +templates: + main: | + #include + #include + + #define UNUSED(a) ((void) (a)) + + #define F_Z (1 << 7) + #define F_N (1 << 6) + #define F_H (1 << 5) + #define F_C (1 << 4) + + typedef enum { + RB_A, + RB_F, + RB_B, + RB_C, + RB_D, + RB_E, + RB_H, + RB_L, + RB_LAST + } rb_t; + + typedef enum { + RW_AF, + RW_BC, + RW_DE, + RW_HL, + RW_SP, + RW_PC, + RW_LAST, + } rw_t; + + typedef enum { + STATE_RUN, + STATE_STOP, + STATE_HALT, + STATE_INVALID, + STATE_NOT_IMPLEMENTED, + STATE_LAST, + } cpu_state_t; + + typedef struct { + struct { + // TODO + uint8_t mem[0xFFFF]; + } mmu; + + struct { + uint16_t rs[RW_LAST]; + uint32_t clock; /* FIXME: uint16_t? */ + cpu_state_t state; + bool ei; + } cpu; + } gb_t; + + static uint8_t + mmu_rb( + const gb_t * const ctx, + const uint16_t addr + ) { + return ctx->mmu.mem[addr]; + } + + static void + mmu_wb( + gb_t * const ctx, + const uint16_t addr, + const uint8_t val + ) { + ctx->mmu.mem[addr] = val; + } + + static uint16_t + mmu_rw( + const gb_t * const ctx, + const uint16_t addr + ) { + // FIXME + return (((uint16_t) mmu_rb(ctx, addr)) << 8) + mmu_rb(ctx, addr + 1); + } + + static void + mmu_ww( + gb_t * const ctx, + const uint16_t addr, + const uint16_t val + ) { + ctx->mmu.mem[addr] = (val >> 8); + ctx->mmu.mem[addr + 1] = val & 0xFF; + } + + static uint16_t + cpu_rw( + const gb_t * const ctx, + const rw_t reg + ) { + return ctx->cpu.rs[reg]; + } + + static void + cpu_ww( + gb_t * const ctx, + const rw_t reg, + const uint16_t val + ) { + ctx->cpu.rs[reg] = val; + } + + static uint8_t + cpu_rb( + const gb_t * const ctx, + const rb_t reg + ) { + switch (reg) { + case RB_A: + return cpu_rw(ctx, RW_AF) >> 8; + case RB_F: + return cpu_rw(ctx, RW_AF) & 0xFF; + case RB_B: + return cpu_rw(ctx, RW_BC) >> 8; + case RB_C: + return cpu_rw(ctx, RW_BC) & 0xFF; + case RB_D: + return cpu_rw(ctx, RW_DE) >> 8; + case RB_E: + return cpu_rw(ctx, RW_DE) & 0xFF; + case RB_H: + return cpu_rw(ctx, RW_HL) >> 8; + case RB_L: + return cpu_rw(ctx, RW_HL) & 0xFF; + default: + return 0; + } + } + + static void + cpu_wb( + gb_t * const ctx, + const rb_t reg, + const uint8_t val + ) { + switch (reg) { + case RB_A: + ctx->cpu.rs[RW_AF] = (((uint16_t) val) << 8) + (ctx->cpu.rs[RW_AF] & 0xFF); + break; + case RB_F: + ctx->cpu.rs[RW_AF] = (ctx->cpu.rs[RW_AF] & 0xFF00) + val; + break; + case RB_B: + ctx->cpu.rs[RW_BC] = (((uint16_t) val) << 8) + (ctx->cpu.rs[RW_BC] & 0xFF); + break; + case RB_C: + ctx->cpu.rs[RW_BC] = (ctx->cpu.rs[RW_BC] & 0xFF00) + val; + break; + case RB_D: + ctx->cpu.rs[RW_DE] = (((uint16_t) val) << 8) + (ctx->cpu.rs[RW_DE] & 0xFF); + break; + case RB_E: + ctx->cpu.rs[RW_DE] = (ctx->cpu.rs[RW_DE] & 0xFF00) + val; + break; + case RB_H: + ctx->cpu.rs[RW_HL] = (((uint16_t) val) << 8) + (ctx->cpu.rs[RW_HL] & 0xFF); + break; + case RB_L: + ctx->cpu.rs[RW_HL] = (ctx->cpu.rs[RW_HL] & 0xFF00) + val; + break; + default: + // FIXME: do what now? + return; + } + } + + static void + cpu_wf( + gb_t * const ctx, + const uint8_t mask, + const uint8_t flags + ) { + 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_C) ? flags : of) & F_C) + )); + } + + static void + invalid( + gb_t * const ctx, + const uint16_t pc + ) { + ctx->cpu.state = STATE_INVALID; + cpu_ww(ctx, RW_PC, pc); // FIXME? + } + + static void + not_implemented( + gb_t * const ctx, + const uint16_t pc, + const uint16_t op + ) { + UNUSED(op); + ctx->cpu.state = STATE_NOT_IMPLEMENTED; + 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, + const rb_t reg + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, reg), + n = o + 1; + + // set new value + cpu_wb(ctx, reg, n); + + // set flags + cpu_wf(ctx, F_Z | F_N | F_H, ( + (n ? F_Z : 0) | + (((o & 0x0F) == 0x0F) ? F_H : 0) + )); + } + + static void + dec_rb( + gb_t * const ctx, + const rb_t reg + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, reg), + n = o - 1; + + // set new value + cpu_wb(ctx, reg, n); + + // set flags + cpu_wf(ctx, F_Z | F_N | F_H, ( + (n ? F_Z : 0) | + F_N | + (((o ^ n) & 0x10) ? F_H : 0) + )); + } + + static void + add_rw_rw( + gb_t * const ctx, + const rw_t dst_reg, + const rw_t src_reg + ) { + // get old values and sum + 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)); + + // set flags + cpu_wf(ctx, F_N | F_H | F_C, ( + ((((dst_val & 0xFF) + (src_val & 0xFF)) > 0xFF) ? F_H : 0) | + ((n == 0x10000) ? F_C : 0) + )); + } + + static void + add_rb( + gb_t * const ctx, + const rb_t reg + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, RB_A), + n = cpu_rb(ctx, reg); + 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 + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, RB_A), + n = cpu_rb(ctx, reg), + c = (cpu_rb(ctx, RB_F) & F_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 + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, RB_A), + n = cpu_rb(ctx, reg), + 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 + sbc_rb( + gb_t * const ctx, + const rb_t reg + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, RB_A), + n = cpu_rb(ctx, reg), + c = (cpu_rb(ctx, RB_F) & F_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 + ) { + // 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) | + F_H + )); + } + + static void + xor_rb( + 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) + )); + } + + static void + or_rb( + 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) + )); + } + + static void + cp_rb( + gb_t * const ctx, + const rb_t reg + ) { + // get old and new value + const uint8_t o = cpu_rb(ctx, RB_A), + n = cpu_rb(ctx, reg), + 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 + ) { + // get sp + const uint16_t sp = cpu_rw(ctx, RW_SP); + + // write to stack + mmu_ww(ctx, sp - 2, cpu_rw(ctx, reg)); + + // decriment sp + cpu_ww(ctx, RW_SP, sp - 2); + } + + static void + pop_rw( + gb_t * const ctx, + const rw_t reg + ) { + // get sp + const uint16_t sp = cpu_rw(ctx, RW_SP); + + // read from sp + cpu_ww(ctx, reg, mmu_rw(ctx, sp)); + + // increment sp + cpu_ww(ctx, RW_SP, sp + 2); + } + + static void + rlc_rb( + 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 & 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) + )); + } + + static void + rrc_rb( + 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) + )); + } + + static void + rl_rb( + 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) + (cpu_rb(ctx, RB_F) & F_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) + )); + } + + static void + rr_rb( + gb_t * const ctx, + const rb_t reg + ) { + // get old value and new value + const uint8_t o = cpu_rb(ctx, reg), + n = (cpu_rb(ctx, RB_F) & F_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) + )); + } + + static void + sla_rb( + 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) + )); + } + + static void + sra_rb( + 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) + )); + } + + static void + srl_rb( + 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) + )); + } + + static void + bit_rb( + gb_t * const ctx, + const rb_t reg, + const uint8_t bit + ) { + // test bit + const uint8_t v = cpu_rb(ctx, reg) & (bit ? (1 << bit) : 1); + + // set flags + cpu_wf(ctx, F_Z | F_N | F_H, ( + (v ? 0 : F_Z) | + 0 | + F_H + )); + } + + static void + bit_hl( + gb_t * const ctx, + const uint8_t bit + ) { + // test bit + const uint16_t addr = cpu_rb(ctx, RW_HL); + const uint8_t v = mmu_rb(ctx, addr) & (bit ? (1 << bit) : 1); + + // set flags + cpu_wf(ctx, F_Z | F_N | F_H, ( + (v ? 0 : F_Z) | + 0 | + F_H + )); + } + + + static void + set_rb( + gb_t * const ctx, + const rb_t reg, + const uint8_t bit + ) { + // get/update value + cpu_wb(ctx, reg, cpu_rb(ctx, reg) | (bit ? (1 << bit) : 1)); + } + + static void + set_hl( + gb_t * const ctx, + const uint8_t bit + ) { + // get address + const uint16_t addr = cpu_rw(ctx, RW_HL); + + // get/update value + mmu_wb(ctx, addr, mmu_rb(ctx, addr) | (bit ? (1 << bit) : 1)); + } + + static void + res_rb( + gb_t * const ctx, + const rb_t reg, + const uint8_t bit + ) { + // get/update value + cpu_wb(ctx, reg, cpu_rb(ctx, reg) | ~(bit ? (1 << bit) : 1)); + } + + static void + res_hl( + gb_t * const ctx, + const uint8_t bit + ) { + // get address + const uint16_t addr = cpu_rw(ctx, RW_HL); + + // get/update value + mmu_wb(ctx, addr, mmu_rb(ctx, addr) | ~(bit ? (1 << bit) : 1)); + } + + static void + swap_rb( + gb_t * const ctx, + const rb_t reg + ) { + const uint8_t v = cpu_rb(ctx, reg); + 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) + )); + } + + void + gb_step( + gb_t * const ctx + ) { + const uint16_t old_pc = cpu_rw(ctx, RW_PC), + op = gb_next_op(ctx); + + // TODO: handle interrupts + + switch (op) { + <%= switches %> + default: + not_implemented(ctx, old_pc, op); + } + } + + sla_r8: | + let b = ctx.cpu.r.<%= dst.downcase %>, + c = (b & 0x80), + v = (b << 1) & 0xFF; + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + (c ? 0x10 : 0) + ); + ctx.cpu.r.<%= dst.downcase %> = v; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + sla_rp16: | + let addr = ( + ((ctx.cpu.r.<%= dst.downcase[1] %> & 0xFF) << 8) + + (ctx.cpu.r.<%= dst.downcase[2] %> & 0xFF) + ), + b = ctx.mmu.rb(addr), + c = (b & 0x80), + v = (b << 1) & 0xFF; + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + (c ? 0x10 : 0) + ); + ctx.mmu.wb(addr, v); + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + sra_r8: | + let b = ctx.cpu.r.<%= dst.downcase %>, + c = (b & 0x01), + v = ((b & 0x80) | (b >> 1)) & 0xFF; + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + (c ? 0x10 : 0) + ); + ctx.cpu.r.<%= dst.downcase %> = v; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + sra_rp16: | + let addr = ( + ((ctx.cpu.r.<%= dst.downcase[1] %> & 0xFF) << 8) + + (ctx.cpu.r.<%= dst.downcase[2] %> & 0xFF) + ), + b = ctx.mmu.rb(addr), + c = (b & 0x01), + v = ((b & 0x80) | (b >> 1)) & 0xFF; + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + (c ? 0x10 : 0) + ); + ctx.mmu.wb(addr, v); + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + srl_r8: | + let b = ctx.cpu.r.<%= dst.downcase %>, + c = (b & 0x01), + v = (b >> 1) & 0x7F; + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + (c ? 0x10 : 0) + ); + ctx.cpu.r.<%= dst.downcase %> = v; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + srl_rp16: | + let addr = ( + ((ctx.cpu.r.<%= dst.downcase[1] %> & 0xFF) << 8) + + (ctx.cpu.r.<%= dst.downcase[2] %> & 0xFF) + ), + b = ctx.mmu.rb(addr), + c = (b & 0x01), + v = (b >> 1) & 0x7F; + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + (c ? 0x10 : 0) + ); + ctx.mmu.wb(addr, v); + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + swap_r8: | + let b = ctx.cpu.r.<%= dst.downcase %>, + v = ((b & 0x0F) << 4) | (b >> 4); + + ctx.cpu.r.f = ( + (v ? 0 : 0x80); + ); + ctx.cpu.r.<%= dst.downcase %> = v; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + swap_rp16: | + let addr = ( + ((ctx.cpu.r.<%= dst.downcase[1] %> & 0xFF) << 8) + + (ctx.cpu.r.<%= dst.downcase[2] %> & 0xFF) + ), + b = ctx.mmu.rb(addr), + v = ((b & 0x0F) << 4) | (b >> 4); + + ctx.cpu.r.f = ( + (v ? 0 : 0x80) | + ); + ctx.mmu.wb(addr, v); + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + cp_r8: | + let v = ( + ctx.cpu.r.<%= dst.downcase %> - + ctx.cpu.r.<%= src.downcase %> + ), hc = ( + // FIXME: probably wrong + (ctx.cpu.r.<%= dst.downcase %> & 0xF) < + (v & 0xF) + ); + + ctx.cpu.r.f = ( + ((v & 0xFF) ? 0 : 0x80) | + 0x40 | + (hc ? 0x20 : 0) | + ((v < 0) ? 0 : 0x10) + ) 0xFF; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + cp_d8: | + let v = ( + ctx.cpu.r.<%= dst.downcase %> - + ctx.mmu.rb(ctx.cpu.r.pc + 1) + ), hc = ( + // FIXME: probably wrong + (ctx.cpu.r.<%= dst.downcase %> & 0xF) < + (v & 0xF) + ); + + ctx.cpu.r.f = ( + ((v & 0xFF) ? 0 : 0x80) | + 0x40 | + (hc ? 0x20 : 0) | + ((v < 0) ? 0 : 0x10) + ) 0xFF; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + cp_rp16: | + let v = ( + ctx.cpu.r.<%= dst.downcase %> - + ctx.mmu.rb( + ((ctx.cpu.r.<%= src.downcase[1] %> & 0xFF) << 8) + + (ctx.cpu.r.<%= src.downcase[2] %> & 0xFF) + ) + ), hc = ( + // FIXME: probably wrong + (ctx.cpu.r.<%= dst.downcase %> & 0xF) < + (v & 0xF) + ); + + ctx.cpu.r.f = ( + ((v & 0xFF) ? 0 : 0x80) | + 0x40 | + (hc ? 0x20 : 0) | + ((v < 0) ? 0 : 0x10) + ) 0xFF; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + nop: | + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + halt: | + ctx.cpu.r.halt = true; + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + stop: | + ctx.cpu.r.stop = true; + // ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + rst: | + // increment pc + // FIXME: is this correct before sp push? + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + + // push pc + ctx.cpu.r.sp = (ctx.cpu.r.sp - 2) & 0xFFFF; + ctx.mmu.ww(ctx.cpu.r.sp, ctx.cpu.r.pc); + + // set pc + ctx.cpu.r.pc = <%= addr %>; + t += <%= time %>; + + push: | + // push hi + ctx.cpu.r.sp = (ctx.cpu.r.sp - 1) & 0xFFFF; + ctx.mmu.wb(ctx.cpu.r.sp, ctx.cpu.r.<%= src.downcase[0] %>); + + // push lo + ctx.cpu.r.sp = (ctx.cpu.r.sp - 1) & 0xFFFF; + ctx.mmu.wb(ctx.cpu.r.sp, ctx.cpu.r.<%= src.downcase[1] %>); + + // set pc + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + pop: | + // pop lo + ctx.cpu.r.<%= dst.downcase[1] %> = ctx.mmu.rb(ctx.cpu.r.sp) & 0xFF; + ctx.cpu.r.sp = (ctx.cpu.r.sp + 1) & 0xFFFF; + + // pop hi + ctx.cpu.r.<%= dst.downcase[0] %> = ctx.mmu.rb(ctx.cpu.r.sp) & 0xFF; + ctx.cpu.r.sp = (ctx.cpu.r.sp + 1) & 0xFFFF; + + // set pc + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + cond_Z: | + ctx.cpu.r.f & 0x80 + + cond_NZ: | + !(ctx.cpu.r.f ^ 0x80) + + cond_C: | + ctx.cpu.r.f & 0x10 + + cond_NC: | + !(ctx.cpu.r.f & 0x10) + + jp_addr: | + ( + (ctx.cpu.r.<%= src.downcase[1] %> & 0xFF) << 8 | + (ctx.cpu.r.<%= src.downcase[2] %> & 0xFF) + ) + + jp_test: | + if (<%= cond %>) { + ctx.cpu.r.pc = ctx.mmu.rw(<%= addr %>) & 0xFFFF; + t += <%= time['t'] %>; + } else { + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time['f'] %>; + } + + jp: | + ctx.cpu.r.pc = ctx.mmu.rw(<%= addr %>) & 0xFFFF; + t += <%= time %>; + + jr_test: | + if (<%= cond %>) { + // treat byte as signed offset + let byte = ctx.mmu.rb(ctx.cpu.pc + 1), + ofs = (byte & 0x08) ? -((~byte + 1) & 0xFF) : byte; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + ofs) & 0xFFFF; + t += <%= time['t'] %>; + } else { + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time['f'] %>; + } + + jr: | + // treat byte as signed offset + let byte = ctx.mmu.rb(ctx.cpu.pc + 1), + ofs = (byte & 0x08) ? -((~byte + 1) & 0xFF) : byte; + + ctx.cpu.r.pc = (ctx.cpu.r.pc + ofs) & 0xFFFF; + t += <%= time %>; + + call_test: | + // calc next instruction + let next_inst = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + + if (<%= cond %>) { + // calc addr + let addr = ( + ((ctx.mmu.rb(ctx.cpu.r.pc + 1) & 0xFF) << 8) & | + (ctx.mmu.rb(ctx.cpu.r.pc + 2) & 0xFF) + ); + + // push hi pc byte + ctx.cpu.r.sp = (ctx.cpu.r.sp - 1) & 0xFFFF; + ctx.mmu.wb(ctx.cpu.r.sp, (next_inst >> 8) & 0xFF); + + // push lo pc byte + ctx.cpu.r.sp = (ctx.cpu.r.sp - 1) & 0xFFFF; + ctx.mmu.wb(ctx.cpu.r.sp, next_inst & 0xFF); + + // set pc, inc time + ctx.cpu.r.pc = addr; + t += <%= time['t'] %>; + } else { + // set pc, inc time + ctx.cpu.r.pc = next_inst; + t += <%= time['f'] %>; + } + + call: | + // calc next instruction + let next_inst = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + + // calc addr + let addr = ( + ((ctx.mmu.rb(ctx.cpu.r.pc + 1) & 0xFF) << 8) & | + (ctx.mmu.rb(ctx.cpu.r.pc + 2) & 0xFF) + ); + + // push hi pc byte + ctx.cpu.r.sp = (ctx.cpu.r.sp - 1) & 0xFFFF; + ctx.mmu.wb(ctx.cpu.r.sp, (next_inst >> 8) & 0xFF); + + // push lo pc byte + ctx.cpu.r.sp = (ctx.cpu.r.sp - 1) & 0xFFFF; + ctx.mmu.wb(ctx.cpu.r.sp, next_inst & 0xFF); + + // set pc, inc time + ctx.cpu.r.pc = addr; + t += <%= time %>; + + ret_test: | + if (<%= cond %>) { + // pop lo + let lo = ctx.mmu.rb(ctx.cpu.r.sp); + ctx.cpu.r.sp = (ctx.cpu.r.sp + 1) & 0xFFFF; + + // pop hi + let hi = ctx.mmu.rb(ctx.cpu.r.sp); + ctx.cpu.r.sp = (ctx.cpu.r.sp + 1) & 0xFFFF; + + // set pc, inc time + ctx.cpu.r.pc = ((hi & 0xFF) << 8) | (lo & 0xFF); + t += <%= time['t'] %>; + } else { + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time['f'] %>; + } + + ret: | + // pop lo + let lo = ctx.mmu.rb(ctx.cpu.r.sp); + ctx.cpu.r.sp = (ctx.cpu.r.sp + 1) & 0xFFFF; + + // pop hi + let hi = ctx.mmu.rb(ctx.cpu.r.sp); + ctx.cpu.r.sp = (ctx.cpu.r.sp + 1) & 0xFFFF; + + // set pc, inc time + ctx.cpu.r.pc = ((hi & 0xFF) << 8) | (lo & 0xFF); + t += <%= time %>; + + reti: | + // enable interrupts + ctx.cpu.r.i = true; + + /// rest is ret + + ei: | + // enable interrupts + ctx.cpu.r.i = true; + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + di: | + // disable interrupts + ctx.cpu.r.i = false; + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + scf: | + ctx.cpu.r.f = ( + (ctx.cpu.r.f & 0x80) | + 0x10 + ); + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + ccf: | + ctx.cpu.r.f = ( + (ctx.cpu.r.f & 0x80) | + (ctx.cpu.r.f & 0x10 ? 0 : 0x10) + ); + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + cpl: | + // complement a + ctx.cpu.r.a = (~ctx.cpu.r.a) & 0xFF; + + // set flags + ctx.cpu.r.f = ( + (ctx.cpu.r.f & 0x80) | + 0x40 | + 0x20 | + (ctx.cpu.r.f & 0x10) + ); + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + ldh_a_a8: | + ctx.cpu.r.a = ctx.mmu.rb(0xFF00 | ctx.mmu.rb(ctx.cpu.r.pc + 1)); + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + ldh_a8_a: | + ctx.mmu.wb(0xFF00 | ctx.mmu.rb(ctx.cpu.r.pc + 1), ctx.cpu.r.a); + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; + + daa: | + // from http://datasheets.chipdb.org/Zilog/Z80/z80-documented-0.90.pdf + // and http://forums.nesdev.com/viewtopic.php?t=9088 + let v = ctx.cpu.r.a; + let ofs = ( + (((ctx.cpu.r.f & 0x10) || ((ctx.cpu.r.a >> 4) > 9)) ? 0x60 : 0) + + (((ctx.cpu.r.f & 0x20) || ((ctx.cpu.r.a & 0xF) > 9)) ? 0x06 : 0) + ); + + if (ctx.cpu.r.f & 0x40) { + v -= ofs; + } else { + v += ofs; + } + + // set flags + ctx.cpu.r.f = ( + (v & 0xFF ? 0 : 0x80) | + (ctx.cpu.r.f & 0x40) | + (cf ? 0x10 : 0) + ); + + // update a + ctx.cpu.r.a = v & 0xFF; + + // set pc, inc time + ctx.cpu.r.pc = (ctx.cpu.r.pc + <%= len %>) & 0xFFFF; + t += <%= time %>; -- cgit v1.2.3