// File: /workspace/github_c_makefile_star2_O3/leiradel[P]zx48k-libretro/src/zx.h
// Function: zx_quickload
bool zx_quickload(zx_t* sys, const uint8_t* ptr, int num_bytes) {
    const uint8_t* end_ptr = ptr + num_bytes;
    if (_zx_overflow(ptr, sizeof(_zx_z80_header), end_ptr)) {
        return false;
    }
    const _zx_z80_header* hdr = (const _zx_z80_header*) ptr;
    ptr += sizeof(_zx_z80_header);
    const _zx_z80_ext_header* ext_hdr = 0;
    uint16_t pc = (hdr->PC_h<<8 | hdr->PC_l) & 0xFFFF;
    const bool is_version1 = 0 != pc;
    if (!is_version1) {
        if (_zx_overflow(ptr, sizeof(_zx_z80_ext_header), end_ptr)) {
            return false;
        }
        ext_hdr = (_zx_z80_ext_header*) ptr;
        int ext_hdr_len = (ext_hdr->len_h<<8)|ext_hdr->len_l;
        ptr += 2 + ext_hdr_len;
        if (ext_hdr->hw_mode < 3) {
            if (sys->type != ZX_TYPE_48K) {
                return false;
            }
        }
        else {
            if (sys->type != ZX_TYPE_128) {
                return false;
            }
        }
    }
    else {
        if (sys->type != ZX_TYPE_48K) {
            return false;
        }
    }
    const bool v1_compr = 0 != (hdr->flags0 & (1<<5));
    while (ptr < end_ptr) {
        int page_index = 0;
        int src_len = 0;
        if (is_version1) {
            src_len = num_bytes - sizeof(_zx_z80_header);
        }
        else {
            _zx_z80_page_header* phdr = (_zx_z80_page_header*) ptr;
            if (_zx_overflow(ptr, sizeof(_zx_z80_page_header), end_ptr)) {
                return false;
            }
            ptr += sizeof(_zx_z80_page_header);
            src_len = (phdr->len_h<<8 | phdr->len_l) & 0xFFFF;
            page_index = phdr->page_nr - 3;
            if ((sys->type == ZX_TYPE_48K) && (page_index == 5)) {
                page_index = 0;
            }
            if ((page_index < 0) || (page_index > 7)) {
                page_index = -1;
            }
        }
        uint8_t* dst_ptr;
        if (-1 == page_index) {
            dst_ptr = sys->junk;
        }
        else {
            dst_ptr = sys->ram[page_index];
        }
        if (0xFFFF == src_len) {
            /* FIXME: uncompressed not supported yet */
            return false;
        }
        else {
            /* compressed */
            int src_pos = 0;
            bool v1_done = false;
            uint8_t val[4];
            while ((src_pos < src_len) && !v1_done) {
                val[0] = ptr[src_pos];
                val[1] = ptr[src_pos+1];
                val[2] = ptr[src_pos+2];
                val[3] = ptr[src_pos+3];
                /* check for version 1 end marker */
                if (v1_compr && (0==val[0]) && (0xED==val[1]) && (0xED==val[2]) && (0==val[3])) {
                    v1_done = true;
                    src_pos += 4;
                }
                else if (0xED == val[0]) {
                    if (0xED == val[1]) {
                        uint8_t count = val[2];
                        CHIPS_ASSERT(0 != count);
                        uint8_t data = val[3];
                        src_pos += 4;
                        for (int i = 0; i < count; i++) {
                            *dst_ptr++ = data;
                        }
                    }
                    else {
                        /* single ED */
                        *dst_ptr++ = val[0];
                        src_pos++;
                    }
                }
                else {
                    /* any value */
                    *dst_ptr++ = val[0];
                    src_pos++;
                }
            }
            CHIPS_ASSERT(src_pos == src_len);
        }
        if (0xFFFF == src_len) {
            ptr += 0x4000;
        }
        else {
            ptr += src_len;
        }
    }

    /* start loaded image */
    z80_reset(&sys->cpu);
    z80_set_a(&sys->cpu, hdr->A); z80_set_f(&sys->cpu, hdr->F);
    z80_set_b(&sys->cpu, hdr->B); z80_set_c(&sys->cpu, hdr->C);
    z80_set_d(&sys->cpu, hdr->D); z80_set_e(&sys->cpu, hdr->E);
    z80_set_h(&sys->cpu, hdr->H); z80_set_l(&sys->cpu, hdr->L);
    z80_set_ix(&sys->cpu, hdr->IX_h<<8|hdr->IX_l);
    z80_set_iy(&sys->cpu, hdr->IY_h<<8|hdr->IY_l);
    z80_set_af_(&sys->cpu, hdr->A_<<8|hdr->F_);
    z80_set_bc_(&sys->cpu, hdr->B_<<8|hdr->C_);
    z80_set_de_(&sys->cpu, hdr->D_<<8|hdr->E_);
    z80_set_hl_(&sys->cpu, hdr->H_<<8|hdr->L_);
    z80_set_sp(&sys->cpu, hdr->SP_h<<8|hdr->SP_l);
    z80_set_i(&sys->cpu, hdr->I);
    z80_set_r(&sys->cpu, (hdr->R & 0x7F) | ((hdr->flags0 & 1)<<7));
    z80_set_iff2(&sys->cpu, hdr->IFF2 != 0);
    z80_set_ei_pending(&sys->cpu, hdr->EI != 0);
    if (hdr->flags1 != 0xFF) {
        z80_set_im(&sys->cpu, hdr->flags1 & 3);
    }
    else {
        z80_set_im(&sys->cpu, 1);
    }
    if (ext_hdr) {
        z80_set_pc(&sys->cpu, ext_hdr->PC_h<<8|ext_hdr->PC_l);
        if (sys->type == ZX_TYPE_128) {
            for (int i = 0; i < 16; i++) {
                /* latch AY-3-8912 register address */
                ay38910_iorq(&sys->ay, AY38910_BDIR|AY38910_BC1|(i<<16));
                /* write AY-3-8912 register value */
                ay38910_iorq(&sys->ay, AY38910_BDIR|(ext_hdr->audio[i]<<16));
            }
        }
        /* simulate an out of port 0xFFFD and 0x7FFD */
        uint64_t pins = Z80_IORQ|Z80_WR;
        Z80_SET_ADDR(pins, 0xFFFD);
        Z80_SET_DATA(pins, ext_hdr->out_fffd);
        _zx_tick(4, pins, sys);
        Z80_SET_ADDR(pins, 0x7FFD);
        Z80_SET_DATA(pins, ext_hdr->out_7ffd);
        _zx_tick(4, pins, sys);
    }
    else {
        z80_set_pc(&sys->cpu, hdr->PC_h<<8|hdr->PC_l);
    }
    sys->border_color = _zx_palette[(hdr->flags0>>1) & 7] & 0xFFD7D7D7;
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
cmpl $0x1e, %edx
jge 0x1197c
xorl %r14d, %r14d
jmp 0x11e07
leaq 0x1e(%rsi), %rcx
movzwl 0x6(%rsi), %eax
movw %ax, -0x32(%rbp)
testw %ax, %ax
je 0x11cce
xorl %r14d, %r14d
cmpl $0x0, 0x1114(%rdi)
jne 0x11e07
movl %edx, -0x30(%rbp)
movq %rcx, %rax
movq %rdi, -0x40(%rbp)
movslq -0x30(%rbp), %rcx
movq %rsi, -0x48(%rbp)
addq %rsi, %rcx
movq %rcx, -0x58(%rbp)
cmpq %rcx, %rax
jae 0x11b37
movq -0x48(%rbp), %rcx
movb 0xc(%rcx), %r10b
addl $-0x1e, -0x30(%rbp)
movq -0x40(%rbp), %rcx
leaq 0x4230(%rcx), %rdx
movq %rdx, -0x68(%rbp)
addq $0x2c230, %rcx          # imm = 0x2C230
movq %rcx, -0x60(%rbp)
andb $0x20, %r10b
shrb $0x5, %r10b
movq %r14, -0x70(%rbp)
movb %r10b, -0x29(%rbp)
cmpw $0x0, -0x32(%rbp)
je 0x11a0b
movl -0x30(%rbp), %r11d
xorl %ecx, %ecx
movq %rax, %rbx
jmp 0x11a44
leaq 0x3(%rax), %rbx
cmpq -0x58(%rbp), %rbx
ja 0x11974
movzwl (%rax), %r11d
movzbl 0x2(%rax), %ecx
addl $-0x3, %ecx
movl %ecx, %eax
xorl $0x5, %eax
movq -0x40(%rbp), %rdx
orl 0x1114(%rdx), %eax
movl $0x0, %eax
cmovel %eax, %ecx
movq -0x60(%rbp), %r13
cmpl $0x7, %ecx
ja 0x11a4f
movl %ecx, %r13d
shlq $0xe, %r13
addq -0x68(%rbp), %r13
xorl %eax, %eax
cmpl $0xffff, %r11d          # imm = 0xFFFF
je 0x11974
testl %r11d, %r11d
jle 0x11b17
xorl %r14d, %r14d
movl %r11d, -0x4c(%rbp)
movslq %r14d, %rax
movb (%rbx,%rax), %sil
movb 0x1(%rbx,%rax), %dil
movb 0x2(%rbx,%rax), %dl
movb 0x3(%rbx,%rax), %cl
movl %edi, %r8d
xorb $-0x13, %r8b
orb %sil, %r8b
movl %edx, %r9d
xorb $-0x13, %r9b
orb %r8b, %r9b
orb %cl, %r9b
sete %r12b
andb %r10b, %r12b
cmpb $0x1, %r12b
je 0x11b10
incq %rax
cmpb $-0x13, %sil
jne 0x11aea
cmpb $-0x13, %dil
jne 0x11af0
movzbl %dl, %r15d
testq %r15, %r15
je 0x11e19
movzbl %cl, %esi
movq %r13, %rdi
movq %r15, %rdx
callq 0x30d0
decl %r15d
addl $0x4, %r14d
addq %r15, %r13
incq %r13
movl %r14d, %eax
movb -0x29(%rbp), %r10b
movl -0x4c(%rbp), %r11d
jmp 0x11af8
movb %sil, (%r13)
jmp 0x11af5
movb $-0x13, (%r13)
incq %r13
cmpl %r11d, %eax
setl %cl
xorb $0x1, %r12b
movl %eax, %r14d
testb %r12b, %cl
jne 0x11a6e
jmp 0x11b17
addl $0x4, %r14d
movl %r14d, %eax
cmpl %r11d, %eax
jne 0x11e38
movslq %r11d, %rax
addq %rax, %rbx
movq %rbx, %rax
cmpq -0x58(%rbp), %rbx
movq -0x70(%rbp), %r14
jb 0x119f9
movq -0x40(%rbp), %rbx
testq %rbx, %rbx
je 0x11e57
movabsq $-0xffff0001, %rax      # imm = 0xFFFFFFFF0000FFFF
movabsq $0xffffffffffff, %rcx   # imm = 0xFFFFFFFFFFFF
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0x8(%rbx)
movq $-0x1, 0x18(%rbx)
movabsq $-0xffffffffff0020, %rdx # imm = 0xFF0000000000FFE0
andq 0x20(%rbx), %rdx
movq %rdx, 0x20(%rbx)
movq -0x48(%rbp), %r10
movzwl (%r10), %esi
movzbl 0x3(%r10), %edi
shlq $0x38, %rdi
orq %rsi, %rdi
movzbl 0x2(%r10), %esi
shlq $0x30, %rsi
orq %rdi, %rsi
movzbl 0xe(%r10), %edi
shlq $0x28, %rdi
orq %rsi, %rdi
movzbl 0xd(%r10), %esi
shlq $0x20, %rsi
orq %rdi, %rsi
movzbl 0x5(%r10), %edi
shll $0x18, %edi
orq %rsi, %rdi
movzbl 0x4(%r10), %esi
shll $0x10, %esi
orq %rdi, %rsi
movq %rsi, 0x8(%rbx)
movzwl 0x19(%r10), %esi
shlq $0x20, %rsi
movabsq $-0xffff00000001, %rdi  # imm = 0xFFFF0000FFFFFFFF
leaq (%rsi,%rdi), %r8
movq %r8, 0x18(%rbx)
movzwl 0x17(%r10), %r8d
shll $0x10, %r8d
orq %rsi, %r8
movabsq $-0xffffffff0001, %rsi  # imm = 0xFFFF00000000FFFF
orq %r8, %rsi
movq %rsi, 0x18(%rbx)
movzwl 0x15(%r10), %r8d
orq $-0x10000, %r8          # imm = 0xFFFF0000
movq %r8, 0x10(%rbx)
movzwl 0xf(%r10), %r9d
shlq $0x30, %r9
andq %rcx, %r8
orq %r9, %r8
movq %r8, 0x10(%rbx)
movzwl 0x11(%r10), %r9d
shlq $0x20, %r9
andq %rdi, %r8
orq %r9, %r8
movq %r8, 0x10(%rbx)
movzwl 0x13(%r10), %edi
shll $0x10, %edi
andq %rax, %r8
orq %rdi, %r8
movq %r8, 0x10(%rbx)
movw 0x8(%r10), %si
movq %rsi, 0x18(%rbx)
movzbl 0xa(%r10), %edi
shlq $0x28, %rdi
movzbl 0xb(%r10), %r8d
andl $0x7f, %r8d
movb 0xc(%r10), %sil
movl %esi, %r9d
shlb $0x7, %r9b
movzbl %r9b, %r9d
orl %r8d, %r9d
shlq $0x20, %r9
orq %rdi, %r9
xorl %r8d, %r8d
cmpb $0x0, 0x1c(%r10)
movabsq $-0xff0000ffff0008, %rdi # imm = 0xFF00FFFF0000FFF8
setne %r8b
leaq (%r9,%r8,8), %r9
xorl %r8d, %r8d
cmpb $0x0, 0x1b(%r10)
setne %r8b
shll $0x4, %r8d
orq %r9, %r8
orq %rdx, %r8
movzbl 0x1d(%r10), %edx
cmpq $0xff, %rdx
je 0x11d0f
andl $0x3, %edx
andq %rdi, %r8
shlq $0x30, %rdx
orq %r8, %rdx
jmp 0x11d19
cmpl $0x56, %edx
jb 0x11974
movl %edx, -0x30(%rbp)
movzwl 0x1e(%rsi), %eax
addq %rcx, %rax
addq $0x2, %rax
cmpb $0x2, 0x22(%rsi)
movl 0x1114(%rdi), %edx
movq %rcx, %r14
ja 0x11d01
testl %edx, %edx
jne 0x11974
jmp 0x119a7
cmpl $0x1, %edx
jne 0x11974
jmp 0x119a7
andq %rdi, %r8
leaq (%rcx,%r8), %rdx
incq %rdx
movq %rdx, 0x20(%rbx)
testq %r14, %r14
je 0x11dcf
movzwl 0x2(%r14), %ecx
shll $0x10, %ecx
andq %rax, %rdx
orq %rcx, %rdx
movq %rdx, 0x20(%rbx)
cmpl $0x1, 0x1114(%rbx)
jne 0x11d89
movq -0x40(%rbp), %rax
leaq 0x870(%rax), %r12
movabsq $0x30000000000, %r13    # imm = 0x30000000000
xorl %ebx, %ebx
movq %r12, %rdi
movq %r13, %rsi
callq 0x3090
movzbl 0x9(%r14,%rbx), %esi
shll $0x10, %esi
btsq $0x28, %rsi
movq %r12, %rdi
callq 0x3090
incq %rbx
addq $0x10000, %r13          # imm = 0x10000
cmpq $0x10, %rbx
jne 0x11d58
movzbl 0x8(%r14), %esi
shll $0x10, %esi
orq $0x1400fffd, %rsi       # imm = 0x1400FFFD
movl $0x4, %edi
movq -0x40(%rbp), %rbx
movq %rbx, %rdx
callq 0x10a82
movzbl 0x5(%r14), %esi
shll $0x10, %esi
orq $0x14007ffd, %rsi       # imm = 0x14007FFD
movl $0x4, %edi
movq %rbx, %rdx
callq 0x10a82
movq -0x48(%rbp), %rax
movb 0xc(%rax), %sil
jmp 0x11de4
movq -0x48(%rbp), %rcx
movzwl 0x6(%rcx), %ecx
shll $0x10, %ecx
andq %rax, %rdx
orq %rcx, %rdx
movq %rdx, 0x20(%rbx)
shrb %sil
andb $0x7, %sil
movzbl %sil, %eax
leaq 0x27ea(%rip), %rcx      # 0x145e0
movl $0xffd7d7d7, %edx       # imm = 0xFFD7D7D7
andl (%rcx,%rax,4), %edx
movl %edx, 0x1140(%rbx)
movb $0x1, %r14b
movl %r14d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x258a(%rip), %rdi      # 0x143aa
leaq 0x2333(%rip), %rsi      # 0x1415a
leaq 0x2587(%rip), %rcx      # 0x143b5
movl $0x3a1, %edx            # imm = 0x3A1
callq 0x30b0
leaq 0x25a7(%rip), %rdi      # 0x143e6
leaq 0x2314(%rip), %rsi      # 0x1415a
leaq 0x2568(%rip), %rcx      # 0x143b5
movl $0x3b4, %edx            # imm = 0x3B4
callq 0x30b0
leaq 0x22a6(%rip), %rdi      # 0x14104
leaq 0x225c(%rip), %rsi      # 0x140c1
leaq 0x229c(%rip), %rcx      # 0x14108
movl $0x2d0, %edx            # imm = 0x2D0
callq 0x30b0