对比以下两个指令集的差异，要求不能有缺漏，要逐一指出：
指令集1：（正确集合）
对比以下两个指令集的差异，要求不能有缺漏，要逐一指出：
指令集1：（正确集合）

static void proc_none(cpu_context *ctx) {
    printf("INVALID INSTRUCTION!\n");
    exit(-7);
}

static void proc_nop(cpu_context *ctx) {

}

reg_type rt_lookup[] = {
    RT_B,
    RT_C,
    RT_D,
    RT_E,
    RT_H,
    RT_L,
    RT_HL,
    RT_A
};

reg_type decode_reg(u8 reg) {
    if (reg > 0b111) {
        return RT_NONE;
    }

    return rt_lookup[reg];
}

static void proc_cb(cpu_context *ctx) {
    u8 op = ctx->fetched_data;
    reg_type reg = decode_reg(op & 0b111);
    u8 bit = (op >> 3) & 0b111;
    u8 bit_op = (op >> 6) & 0b11;
    u8 reg_val = cpu_read_reg8(reg);

    emu_cycles(1);

    if (reg == RT_HL) {
        emu_cycles(2);
    }

    switch(bit_op) {
        case 1:
            //BIT
            cpu_set_flags(ctx, !(reg_val & (1 << bit)), 0, 1, -1);
            return;

        case 2:
            //RST
            reg_val &= ~(1 << bit);
            cpu_set_reg8(reg, reg_val);
            return;

        case 3:
            //SET
            reg_val |= (1 << bit);
            cpu_set_reg8(reg, reg_val);
            return;
    }

    bool flagC = CPU_FLAG_C;

    switch(bit) {
        case 0: {
            //RLC
            bool setC = false;
            u8 result = (reg_val << 1) & 0xFF;

            if ((reg_val & (1 << 7)) != 0) {
                result |= 1;
                setC = true;
            }

            cpu_set_reg8(reg, result);
            cpu_set_flags(ctx, result == 0, false, false, setC);
        } return;

        case 1: {
            //RRC
            u8 old = reg_val;
            reg_val >>= 1;
            reg_val |= (old << 7);

            cpu_set_reg8(reg, reg_val);
            cpu_set_flags(ctx, !reg_val, false, false, old & 1);
        } return;

        case 2: {
            //RL
            u8 old = reg_val;
            reg_val <<= 1;
            reg_val |= flagC;

            cpu_set_reg8(reg, reg_val);
            cpu_set_flags(ctx, !reg_val, false, false, !!(old & 0x80));
        } return;

        case 3: {
            //RR
            u8 old = reg_val;
            reg_val >>= 1;

            reg_val |= (flagC << 7);

            cpu_set_reg8(reg, reg_val);
            cpu_set_flags(ctx, !reg_val, false, false, old & 1);
        } return;

        case 4: {
            //SLA
            u8 old = reg_val;
            reg_val <<= 1;

            cpu_set_reg8(reg, reg_val);
            cpu_set_flags(ctx, !reg_val, false, false, !!(old & 0x80));
        } return;

        case 5: {
            //SRA
            u8 u = (int8_t)reg_val >> 1;
            cpu_set_reg8(reg, u);
            cpu_set_flags(ctx, !u, 0, 0, reg_val & 1);
        } return;

        case 6: {
            //SWAP
            reg_val = ((reg_val & 0xF0) >> 4) | ((reg_val & 0xF) << 4);
            cpu_set_reg8(reg, reg_val);
            cpu_set_flags(ctx, reg_val == 0, false, false, false);
        } return;

        case 7: {
            //SRL
            u8 u = reg_val >> 1;
            cpu_set_reg8(reg, u);
            cpu_set_flags(ctx, !u, 0, 0, reg_val & 1);
        } return;
    }

    fprintf(stderr, "ERROR: INVALID CB: %02X", op);
    NO_IMPL
}

static void proc_rlca(cpu_context *ctx) {
    u8 u = ctx->regs.a;
    bool c = (u >> 7) & 1;
    u = (u << 1) | c;
    ctx->regs.a = u;

    cpu_set_flags(ctx, 0, 0, 0, c);
}

static void proc_rrca(cpu_context *ctx) {
    u8 b = ctx->regs.a & 1;
    ctx->regs.a >>= 1;
    ctx->regs.a |= (b << 7);

    cpu_set_flags(ctx, 0, 0, 0, b);
}


static void proc_rla(cpu_context *ctx) {
    u8 u = ctx->regs.a;
    u8 cf = CPU_FLAG_C;
    u8 c = (u >> 7) & 1;

    ctx->regs.a = (u << 1) | cf;
    cpu_set_flags(ctx, 0, 0, 0, c);
}

static void proc_stop(cpu_context *ctx) {
    fprintf(stderr, "STOPPING!\n");
}

static void proc_daa(cpu_context *ctx) {
    u8 u = 0;
    int fc = 0;

    if (CPU_FLAG_H || (!CPU_FLAG_N && (ctx->regs.a & 0xF) > 9)) {
        u = 6;
    }

    if (CPU_FLAG_C || (!CPU_FLAG_N && ctx->regs.a > 0x99)) {
        u |= 0x60;
        fc = 1;
    }

    ctx->regs.a += CPU_FLAG_N ? -u : u;

    cpu_set_flags(ctx, ctx->regs.a == 0, -1, 0, fc);
}

static void proc_cpl(cpu_context *ctx) {
    ctx->regs.a = ~ctx->regs.a;
    cpu_set_flags(ctx, -1, 1, 1, -1);
}

static void proc_scf(cpu_context *ctx) {
    cpu_set_flags(ctx, -1, 0, 0, 1);
}

static void proc_ccf(cpu_context *ctx) {
    cpu_set_flags(ctx, -1, 0, 0, CPU_FLAG_C ^ 1);
}

static void proc_halt(cpu_context *ctx) {
    ctx->halted = true;
}

static void proc_rra(cpu_context *ctx) {
    u8 carry = CPU_FLAG_C;
    u8 new_c = ctx->regs.a & 1;

    ctx->regs.a >>= 1;
    ctx->regs.a |= (carry << 7);

    cpu_set_flags(ctx, 0, 0, 0, new_c);
}

static void proc_and(cpu_context *ctx) {
    ctx->regs.a &= ctx->fetched_data;
    cpu_set_flags(ctx, ctx->regs.a == 0, 0, 1, 0);
}

static void proc_xor(cpu_context *ctx) {
    ctx->regs.a ^= ctx->fetched_data & 0xFF;
    cpu_set_flags(ctx, ctx->regs.a == 0, 0, 0, 0);
}

static void proc_or(cpu_context *ctx) {
    ctx->regs.a |= ctx->fetched_data & 0xFF;
    cpu_set_flags(ctx, ctx->regs.a == 0, 0, 0, 0);
}

static void proc_cp(cpu_context *ctx) {
    int n = (int)ctx->regs.a - (int)ctx->fetched_data;

    cpu_set_flags(ctx, n == 0, 1, 
        ((int)ctx->regs.a & 0x0F) - ((int)ctx->fetched_data & 0x0F) < 0, n < 0);
}

static void proc_di(cpu_context *ctx) {
    ctx->int_master_enabled = false;
}

static void proc_ei(cpu_context *ctx) {
    ctx->enabling_ime = true;
}

static bool is_16_bit(reg_type rt) {
    return rt >= RT_AF;
}

static void proc_ld(cpu_context *ctx) {
    if (ctx->dest_is_mem) {
        //LD (BC), A for instance...

        if (is_16_bit(ctx->cur_inst->reg_2)) {
            //if 16 bit register...
            emu_cycles(1);
            bus_write16(ctx->mem_dest, ctx->fetched_data);
        } else {
            bus_write(ctx->mem_dest, ctx->fetched_data);
        }

        emu_cycles(1);

        return;
    }

    if (ctx->cur_inst->mode == AM_HL_SPR) {
        u8 hflag = (cpu_read_reg(ctx->cur_inst->reg_2) & 0xF) + 
            (ctx->fetched_data & 0xF) >= 0x10;

        u8 cflag = (cpu_read_reg(ctx->cur_inst->reg_2) & 0xFF) + 
            (ctx->fetched_data & 0xFF) >= 0x100;

        cpu_set_flags(ctx, 0, 0, hflag, cflag);
        cpu_set_reg(ctx->cur_inst->reg_1, 
            cpu_read_reg(ctx->cur_inst->reg_2) + (int8_t)ctx->fetched_data);

        return;
    }

    cpu_set_reg(ctx->cur_inst->reg_1, ctx->fetched_data);
}

static void proc_ldh(cpu_context *ctx) {
    if (ctx->cur_inst->reg_1 == RT_A) {
        cpu_set_reg(ctx->cur_inst->reg_1, bus_read(0xFF00 | ctx->fetched_data));
    } else {
        bus_write(ctx->mem_dest, ctx->regs.a);
    }

    emu_cycles(1);
}


static bool check_cond(cpu_context *ctx) {
    bool z = CPU_FLAG_Z;
    bool c = CPU_FLAG_C;

    switch(ctx->cur_inst->cond) {
        case CT_NONE: return true;
        case CT_C: return c;
        case CT_NC: return !c;
        case CT_Z: return z;
        case CT_NZ: return !z;
    }

    return false;
}

static void goto_addr(cpu_context *ctx, u16 addr, bool pushpc) {
    if (check_cond(ctx)) {
        if (pushpc) {
            emu_cycles(2);
            stack_push16(ctx->regs.pc);
        }

        ctx->regs.pc = addr;
        emu_cycles(1);
    }
}

static void proc_jp(cpu_context *ctx) {
    goto_addr(ctx, ctx->fetched_data, false);
}

static void proc_jr(cpu_context *ctx) {
    int8_t rel = (int8_t)(ctx->fetched_data & 0xFF);
    u16 addr = ctx->regs.pc + rel;
    goto_addr(ctx, addr, false);
}

static void proc_call(cpu_context *ctx) {
    goto_addr(ctx, ctx->fetched_data, true);
}

static void proc_rst(cpu_context *ctx) {
    goto_addr(ctx, ctx->cur_inst->param, true);
}

static void proc_ret(cpu_context *ctx) {
    if (ctx->cur_inst->cond != CT_NONE) {
        emu_cycles(1);
    }

    if (check_cond(ctx)) {
        u16 lo = stack_pop();
        emu_cycles(1);
        u16 hi = stack_pop();
        emu_cycles(1);

        u16 n = (hi << 8) | lo;
        ctx->regs.pc = n;

        emu_cycles(1);
    }
}

static void proc_reti(cpu_context *ctx) {
    ctx->int_master_enabled = true;
    proc_ret(ctx);
}

static void proc_pop(cpu_context *ctx) {
    u16 lo = stack_pop();
    emu_cycles(1);
    u16 hi = stack_pop();
    emu_cycles(1);

    u16 n = (hi << 8) | lo;

    cpu_set_reg(ctx->cur_inst->reg_1, n);

    if (ctx->cur_inst->reg_1 == RT_AF) {
        cpu_set_reg(ctx->cur_inst->reg_1, n & 0xFFF0);
    }
}

static void proc_push(cpu_context *ctx) {
    u16 hi = (cpu_read_reg(ctx->cur_inst->reg_1) >> 8) & 0xFF;
    emu_cycles(1);
    stack_push(hi);

    u16 lo = cpu_read_reg(ctx->cur_inst->reg_1) & 0xFF;
    emu_cycles(1);
    stack_push(lo);
    
    emu_cycles(1);
}

static void proc_inc(cpu_context *ctx) {
    u16 val = cpu_read_reg(ctx->cur_inst->reg_1) + 1;

    if (is_16_bit(ctx->cur_inst->reg_1)) {
        emu_cycles(1);
    }

    if (ctx->cur_inst->reg_1 == RT_HL && ctx->cur_inst->mode == AM_MR) {
        val = bus_read(cpu_read_reg(RT_HL)) + 1;
        val &= 0xFF;
        bus_write(cpu_read_reg(RT_HL), val);
    } else {
        cpu_set_reg(ctx->cur_inst->reg_1, val);
        val = cpu_read_reg(ctx->cur_inst->reg_1);
    }

    if ((ctx->cur_opcode & 0x03) == 0x03) {
        return;
    }

    cpu_set_flags(ctx, val == 0, 0, (val & 0x0F) == 0, -1);
}

static void proc_dec(cpu_context *ctx) {
    u16 val = cpu_read_reg(ctx->cur_inst->reg_1) - 1;

    if (is_16_bit(ctx->cur_inst->reg_1)) {
        emu_cycles(1);
    }

    if (ctx->cur_inst->reg_1 == RT_HL && ctx->cur_inst->mode == AM_MR) {
        val = bus_read(cpu_read_reg(RT_HL)) - 1;
        bus_write(cpu_read_reg(RT_HL), val);
    } else {
        cpu_set_reg(ctx->cur_inst->reg_1, val);
        val = cpu_read_reg(ctx->cur_inst->reg_1);
    }

    if ((ctx->cur_opcode & 0x0B) == 0x0B) {
        return;
    }

    cpu_set_flags(ctx, val == 0, 1, (val & 0x0F) == 0x0F, -1);
}

static void proc_sub(cpu_context *ctx) {
    u16 val = cpu_read_reg(ctx->cur_inst->reg_1) - ctx->fetched_data;

    int z = val == 0;
    int h = ((int)cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) - ((int)ctx->fetched_data & 0xF) < 0;
    int c = ((int)cpu_read_reg(ctx->cur_inst->reg_1)) - ((int)ctx->fetched_data) < 0;

    cpu_set_reg(ctx->cur_inst->reg_1, val);
    cpu_set_flags(ctx, z, 1, h, c);
}

static void proc_sbc(cpu_context *ctx) {
    u8 val = ctx->fetched_data + CPU_FLAG_C;

    int z = cpu_read_reg(ctx->cur_inst->reg_1) - val == 0;

    int h = ((int)cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) 
        - ((int)ctx->fetched_data & 0xF) - ((int)CPU_FLAG_C) < 0;
    int c = ((int)cpu_read_reg(ctx->cur_inst->reg_1)) 
        - ((int)ctx->fetched_data) - ((int)CPU_FLAG_C) < 0;

    cpu_set_reg(ctx->cur_inst->reg_1, cpu_read_reg(ctx->cur_inst->reg_1) - val);
    cpu_set_flags(ctx, z, 1, h, c);
}

static void proc_adc(cpu_context *ctx) {
    u16 u = ctx->fetched_data;
    u16 a = ctx->regs.a;
    u16 c = CPU_FLAG_C;

    ctx->regs.a = (a + u + c) & 0xFF;

    cpu_set_flags(ctx, ctx->regs.a == 0, 0, 
        (a & 0xF) + (u & 0xF) + c > 0xF,
        a + u + c > 0xFF);
}

static void proc_add(cpu_context *ctx) {
    u32 val = cpu_read_reg(ctx->cur_inst->reg_1) + ctx->fetched_data;

    bool is_16bit = is_16_bit(ctx->cur_inst->reg_1);

    if (is_16bit) {
        emu_cycles(1);
    }

    if (ctx->cur_inst->reg_1 == RT_SP) {
        val = cpu_read_reg(ctx->cur_inst->reg_1) + (int8_t)ctx->fetched_data;
    }

    int z = (val & 0xFF) == 0;
    int h = (cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) + (ctx->fetched_data & 0xF) >= 0x10;
    int c = (int)(cpu_read_reg(ctx->cur_inst->reg_1) & 0xFF) + (int)(ctx->fetched_data & 0xFF) >= 0x100;

    if (is_16bit) {
        z = -1;
        h = (cpu_read_reg(ctx->cur_inst->reg_1) & 0xFFF) + (ctx->fetched_data & 0xFFF) >= 0x1000;
        u32 n = ((u32)cpu_read_reg(ctx->cur_inst->reg_1)) + ((u32)ctx->fetched_data);
        c = n >= 0x10000;
    }

    if (ctx->cur_inst->reg_1 == RT_SP) {
        z = 0;
        h = (cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) + (ctx->fetched_data & 0xF) >= 0x10;
        c = (int)(cpu_read_reg(ctx->cur_inst->reg_1) & 0xFF) + (int)(ctx->fetched_data & 0xFF) >= 0x100;
    }

    cpu_set_reg(ctx->cur_inst->reg_1, val & 0xFFFF);
    cpu_set_flags(ctx, z, 0, h, c);
}



指令集2：（待检查集合）
bool CPUContext::checkCond()
{
    bool z = reg_.getZFlag();
    bool c = reg_.getCFlag();
    // std::cout << "zflag!"  << z << std::endl;
    switch (curInst_.cond) {
        case CondType::NONE: return true;
        case CondType::C: return c;
        case CondType::NC: return !c;
        case CondType::Z: return z;
        case CondType::NZ: return !z;
    }

    return false;
}

void CPUContext::nop()
{
    return;
}

void CPUContext::ldh()
{
    if (curInst_.reg1 == RegType::A) {
        reg_.writeReg(curInst_.reg1, bus_.read(0xFF00 | fetchedData_));
    } else {
        bus_.write(0xFF00 | fetchedData_, reg_.a_);
    }

    cycle_.cycle(1);
}

void CPUContext::ld()
{
    if (writeToMemo_) {
        if (is16bitReg(curInst_.reg2)) {
            bus_.write16(memoDest_, fetchedData_);
        } else {
            bus_.write(memoDest_, fetchedData_);
        }
        writeToMemo_ = false;
        return;
    }

    if (curInst_.mode == AddrMode::HL_SPR) {
        uint8_t hFlag = (reg_.readReg(curInst_.reg1) & 0xF) +
            (reg_.readReg(curInst_.reg2) & 0xF) >= 0x10;
        uint8_t cFlag = (reg_.readReg(curInst_.reg1) & 0xFF) +
            (reg_.readReg(curInst_.reg2) & 0xFF) >= 0x100;
        reg_.setFlags(0, 0, hFlag, cFlag);
        reg_.writeReg(curInst_.reg1, reg_.readReg(curInst_.reg2) +
            static_cast<int8_t>(fetchedData_));
        return;
    }
    reg_.writeReg(curInst_.reg1, fetchedData_);
}

void CPUContext::inc()
{
    if (is16bitReg(curInst_.reg1)) {
        // ... emu
    }
    uint16_t val = reg_.readReg(curInst_.reg1) + 1;
    if (writeToMemo_) {
        val = (bus_.read(fetchedData_) & 0xFF) + 1;
        val &= 0xFF;
        bus_.write(fetchedData_, val);
    } else {
        reg_.writeReg(curInst_.reg1, val);
        val = reg_.readReg(curInst_.reg1);
    }

    if ((curOpcode_ & 0x03) == 0x03) {
        return;
    }

    reg_.setFlags(val == 0, 0, (val & 0x0F) == 0, -1);
}

void CPUContext::dec()
{
    if (is16bitReg(curInst_.reg1)) {
        // ... emu
    }
    uint16_t val = reg_.readReg(curInst_.reg1) - 1;
    if (writeToMemo_) {
        val = (bus_.read(fetchedData_) & 0xFF) - 1;
        bus_.write(fetchedData_, val);
    } else {
        reg_.writeReg(curInst_.reg1, val);
    }

    if ((curOpcode_ & 0x0B) == 0x0B) {
        return;
    }
    // std::cout << "dec set flag! val=" << val << std::endl;
    reg_.setFlags(val == 0, 1, (val & 0x0F) == 0x0F, -1);
}

uint8_t CPUContext::stackPop()
{
    return bus_.read(reg_.sp_++);
}

uint16_t CPUContext::stackPop16()
{
    uint16_t lo;
    lo = stackPop();
    uint16_t hi;
    hi = stackPop();
    return (hi << 8) | lo;
}

void CPUContext::stackPush(uint8_t val)
{
    bus_.write(--reg_.sp_, val);
}

void CPUContext::stackPush16(uint16_t val)
{
    stackPush((val >> 8) & 0xFF);
    stackPush(val & 0xFF);
}

void CPUContext::ei()
{
    enablingIME_ = true;
}

void CPUContext::di()
{
    interruptEnabled_ = false;
}

void CPUContext::go2(uint16_t addr, bool pushPC)
{
    if (checkCond()) {
        if (pushPC) {
            stackPush16(reg_.pc_);
        }
        reg_.pc_ = addr;
        // emu_.cycle(1);
    }
}

void CPUContext::jp()
{
    go2(fetchedData_, false);
}

void CPUContext::ret()
{
    if (curInst_.cond != CondType::NONE) {
        // emu_cycle
    }

    if (checkCond()) {
        uint16_t lo;
        lo = stackPop();
        uint16_t hi;
        hi = stackPop();
        uint16_t res = (hi << 8) | lo;
        reg_.pc_ = res;
    }
}

void CPUContext::reti()
{
    interruptEnabled_ = true;
    ret();
}

void CPUContext::call()
{
    go2(fetchedData_, true);
}

void CPUContext::rst()
{
    go2(curInst_.param, true);
}

void CPUContext::jr()
{
    int8_t rel = static_cast<int8_t>(fetchedData_ & 0xFF);
    uint16_t addr = reg_.pc_ + rel;
    go2(addr, false);
}

void CPUContext::pop()
{
    uint16_t lo;
    lo = stackPop();
    uint16_t hi;
    hi = stackPop();
    uint16_t res = (hi << 8) | lo;
    reg_.writeReg(curInst_.reg1,
        res & (curInst_.reg1 == RegType::AF ? 0xFFF0 : 0xFFFF));
}

void CPUContext::push()
{
    uint16_t hi;
    hi = (reg_.readReg(curInst_.reg1) >> 8) & 0xFF;
    stackPush(hi);
    uint16_t lo;
    lo = reg_.readReg(curInst_.reg1) & 0xFF;
    stackPush(lo);
}

void CPUContext::add()
{
    uint16_t val = reg_.readReg(curInst_.reg1) + fetchedData_;
    bool is16bit = is16bitReg(curInst_.reg1);
    if (is16bit) {
        // emu...
    }

    if (curInst_.reg1 == RegType::SP) {
        val = reg_.readReg(curInst_.reg1) + static_cast<int8_t>(fetchedData_);
    }

    int z = (val & 0xFF) == 0;
    int h = ((reg_.readReg(curInst_.reg1) & 0xF) + (fetchedData_ & 0xF)) >= 0x10;
    int c = (static_cast<int>(reg_.readReg(curInst_.reg1) & 0xFF) + static_cast<int>(fetchedData_ & 0xFF)) >= 0x100;
    if (is16bit) {
        z = -1;
        h = ((reg_.readReg(curInst_.reg1) & 0xFFF) + (static_cast<int8_t>(fetchedData_) & 0xFFF)) >= 0x1000;
        c = (static_cast<uint32_t>(reg_.readReg(curInst_.reg1) & 0xFFFF) + static_cast<uint32_t>(fetchedData_ & 0xFFFF)) >= 0x10000;
    }

    if (curInst_.reg1 == RegType::SP) {
        z = 0;
        h = ((reg_.readReg(curInst_.reg1) & 0xF) + (static_cast<int8_t>(fetchedData_) & 0xF)) >= 0x10;
        c = (static_cast<uint16_t>(reg_.readReg(curInst_.reg1) & 0xFF) + static_cast<uint16_t>(fetchedData_ & 0xFF)) >= 0x100;
    }

    reg_.writeReg(curInst_.reg1, val & 0xFFFF);
    reg_.setFlags(z, 0, h, c);
}

void GBCEmu::CPUContext::sub()
{
    uint16_t val = reg_.readReg(curInst_.reg1) - fetchedData_;

    int z = val == 0;
    int h = ((static_cast<int>(reg_.readReg(curInst_.reg1)) & 0xF) - (static_cast<int>(fetchedData_) & 0xF)) < 0;
    int c = (static_cast<int>(reg_.readReg(curInst_.reg1)) - static_cast<int>(fetchedData_)) < 0;

    reg_.writeReg(curInst_.reg1, val);
    reg_.setFlags(z, 1, h, c);
}

void GBCEmu::CPUContext::sbc()
{
    uint8_t val = fetchedData_ + reg_.getCFlag();

    int z = (reg_.readReg(curInst_.reg1) - val) == 0;
    int h = ((static_cast<int>(reg_.readReg(curInst_.reg1)) & 0xF) - (static_cast<int>(fetchedData_) & 0xF) - (static_cast<int>(reg_.getCFlag()))) < 0;
    int c = (static_cast<int>(reg_.readReg(curInst_.reg1)) - static_cast<int>(fetchedData_)) - reg_.getCFlag() < 0;

    reg_.writeReg(curInst_.reg1, (reg_.readReg(curInst_.reg1) - val));
    reg_.setFlags(z, 1, h, c);
}

void GBCEmu::CPUContext::adc()
{
    uint16_t u = fetchedData_;
    uint16_t a = reg_.a_;
    uint16_t c = reg_.getCFlag();

    reg_.a_ = (a + u + c) & 0xFF;
    reg_.setFlags(a == 0, 0, (a & 0xF) + (u & 0xF) + c > 0xF, a + u + c > 0xFF);
}

void CPUContext::and()
{
    reg_.a_ &= fetchedData_;
    reg_.setFlags(reg_.a_ == 0, 0, 1, 0);
}

void CPUContext::xor()
{
    reg_.a_ ^= fetchedData_ & 0xFF;
    reg_.setFlags(reg_.a_ == 0, 0, 0, 0);
}

void CPUContext::or()
{
    reg_.a_ |= fetchedData_ & 0xFF;
    reg_.setFlags(reg_.a_ == 0, 0, 0, 0);
}

void CPUContext::cp()
{
    int n = static_cast<int>(reg_.a_) - static_cast<int>(fetchedData_);
    // std::cout << "n: " << n << "\n"; 
    reg_.setFlags(n == 0, 1, (static_cast<int>(reg_.a_) & 0x0F) - (static_cast<int>(fetchedData_) & 0x0F), n < 0);
}

const RegType regTable[8] = {
    RegType::B,
    RegType::C,
    RegType::D,
    RegType::E,
    RegType::H,
    RegType::L,
    RegType::HL,
    RegType::A,
};

RegType CPUContext::decodeReg(uint8_t reg)
{
    return regTable[reg];
}

void CPUContext::cb()
{
    uint8_t opcode = fetchedData_;
    RegType reg = decodeReg(opcode & 0b111);
    uint8_t bit = (opcode >> 3) & 0b111;
    uint8_t bitOp = (opcode >> 6) & 0b11;
    uint8_t regVal = reg_.readReg(reg);

    cycle_.cycle(1);

    if (reg == RegType::HL) {
        cycle_.cycle(2);
    }

    switch (bitOp) {
        case 1: // BIT
            reg_.setFlags(getBit(regVal, bit) == 0, 0, 1, -1);
            return;
        case 2: // RST
            reg_.writeReg(reg, regVal & ~(1 << bit));
            return;
        case 3: // SET
            reg_.writeReg(reg, regVal | (1 << bit));
            return;
    }

    bool flagC = reg_.getCFlag();
    switch (bitOp) {
        case 0: {// RLC
            uint8_t carry = getBit(regVal, 7);
            uint8_t res = (regVal << 1) | carry & 0xFF;
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 1, -1, carry);
            return;
            }
        case 1: {// RRC
            uint8_t carry = getBit(regVal, 0);
            uint8_t res = (regVal >> 1) | (carry << 7  & 0xFF);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, carry);
            return;
            }
        case 2: {// RL
            uint8_t res = (regVal << 1) | flagC;
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, !!(regVal & 0x80));
            return;
            }
        case 3: {// RR
            uint8_t res = (regVal >> 1) | (flagC << 7);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, regVal & 0x1);
            return;
            }
        case 4: {// SLA
            uint8_t res = (regVal << 1);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, !!(regVal & 0x80));
            return;
            }
        case 5: {// SRA
            uint8_t res = (static_cast<int>(regVal) >> 1);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, regVal & 0x1);
            return;}
        case 6: {// SWAP
            uint8_t res = (regVal >> 4) | ((regVal & 0xF) << 4);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, 0);
            return;
            }
        case 7: {// SRL
            uint8_t res = (regVal >> 1);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, regVal & 0x1);
            return;
            }
    }

    std::cerr << "INVALID CB\n";
    NO_IMPL
}

void CPUContext::rlca()
{
    uint8_t res = reg_.a_;
    bool cFlag = (res >> 7) & 1;
    res = (res << 1) | cFlag;
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, cFlag);
}

void CPUContext::rrca()
{
    uint8_t res = reg_.a_;
    uint8_t lsb = res & 1;
    res = (res >> 1) | (lsb << 7);
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, lsb);
}

void CPUContext::rla()
{
    uint8_t res = reg_.a_;
    bool cFlag = (res >> 7) & 1;
    res = (res << 1) | reg_.getCFlag();
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, cFlag);
}

void CPUContext::rra()
{
    uint8_t res = reg_.a_;
    bool cFlag = res & 1;
    res = (res >> 1) | (reg_.getCFlag() << 7);
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, cFlag);
}

void CPUContext::stop()
{
    std::cerr << "STOP INSTRUCTION!\n";
    exit(0);
}

void CPUContext::daa()
{
    uint8_t res = 0;
    int cFlag = 0;

    if (reg_.getHFlag() || (!reg_.getNFlag() && (reg_.a_ & 0xF) > 9)) {
        res = 6;
    }
    if (reg_.getCFlag() || (!reg_.getNFlag() && reg_.a_ > 0x99)) {
        res |= 0x60;
        cFlag = 1;
    }

    reg_.a_ += reg_.getNFlag() ? -res : res;
    reg_.setFlags(reg_.a_ == 0, -1, 0, cFlag);
}

void CPUContext::cpl()
{
    reg_.a_ = ~reg_.a_;
    reg_.setFlags(-1, 1, 1, -1);
}

void CPUContext::scf()
{
    reg_.setFlags(-1, 0, 0, -1);
}

void CPUContext::ccf()
{
    reg_.setFlags(-1, 0, 0, ~reg_.getCFlag());
}

void CPUContext::halt()
{
    halt_ = true;
}




指令集2：（待检查集合）
bool CPUContext::checkCond()
{
    bool z = reg_.getZFlag();
    bool c = reg_.getCFlag();
    // std::cout << "zflag!"  << z << std::endl;
    switch (curInst_.cond) {
        case CondType::NONE: return true;
        case CondType::C: return c;
        case CondType::NC: return !c;
        case CondType::Z: return z;
        case CondType::NZ: return !z;
    }

    return false;
}

void CPUContext::nop()
{
    return;
}

void CPUContext::ldh()
{
    if (curInst_.reg1 == RegType::A) {
        reg_.writeReg(curInst_.reg1, bus_.read(0xFF00 | fetchedData_));
    } else {
        bus_.write(0xFF00 | fetchedData_, reg_.a_);
    }

    cycle_.cycle(1);
}

void CPUContext::ld()
{
    if (writeToMemo_) {
        if (is16bitReg(curInst_.reg2)) {
            bus_.write16(memoDest_, fetchedData_);
        } else {
            bus_.write(memoDest_, fetchedData_);
        }
        writeToMemo_ = false;
        return;
    }

    if (curInst_.mode == AddrMode::HL_SPR) {
        uint8_t hFlag = (reg_.readReg(curInst_.reg1) & 0xF) +
            (reg_.readReg(curInst_.reg2) & 0xF) >= 0x10;
        uint8_t cFlag = (reg_.readReg(curInst_.reg1) & 0xFF) +
            (reg_.readReg(curInst_.reg2) & 0xFF) >= 0x100;
        reg_.setFlags(0, 0, hFlag, cFlag);
        reg_.writeReg(curInst_.reg1, reg_.readReg(curInst_.reg2) +
            static_cast<int8_t>(fetchedData_));
        return;
    }
    reg_.writeReg(curInst_.reg1, fetchedData_);
}

void CPUContext::inc()
{
    if (is16bitReg(curInst_.reg1)) {
        // ... emu
    }
    uint16_t val = reg_.readReg(curInst_.reg1) + 1;
    if (writeToMemo_) {
        val = (bus_.read(fetchedData_) & 0xFF) + 1;
        val &= 0xFF;
        bus_.write(fetchedData_, val);
    } else {
        reg_.writeReg(curInst_.reg1, val);
        val = reg_.readReg(curInst_.reg1);
    }

    if ((curOpcode_ & 0x03) == 0x03) {
        return;
    }

    reg_.setFlags(val == 0, 0, (val & 0x0F) == 0, -1);
}

void CPUContext::dec()
{
    if (is16bitReg(curInst_.reg1)) {
        // ... emu
    }
    uint16_t val = reg_.readReg(curInst_.reg1) - 1;
    if (writeToMemo_) {
        val = (bus_.read(fetchedData_) & 0xFF) - 1;
        bus_.write(fetchedData_, val);
    } else {
        reg_.writeReg(curInst_.reg1, val);
    }

    if ((curOpcode_ & 0x0B) == 0x0B) {
        return;
    }
    // std::cout << "dec set flag! val=" << val << std::endl;
    reg_.setFlags(val == 0, 1, (val & 0x0F) == 0x0F, -1);
}

uint8_t CPUContext::stackPop()
{
    return bus_.read(reg_.sp_++);
}

uint16_t CPUContext::stackPop16()
{
    uint16_t lo;
    lo = stackPop();
    uint16_t hi;
    hi = stackPop();
    return (hi << 8) | lo;
}

void CPUContext::stackPush(uint8_t val)
{
    bus_.write(--reg_.sp_, val);
}

void CPUContext::stackPush16(uint16_t val)
{
    stackPush((val >> 8) & 0xFF);
    stackPush(val & 0xFF);
}

void CPUContext::ei()
{
    enablingIME_ = true;
}

void CPUContext::di()
{
    interruptEnabled_ = false;
}

void CPUContext::go2(uint16_t addr, bool pushPC)
{
    if (checkCond()) {
        if (pushPC) {
            stackPush16(reg_.pc_);
        }
        reg_.pc_ = addr;
        // emu_.cycle(1);
    }
}

void CPUContext::jp()
{
    go2(fetchedData_, false);
}

void CPUContext::ret()
{
    if (curInst_.cond != CondType::NONE) {
        // emu_cycle
    }

    if (checkCond()) {
        uint16_t lo;
        lo = stackPop();
        uint16_t hi;
        hi = stackPop();
        uint16_t res = (hi << 8) | lo;
        reg_.pc_ = res;
    }
}

void CPUContext::reti()
{
    interruptEnabled_ = true;
    ret();
}

void CPUContext::call()
{
    go2(fetchedData_, true);
}

void CPUContext::rst()
{
    go2(curInst_.param, true);
}

void CPUContext::jr()
{
    int8_t rel = static_cast<int8_t>(fetchedData_ & 0xFF);
    uint16_t addr = reg_.pc_ + rel;
    go2(addr, false);
}

void CPUContext::pop()
{
    uint16_t lo;
    lo = stackPop();
    uint16_t hi;
    hi = stackPop();
    uint16_t res = (hi << 8) | lo;
    reg_.writeReg(curInst_.reg1,
        res & (curInst_.reg1 == RegType::AF ? 0xFFF0 : 0xFFFF));
}

void CPUContext::push()
{
    uint16_t hi;
    hi = (reg_.readReg(curInst_.reg1) >> 8) & 0xFF;
    stackPush(hi);
    uint16_t lo;
    lo = reg_.readReg(curInst_.reg1) & 0xFF;
    stackPush(lo);
}

void CPUContext::add()
{
    uint16_t val = reg_.readReg(curInst_.reg1) + fetchedData_;
    bool is16bit = is16bitReg(curInst_.reg1);
    if (is16bit) {
        // emu...
    }

    if (curInst_.reg1 == RegType::SP) {
        val = reg_.readReg(curInst_.reg1) + static_cast<int8_t>(fetchedData_);
    }

    int z = (val & 0xFF) == 0;
    int h = ((reg_.readReg(curInst_.reg1) & 0xF) + (fetchedData_ & 0xF)) >= 0x10;
    int c = (static_cast<int>(reg_.readReg(curInst_.reg1) & 0xFF) + static_cast<int>(fetchedData_ & 0xFF)) >= 0x100;
    if (is16bit) {
        z = -1;
        h = ((reg_.readReg(curInst_.reg1) & 0xFFF) + (static_cast<int8_t>(fetchedData_) & 0xFFF)) >= 0x1000;
        c = (static_cast<uint32_t>(reg_.readReg(curInst_.reg1) & 0xFFFF) + static_cast<uint32_t>(fetchedData_ & 0xFFFF)) >= 0x10000;
    }

    if (curInst_.reg1 == RegType::SP) {
        z = 0;
        h = ((reg_.readReg(curInst_.reg1) & 0xF) + (static_cast<int8_t>(fetchedData_) & 0xF)) >= 0x10;
        c = (static_cast<uint16_t>(reg_.readReg(curInst_.reg1) & 0xFF) + static_cast<uint16_t>(fetchedData_ & 0xFF)) >= 0x100;
    }

    reg_.writeReg(curInst_.reg1, val & 0xFFFF);
    reg_.setFlags(z, 0, h, c);
}

void GBCEmu::CPUContext::sub()
{
    uint16_t val = reg_.readReg(curInst_.reg1) - fetchedData_;

    int z = val == 0;
    int h = ((static_cast<int>(reg_.readReg(curInst_.reg1)) & 0xF) - (static_cast<int>(fetchedData_) & 0xF)) < 0;
    int c = (static_cast<int>(reg_.readReg(curInst_.reg1)) - static_cast<int>(fetchedData_)) < 0;

    reg_.writeReg(curInst_.reg1, val);
    reg_.setFlags(z, 1, h, c);
}

void GBCEmu::CPUContext::sbc()
{
    uint8_t val = fetchedData_ + reg_.getCFlag();

    int z = (reg_.readReg(curInst_.reg1) - val) == 0;
    int h = ((static_cast<int>(reg_.readReg(curInst_.reg1)) & 0xF) - (static_cast<int>(fetchedData_) & 0xF) - (static_cast<int>(reg_.getCFlag()))) < 0;
    int c = (static_cast<int>(reg_.readReg(curInst_.reg1)) - static_cast<int>(fetchedData_)) - reg_.getCFlag() < 0;

    reg_.writeReg(curInst_.reg1, (reg_.readReg(curInst_.reg1) - val));
    reg_.setFlags(z, 1, h, c);
}

void GBCEmu::CPUContext::adc()
{
    uint16_t u = fetchedData_;
    uint16_t a = reg_.a_;
    uint16_t c = reg_.getCFlag();

    reg_.a_ = (a + u + c) & 0xFF;
    reg_.setFlags(a == 0, 0, (a & 0xF) + (u & 0xF) + c > 0xF, a + u + c > 0xFF);
}

void CPUContext::and()
{
    reg_.a_ &= fetchedData_;
    reg_.setFlags(reg_.a_ == 0, 0, 1, 0);
}

void CPUContext::xor()
{
    reg_.a_ ^= fetchedData_ & 0xFF;
    reg_.setFlags(reg_.a_ == 0, 0, 0, 0);
}

void CPUContext::or()
{
    reg_.a_ |= fetchedData_ & 0xFF;
    reg_.setFlags(reg_.a_ == 0, 0, 0, 0);
}

void CPUContext::cp()
{
    int n = static_cast<int>(reg_.a_) - static_cast<int>(fetchedData_);
    // std::cout << "n: " << n << "\n"; 
    reg_.setFlags(n == 0, 1, (static_cast<int>(reg_.a_) & 0x0F) - (static_cast<int>(fetchedData_) & 0x0F), n < 0);
}

const RegType regTable[8] = {
    RegType::B,
    RegType::C,
    RegType::D,
    RegType::E,
    RegType::H,
    RegType::L,
    RegType::HL,
    RegType::A,
};

RegType CPUContext::decodeReg(uint8_t reg)
{
    return regTable[reg];
}

void CPUContext::cb()
{
    uint8_t opcode = fetchedData_;
    RegType reg = decodeReg(opcode & 0b111);
    uint8_t bit = (opcode >> 3) & 0b111;
    uint8_t bitOp = (opcode >> 6) & 0b11;
    uint8_t regVal = reg_.readReg(reg);

    cycle_.cycle(1);

    if (reg == RegType::HL) {
        cycle_.cycle(2);
    }

    switch (bitOp) {
        case 1: // BIT
            reg_.setFlags(getBit(regVal, bit) == 0, 0, 1, -1);
            return;
        case 2: // RST
            reg_.writeReg(reg, regVal & ~(1 << bit));
            return;
        case 3: // SET
            reg_.writeReg(reg, regVal | (1 << bit));
            return;
    }

    bool flagC = reg_.getCFlag();
    switch (bitOp) {
        case 0: {// RLC
            uint8_t carry = getBit(regVal, 7);
            uint8_t res = (regVal << 1) | carry & 0xFF;
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 1, -1, carry);
            return;
            }
        case 1: {// RRC
            uint8_t carry = getBit(regVal, 0);
            uint8_t res = (regVal >> 1) | (carry << 7  & 0xFF);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, carry);
            return;
            }
        case 2: {// RL
            uint8_t res = (regVal << 1) | flagC;
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, !!(regVal & 0x80));
            return;
            }
        case 3: {// RR
            uint8_t res = (regVal >> 1) | (flagC << 7);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, regVal & 0x1);
            return;
            }
        case 4: {// SLA
            uint8_t res = (regVal << 1);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, !!(regVal & 0x80));
            return;
            }
        case 5: {// SRA
            uint8_t res = (static_cast<int>(regVal) >> 1);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, regVal & 0x1);
            return;}
        case 6: {// SWAP
            uint8_t res = (regVal >> 4) | ((regVal & 0xF) << 4);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, 0);
            return;
            }
        case 7: {// SRL
            uint8_t res = (regVal >> 1);
            reg_.writeReg(reg, res);
            reg_.setFlags(res == 0, 0, 0, regVal & 0x1);
            return;
            }
    }

    std::cerr << "INVALID CB\n";
    NO_IMPL
}

void CPUContext::rlca()
{
    uint8_t res = reg_.a_;
    bool cFlag = (res >> 7) & 1;
    res = (res << 1) | cFlag;
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, cFlag);
}

void CPUContext::rrca()
{
    uint8_t res = reg_.a_;
    uint8_t lsb = res & 1;
    res = (res >> 1) | (lsb << 7);
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, lsb);
}

void CPUContext::rla()
{
    uint8_t res = reg_.a_;
    bool cFlag = (res >> 7) & 1;
    res = (res << 1) | reg_.getCFlag();
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, cFlag);
}

void CPUContext::rra()
{
    uint8_t res = reg_.a_;
    bool cFlag = res & 1;
    res = (res >> 1) | (reg_.getCFlag() << 7);
    reg_.a_ = res;
    reg_.setFlags(0, 0, 0, cFlag);
}

void CPUContext::stop()
{
    std::cerr << "STOP INSTRUCTION!\n";
    exit(0);
}

void CPUContext::daa()
{
    uint8_t res = 0;
    int cFlag = 0;

    if (reg_.getHFlag() || (!reg_.getNFlag() && (reg_.a_ & 0xF) > 9)) {
        res = 6;
    }
    if (reg_.getCFlag() || (!reg_.getNFlag() && reg_.a_ > 0x99)) {
        res |= 0x60;
        cFlag = 1;
    }

    reg_.a_ += reg_.getNFlag() ? -res : res;
    reg_.setFlags(reg_.a_ == 0, -1, 0, cFlag);
}

void CPUContext::cpl()
{
    reg_.a_ = ~reg_.a_;
    reg_.setFlags(-1, 1, 1, -1);
}

void CPUContext::scf()
{
    reg_.setFlags(-1, 0, 0, -1);
}

void CPUContext::ccf()
{
    reg_.setFlags(-1, 0, 0, ~reg_.getCFlag());
}

void CPUContext::halt()
{
    halt_ = true;
}