// File: /workspace/github_cpp_makefile_star2_O3/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 0x29b51(%rip), %rax     # 0x385f8
testq %rax, %rax
je 0xeb50
leaq 0x29b39(%rip), %rcx     # 0x385f0
movl 0x1c(%rbx), %esi
movq %rax, %rdx
xorl %edi, %edi
cmpl %esi, 0x20(%rdx)
setl %dil
cmovgeq %rdx, %rcx
movq 0x10(%rdx,%rdi,8), %rdx
testq %rdx, %rdx
jne 0xeabd
leaq 0x29b15(%rip), %rdx     # 0x385f0
movq %rdx, %r12
cmpq %rdx, %rcx
je 0xeaf1
cmpl 0x20(%rcx), %esi
leaq 0x29b03(%rip), %r12     # 0x385f0
cmovgeq %rcx, %r12
leaq 0x20(%rbx), %rdi
movl 0x20(%rbx), %ecx
xorl %esi, %esi
cmpl %ecx, 0x20(%rax)
setl %sil
cmovgeq %rax, %rdx
movq 0x10(%rax,%rsi,8), %rax
testq %rax, %rax
jne 0xeaf8
leaq 0x29ada(%rip), %rax     # 0x385f0
cmpq %rax, %rdx
je 0xeb5e
cmpl 0x20(%rdx), %ecx
jl 0xeb5e
movq 0x28(%rdx), %rax
movl 0x30(%rdx), %ebp
cmpl $0x2, %ebp
movq %rdi, (%rsp)
je 0xeee5
cmpl $0x1, %ebp
je 0xeedb
testl %ebp, %ebp
jne 0xeeee
movzwl (%rax), %r13d
xorl %ebp, %ebp
jmp 0xeca0
leaq 0x20(%rbx), %rdi
movl 0x20(%rbx), %ecx
leaq 0x29a92(%rip), %r12     # 0x385f0
cmpl $0xd, %ecx
movq %rdi, (%rsp)
je 0xeb92
cmpl $0xc, %ecx
jne 0xeef6
leaq 0x9987(%rip), %rax      # 0x184fe
movzwl (%rax), %eax
incl %eax
movzwl %ax, %edi
callq 0xb94c
movzbl %al, %r13d
movl $0x1, %ebp
jmp 0xeca0
leaq 0x9965(%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, %r13d
orl %eax, %r13d
movl %r13d, %eax
andl %r15d, %eax
movl $0x1, %ebp
cmpl $0x1200, %eax           # imm = 0x1200
je 0xebe6
cmpl $0x12, %eax
jne 0xeca0
movq 0x93e3(%rip), %r14      # 0x17fd0
leaq 0x47f8(%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), %rcx
leaq (%r14,%rcx), %r15
cmpb $0x0, 0xe1(%r14,%rcx)
jne 0xec43
movq %r15, %rdi
movl $0x20, %esi
callq 0x3280
movb $0x1, 0xe1(%r15)
movq (%r14), %rax
movb $0x30, 0xe0(%r15)
movq -0x18(%rax), %rax
movq $0x4, 0x10(%r14,%rax)
movzwl %r13w, %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
leaq 0x29949(%rip), %rax     # 0x385f0
cmpq %rax, %r12
je 0xecd8
movq 0x28(%r12), %r14
movl 0x30(%r12), %r15d
movl %ebp, %r12d
cmpl $0x2, %r15d
je 0xed55
cmpl $0x1, %r15d
je 0xed48
testl %r15d, %r15d
jne 0xed61
movzwl (%r14), %ebp
jmp 0xed43
movl 0x1c(%rbx), %eax
cmpl $0xd, %eax
je 0xed05
cmpl $0xc, %eax
jne 0xef26
movl %ebp, %r12d
leaq 0x980b(%rip), %rax      # 0x184fe
movzwl (%rax), %eax
incl %eax
movzwl %ax, %edi
callq 0xb94c
movzbl %al, %ebp
jmp 0xed40
movl %ebp, %r12d
leaq 0x97ef(%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, %ebp
orl %eax, %ebp
xorl %r14d, %r14d
xorl %r15d, %r15d
jmp 0xed63
movzbl 0x1(%r14), %ebp
movl $0x1, %r15d
jmp 0xed63
movzbl (%r14), %ebp
movl $0x2, %r15d
jmp 0xed63
xorl %ebp, %ebp
movl 0x18(%rbx), %eax
cmpl $0x4, %eax
jg 0xed8f
leal -0x1(%rax), %ecx
cmpl $0x2, %ecx
jae 0xedc2
cmpl $0x1, %r15d
je 0xee8d
cmpl $0x2, %r15d
jne 0xee93
movb %r13b, (%r14)
jmp 0xeeca
cmpl $0xd, %eax
je 0xedfe
cmpl $0x5, %eax
jne 0xef06
movl 0x1c(%rbx), %edi
movswl %bp, %esi
callq 0xea24
testl %r12d, %r12d
je 0xeeaf
movzbl %r13b, %esi
movzwl %ax, %edi
callq 0xb9cd
jmp 0xeeca
cmpl $0x3, %eax
jne 0xef06
movq (%rsp), %rax
movl (%rax), %edi
movswl %r13w, %esi
callq 0xea24
movzwl %ax, %edi
callq 0xb94c
cmpl $0x1, %r15d
je 0xeebd
cmpl $0x2, %r15d
jne 0xeec3
movb %al, (%r14)
jmp 0xeeca
cmpl $0x9, 0x1c(%rbx)
jne 0xee99
leaq 0x96ef(%rip), %rax      # 0x184fe
movzwl (%rax), %eax
incl %eax
movzwl %ax, %edi
callq 0xb94c
leaq 0x96d9(%rip), %rcx      # 0x184fc
movzwl (%rcx), %ecx
movzbl %al, %eax
movsbl %al, %esi
addl %ecx, %esi
leaq 0x96bb(%rip), %rdx      # 0x184f0
movb (%rdx), %dil
andb $0x2f, %dil
addl %ecx, %eax
movl $0xff, %r8d
movl %eax, %r9d
andl %r8d, %r9d
andl %ecx, %r8d
cmpl %r8d, %r9d
leaq 0x969f(%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 0xeeca
movb %r13b, 0x1(%r14)
jmp 0xeeca
movw %r13w, (%r14)
jmp 0xeeca
leaq 0x9656(%rip), %rax      # 0x184f6
movzwl (%rax), %eax
leaq 0x9652(%rip), %rcx      # 0x184fc
movw %ax, (%rcx)
jmp 0xeeca
movzwl %ax, %edi
movzwl %r13w, %esi
callq 0xb9a9
jmp 0xeeca
movb %al, 0x1(%r14)
jmp 0xeeca
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
movzbl 0x1(%rax), %r13d
jmp 0xeb88
movzbl (%rax), %r13d
jmp 0xeb88
xorl %r13d, %r13d
jmp 0xeca0
movq 0x90d3(%rip), %rdi      # 0x17fd0
leaq 0x44f3(%rip), %rsi      # 0x133f7
jmp 0xef34
movq 0x90c3(%rip), %rdi      # 0x17fd0
leaq 0x4511(%rip), %rsi      # 0x13425
callq 0x3290
movzwl %bp, %esi
movq %rax, %rdi
callq 0x33f0
jmp 0xef39
movq 0x90a3(%rip), %rdi      # 0x17fd0
leaq 0x44db(%rip), %rsi      # 0x1340f
callq 0x3290
movq %rax, %rdi
callq 0x3150
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x3310