// File: /workspace/github_cpp_makefile_star2_O1/rockytriton[P]dreamsys_emu_gb/src/op_handler.cpp
// Function: dsemu::cpu::handleLD(dsemu::cpu::OpCode const&)
int handleLD(const OpCode &op) {
    RegParamType srcType = RegParamType::RPTHi;
    RegParamType dstType;

    Register *src;
    Register *dst;

    ushort srcValue = 0;
    ushort dstValue = 0;

    PTM::iterator dit = paramTypeMap.find(op.params[0]);
    PTM::iterator sit = paramTypeMap.find(op.params[1]);

    if (sit == paramTypeMap.end()) {
        if (op.params[1] == N) {
            srcValue = bus::read(regPC + 1);
        } else if (op.params[1] == NN) {
            srcValue = bus::read(regPC + 1);
            srcValue |= bus::read(regPC + 2) << 8;

            if (srcValue == 0x1200 || srcValue == 0x0012) {
                cout << "LDing ... " << Short(srcValue) << endl;
                //cpuSpeed = 500;
            }

        } else {
            cout << "Unknown LD Source Type " << endl;
            exit(-1);
        }
    } else {
        src = sit->second.first;
        srcType = sit->second.second;

        switch(srcType) {
            case RPT16: {
                ushort *p = (ushort *)src;
                srcValue = *p;
            } break;
            case RPTHi: {
                srcValue = src->hi;
            } break;
            case RPTLo: {
                srcValue = src->lo;
            } break;
        }
    }

    if (dit == paramTypeMap.end()) {
        dst = nullptr;
        dstType = RegParamType::RPT16;

        if (op.params[0] == N) {
            //
            //exit(-1);
            dstValue = bus::read(regPC + 1);
        } else if (op.params[0] == NN){
            //
            //exit(-1);
            dstValue = bus::read(regPC + 1);
            dstValue |= bus::read(regPC + 2) << 8;
            
        } else {
            cout << "Unknown LD Dest Type " << endl;
            exit(-1);
        }
    } else {
        dst = dit->second.first;
        dstType = dit->second.second;

        switch(dstType) {
            case RPT16: {
                ushort *p = (ushort *)dst;
                dstValue = *p;
            } break;
            case RPTHi: {
                dstValue = dst->hi;
            } break;
            case RPTLo: {
                dstValue = dst->lo;
            } break;
        }
    }

    switch(op.mode) {
        case ATypeRA: {

            ushort addr = getAddrValue(op.params[0], dstValue);

            if (srcType == RPT16) {
                bus::write(addr, srcValue);
            } else {
                bus::write(addr, (byte)srcValue);
            }
        }
            break;
        case ATypeAR: {
            ushort addr = getAddrValue(op.params[1], srcValue);

            if (dstType == RPTLo) {
                dst->lo = bus::read(addr); ;
            } else if (dstType == RPTHi) {
                dst->hi = bus::read(addr); ;
            } else {
                *((ushort *)dst) = bus::read(addr); ;
            }
            
            break;
        } break;
        case ATypeRR:
        case ATypeIR:
            {
                if (dstType == RPTLo) {
                    dst->lo = srcValue;
                } else if (dstType == RPTHi) {
                    dst->hi = srcValue;
                } else {
                    *((ushort *)dst) = srcValue;
                }
            } break;

        case ATypeSP:
        {
            if (op.params[0] == HL) {
                char i = (char)bus::read(regPC + 1);
                setReg16Value(regHL, getReg16Value(regSP) + i);

                setFlag(FlagN, 0);
                setFlag(FlagZ, 0);
                setFlag(FlagC, ((getReg16Value(regSP)+i)&0xFF) < (getReg16Value(regSP)&0xFF));
                setFlag(FlagH, ((getReg16Value(regSP)+i)&0xF) < (getReg16Value(regSP)&0xF));
                
            } else {
                setReg16Value(regSP, getReg16Value(regHL));
            }
        } break;

        default:
            cout << "INVALID OP FLAG: " << dstValue << endl;
            exit(-1);
            return 0;
            
    }
    return 0;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x299fd(%rip), %rcx     # 0x385f8
leaq 0x299ee(%rip), %rax     # 0x385f0
movq %rax, %rdx
testq %rcx, %rcx
je 0xec2f
movl 0x1c(%rbx), %esi
leaq 0x299dc(%rip), %rdx     # 0x385f0
movq %rcx, %rdi
xorl %r8d, %r8d
cmpl %esi, 0x20(%rdi)
setl %r8b
cmovgeq %rdi, %rdx
movq 0x10(%rdi,%r8,8), %rdi
testq %rdi, %rdi
jne 0xec17
movq %rax, %r12
cmpq %rax, %rdx
je 0xec48
movl 0x1c(%rbx), %esi
cmpl 0x20(%rdx), %esi
leaq 0x299ac(%rip), %r12     # 0x385f0
cmovgeq %rdx, %r12
movq %rax, %rdx
testq %rcx, %rcx
je 0xec71
movl 0x20(%rbx), %esi
leaq 0x29996(%rip), %rdx     # 0x385f0
xorl %edi, %edi
cmpl %esi, 0x20(%rcx)
setl %dil
cmovgeq %rcx, %rdx
movq 0x10(%rcx,%rdi,8), %rcx
testq %rcx, %rcx
jne 0xec5a
movq %rax, %rcx
cmpq %rax, %rdx
je 0xec8a
movl 0x20(%rbx), %ecx
cmpl 0x20(%rdx), %ecx
leaq 0x2996a(%rip), %rcx     # 0x385f0
cmovgeq %rdx, %rcx
cmpq %rax, %rcx
je 0xecbf
movq 0x28(%rcx), %rax
movl 0x30(%rcx), %r13d
cmpl $0x2, %r13d
je 0xee0b
cmpl $0x1, %r13d
je 0xee05
testl %r13d, %r13d
jne 0xee16
movzwl (%rax), %edx
xorl %r13d, %r13d
jmp 0xee18
movl 0x20(%rbx), %eax
cmpl $0xd, %eax
je 0xecec
cmpl $0xc, %eax
jne 0xf07f
leaq 0x9827(%rip), %rax      # 0x184fe
movzwl (%rax), %eax
incl %eax
movzwl %ax, %edi
callq 0xb94c
movzbl %al, %edx
jmp 0xee0e
leaq 0x980b(%rip), %r14      # 0x184fe
movzwl (%r14), %edi
incl %edi
movl $0xffff, %r15d          # imm = 0xFFFF
andl %r15d, %edi
callq 0xb94c
movl %eax, %ebp
movzwl (%r14), %edi
addl $0x2, %edi
andl %r15d, %edi
callq 0xb94c
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %edx
orl %eax, %edx
movl %edx, %eax
andl %r15d, %eax
movl $0x1, %r13d
cmpl $0x1200, %eax           # imm = 0x1200
je 0xed3f
cmpl $0x12, %eax
jne 0xee18
movl %edx, %ebp
movq 0x9288(%rip), %r14      # 0x17fd0
leaq 0x469d(%rip), %rsi      # 0x133ec
movl $0xa, %edx
movq %r14, %rdi
callq 0x3300
movq (%r14), %rax
movq -0x18(%rax), %rcx
movl 0x18(%r14,%rcx), %edx
andl $-0x4b, %edx
orl $0x8, %edx
movl %edx, 0x18(%r14,%rcx)
movq -0x18(%rax), %rax
leaq (%r14,%rax), %r15
cmpb $0x0, 0xe1(%r14,%rax)
jne 0xeda2
movq %r15, %rdi
movl $0x20, %esi
callq 0x3280
movb %al, 0xe0(%r15)
movb $0x1, 0xe1(%r15)
movb $0x30, 0xe0(%r15)
movq (%r14), %rax
movq -0x18(%rax), %rax
movq $0x4, 0x10(%r14,%rax)
movzwl %bp, %esi
movq %r14, %rdi
callq 0x3190
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x31a0
movl %ebp, %edx
jmp 0xee18
movzbl 0x1(%rax), %edx
jmp 0xee0e
movzbl (%rax), %edx
movl $0x1, %r13d
jmp 0xee18
xorl %edx, %edx
leaq 0x297d1(%rip), %rax     # 0x385f0
cmpq %rax, %r12
je 0xee51
movq 0x28(%r12), %r14
movl 0x30(%r12), %r15d
cmpl $0x2, %r15d
je 0xeeda
cmpl $0x1, %r15d
je 0xeecd
testl %r15d, %r15d
jne 0xeee6
movzwl (%r14), %ebp
jmp 0xeec8
movl 0x1c(%rbx), %eax
cmpl $0xd, %eax
je 0xee87
cmpl $0xc, %eax
jne 0xf08f
movl %edx, %r12d
leaq 0x9692(%rip), %rax      # 0x184fe
movzwl (%rax), %eax
incl %eax
movzwl %ax, %edi
callq 0xb94c
movzbl %al, %ebp
xorl %r14d, %r14d
xorl %r15d, %r15d
movl %r12d, %edx
jmp 0xeee8
leaq 0x9670(%rip), %r14      # 0x184fe
movzwl (%r14), %edi
incl %edi
movl $0xffff, %r15d          # imm = 0xFFFF
andl %r15d, %edi
movl %edx, %r12d
callq 0xb94c
movl %eax, %ebp
movzwl (%r14), %edi
addl $0x2, %edi
andl %r15d, %edi
callq 0xb94c
movl %r12d, %edx
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ebp
orl %eax, %ebp
xorl %r14d, %r14d
xorl %r15d, %r15d
jmp 0xeee8
movzbl 0x1(%r14), %ebp
movl $0x1, %r15d
jmp 0xeee8
movzbl (%r14), %ebp
movl $0x2, %r15d
jmp 0xeee8
xorl %ebp, %ebp
movl 0x18(%rbx), %eax
cmpl $0x4, %eax
jg 0xef14
leal -0x1(%rax), %ecx
cmpl $0x2, %ecx
jae 0xef4a
cmpl $0x1, %r15d
je 0xf011
cmpl $0x2, %r15d
jne 0xf017
movb %dl, (%r14)
jmp 0xf04e
cmpl $0xd, %eax
je 0xef82
cmpl $0x5, %eax
jne 0xf05f
movl %edx, %r14d
movl 0x1c(%rbx), %edi
movswl %bp, %esi
callq 0xeb78
testl %r13d, %r13d
je 0xf033
movzbl %r14b, %esi
movzwl %ax, %edi
callq 0xb9cd
jmp 0xf04e
cmpl $0x3, %eax
jne 0xf05f
movl 0x20(%rbx), %edi
movswl %dx, %esi
callq 0xeb78
movzwl %ax, %edi
callq 0xb94c
cmpl $0x1, %r15d
je 0xf041
cmpl $0x2, %r15d
jne 0xf047
movb %al, (%r14)
jmp 0xf04e
cmpl $0x9, 0x1c(%rbx)
jne 0xf01d
leaq 0x956b(%rip), %rax      # 0x184fe
movzwl (%rax), %eax
incl %eax
movzwl %ax, %edi
callq 0xb94c
leaq 0x9555(%rip), %rcx      # 0x184fc
movzwl (%rcx), %ecx
movzbl %al, %eax
movsbl %al, %esi
addl %ecx, %esi
leaq 0x9537(%rip), %rdx      # 0x184f0
movb (%rdx), %dil
addl %ecx, %eax
movl $0xff, %r8d
movl %eax, %r9d
andl %r8d, %r9d
andl %ecx, %r8d
andb $0x2f, %dil
cmpl %r8d, %r9d
leaq 0x951b(%rip), %r8       # 0x184f6
leal 0x10(%rdi), %r9d
movzbl %dil, %edi
movzbl %r9b, %r9d
cmovael %edi, %r9d
movw %si, (%r8)
andl $0xf, %eax
andl $0xf, %ecx
movl %r9d, %esi
andb $0x1f, %sil
orb $0x20, %r9b
cmpl %ecx, %eax
movzbl %r9b, %eax
movzbl %sil, %ecx
cmovbl %eax, %ecx
movb %cl, (%rdx)
jmp 0xf04e
movb %dl, 0x1(%r14)
jmp 0xf04e
movw %dx, (%r14)
jmp 0xf04e
leaq 0x94d2(%rip), %rax      # 0x184f6
movzwl (%rax), %eax
leaq 0x94ce(%rip), %rcx      # 0x184fc
movw %ax, (%rcx)
jmp 0xf04e
movzwl %ax, %edi
movzwl %r14w, %esi
callq 0xb9a9
jmp 0xf04e
movb %al, 0x1(%r14)
jmp 0xf04e
movzbl %al, %eax
movw %ax, (%r14)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8f6a(%rip), %rdi      # 0x17fd0
leaq 0x43b8(%rip), %rsi      # 0x13425
callq 0x3290
movzwl %bp, %esi
movq %rax, %rdi
callq 0x33f0
jmp 0xf0a2
movq 0x8f4a(%rip), %rdi      # 0x17fd0
leaq 0x436a(%rip), %rsi      # 0x133f7
jmp 0xf09d
movq 0x8f3a(%rip), %rdi      # 0x17fd0
leaq 0x4372(%rip), %rsi      # 0x1340f
callq 0x3290
movq %rax, %rdi
callq 0x3150
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3310