// File: /workspace/github_c_makefile_star2_O1/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 0x119a5
xorl %eax, %eax
jmp 0x11f19
leaq 0x1e(%rsi), %r8
movzwl 0x6(%rsi), %r9d
testl %r9d, %r9d
je 0x11b64
xorl %eax, %eax
cmpl $0x0, 0x1114(%rdi)
jne 0x11f19
movq $0x0, -0x38(%rbp)
movq %r8, %r14
movslq %edx, %r8
addq %rsi, %r8
movq %rsi, -0x40(%rbp)
movb 0xc(%rsi), %r10b
addl $-0x1e, %edx
leaq 0x2c230(%rdi), %rax
movq %rax, -0x68(%rbp)
movq %rdi, -0x58(%rbp)
leaq 0x4230(%rdi), %rax
movq %rax, -0x60(%rbp)
movl %edx, -0x48(%rbp)
movl %r9d, -0x44(%rbp)
movq %r8, -0x70(%rbp)
movb %r10b, -0x29(%rbp)
cmpq %r8, %r14
jae 0x11b9a
xorl %eax, %eax
testl %r9d, %r9d
je 0x11a20
movl %edx, %r11d
jmp 0x11a6d
leaq 0x3(%r14), %rcx
xorl %r11d, %r11d
cmpq %r8, %rcx
jbe 0x11a30
xorl %eax, %eax
jmp 0x11a61
movzwl (%r14), %r11d
movzbl 0x2(%r14), %eax
addl $-0x3, %eax
movl %eax, %edi
xorl $0x5, %edi
movq -0x58(%rbp), %rsi
orl 0x1114(%rsi), %edi
movl $0x0, %esi
cmovel %esi, %eax
cmpl $0x8, %eax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
cmovael %esi, %eax
movq %rcx, %r14
cmpq %r8, %rcx
jbe 0x11a6d
xorl %ecx, %ecx
jmp 0x11b57
cmpl $0xffff, %r11d          # imm = 0xFFFF
setne %cl
je 0x11b57
movl %ecx, -0x4c(%rbp)
testl %r11d, %r11d
jle 0x11b38
cltq
movq %rax, %r13
shlq $0xe, %r13
addq -0x60(%rbp), %r13
cmpl $-0x1, %eax
cmoveq -0x68(%rbp), %r13
xorl %r12d, %r12d
xorl %ebx, %ebx
movl %r11d, -0x50(%rbp)
movslq %ebx, %rax
movb (%r14,%rax), %dl
movb 0x1(%r14,%rax), %dil
movb 0x2(%r14,%rax), %sil
movb 0x3(%r14,%rax), %cl
testb $0x20, %r10b
je 0x11adf
testb %dl, %dl
jne 0x11adf
cmpb $-0x13, %dil
jne 0x11adf
cmpb $-0x13, %sil
jne 0x11adf
testb %cl, %cl
jne 0x11adf
addl $0x4, %ebx
movb $0x1, %r12b
jmp 0x11b27
incq %rax
cmpb $-0x13, %dl
jne 0x11b1e
cmpb $-0x13, %dil
jne 0x11b1e
movzbl %sil, %r15d
testq %r15, %r15
je 0x11f28
movzbl %cl, %esi
movq %r13, %rdi
movq %r15, %rdx
callq 0x30e0
decl %r15d
addl $0x4, %ebx
addq %r15, %r13
incq %r13
movb -0x29(%rbp), %r10b
movl -0x50(%rbp), %r11d
jmp 0x11b27
movb %dl, (%r13)
incq %r13
movl %eax, %ebx
cmpl %r11d, %ebx
jge 0x11b3a
testb $0x1, %r12b
je 0x11aa7
jmp 0x11b3a
xorl %ebx, %ebx
cmpl %r11d, %ebx
jne 0x11f47
movslq %r11d, %rax
addq %rax, %r14
movl -0x48(%rbp), %edx
movl -0x44(%rbp), %r9d
movq -0x70(%rbp), %r8
movl -0x4c(%rbp), %ecx
testb %cl, %cl
jne 0x11a0b
jmp 0x1199e
cmpl $0x56, %edx
jl 0x1199e
movzwl 0x1e(%rsi), %ecx
leaq (%r8,%rcx), %r14
addq $0x2, %r14
cmpb $0x2, 0x22(%rsi)
movl 0x1114(%rdi), %ecx
ja 0x11dfb
movq %r8, -0x38(%rbp)
testl %ecx, %ecx
jne 0x1199e
jmp 0x119d1
movq -0x58(%rbp), %r14
testq %r14, %r14
je 0x11f66
movabsq $-0xffff0001, %rax      # imm = 0xFFFFFFFF0000FFFF
movabsq $0xffffffffffff, %rcx   # imm = 0xFFFFFFFFFFFF
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0x8(%r14)
movq $-0x1, 0x18(%r14)
movabsq $-0xffffffffff0020, %rdx # imm = 0xFF0000000000FFE0
andq 0x20(%r14), %rdx
movq %rdx, 0x20(%r14)
movq -0x40(%rbp), %r11
movzbl (%r11), %esi
orq $-0x100, %rsi
movq %rsi, 0x8(%r14)
andq $-0xff01, %rsi          # imm = 0xFFFF00FF
movzbl 0x1(%r11), %edi
shll $0x8, %edi
orq %rsi, %rdi
movq %rdi, 0x8(%r14)
movabsq $0xffffffffffffff, %rsi # imm = 0xFFFFFFFFFFFFFF
andq %rdi, %rsi
movzbl 0x3(%r11), %edi
shlq $0x38, %rdi
orq %rsi, %rdi
movq %rdi, 0x8(%r14)
movzbl 0x2(%r11), %esi
movabsq $-0xff000000000001, %r8 # imm = 0xFF00FFFFFFFFFFFF
andq %rdi, %r8
shlq $0x30, %rsi
orq %r8, %rsi
movq %rsi, 0x8(%r14)
movzbl 0xe(%r11), %edi
movabsq $-0xff0000000001, %r8   # imm = 0xFFFF00FFFFFFFFFF
andq %rsi, %r8
shlq $0x28, %rdi
orq %r8, %rdi
movq %rdi, 0x8(%r14)
movzbl 0xd(%r11), %esi
movabsq $-0xff00000001, %r8     # imm = 0xFFFFFF00FFFFFFFF
andq %rdi, %r8
shlq $0x20, %rsi
orq %r8, %rsi
movq %rsi, 0x8(%r14)
leaq 0xff0000(%rax), %rdi
andq %rsi, %rdi
movzbl 0x5(%r11), %esi
shll $0x18, %esi
orq %rdi, %rsi
movq %rsi, 0x8(%r14)
movzbl 0x4(%r11), %edi
andq $-0xff0001, %rsi        # imm = 0xFF00FFFF
shll $0x10, %edi
orq %rsi, %rdi
movq %rdi, 0x8(%r14)
movzbl 0x1a(%r11), %esi
movzbl 0x19(%r11), %r8d
movabsq $-0xffff00000001, %rdi  # imm = 0xFFFF0000FFFFFFFF
movq 0x18(%r14), %r9
andq %rdi, %r9
shlq $0x28, %rsi
shlq $0x20, %r8
orq %rsi, %r8
orq %r9, %r8
movq %r8, 0x18(%r14)
movzbl 0x17(%r11), %esi
andq %rax, %r8
movzbl 0x18(%r11), %r9d
shll $0x18, %r9d
orq %r8, %r9
shll $0x10, %esi
orq %r9, %rsi
movq %rsi, 0x18(%r14)
movq 0x10(%r14), %r8
movw 0x15(%r11), %r8w
movq %r8, 0x10(%r14)
movzbl 0x10(%r11), %r9d
movzbl 0xf(%r11), %r10d
andq %rcx, %r8
shlq $0x38, %r9
shlq $0x30, %r10
orq %r9, %r10
orq %r8, %r10
movq %r10, 0x10(%r14)
movzbl 0x12(%r11), %r8d
movzbl 0x11(%r11), %r9d
andq %rdi, %r10
shlq $0x28, %r8
shlq $0x20, %r9
orq %r8, %r9
orq %r10, %r9
movq %r9, 0x10(%r14)
movzbl 0x13(%r11), %edi
andq %rax, %r9
movzbl 0x14(%r11), %r8d
shll $0x18, %r8d
shll $0x10, %edi
orl %r8d, %edi
orq %r9, %rdi
movq %rdi, 0x10(%r14)
movzbl 0x9(%r11), %edi
shll $0x8, %edi
movzbl 0x8(%r11), %r8d
andq $-0x10000, %rsi         # imm = 0xFFFF0000
orq %r8, %rsi
orq %rdi, %rsi
movq %rsi, 0x18(%r14)
movzbl 0xa(%r11), %esi
shlq $0x28, %rsi
orq %rdx, %rsi
movq %rsi, 0x20(%r14)
movzbl 0xb(%r11), %edx
andl $0x7f, %edx
movb 0xc(%r11), %dil
shlb $0x7, %dil
movzbl %dil, %edi
orl %edx, %edi
shlq $0x20, %rdi
orq %rsi, %rdi
movq %rdi, 0x20(%r14)
xorl %edx, %edx
cmpb $0x0, 0x1c(%r11)
setne %dl
leaq (%rdi,%rdx,8), %rsi
movq %rsi, 0x20(%r14)
xorl %edx, %edx
cmpb $0x0, 0x1b(%r11)
setne %dl
shll $0x4, %edx
orq %rsi, %rdx
movq %rdx, 0x20(%r14)
movzbl 0x1d(%r11), %esi
cmpq $0xff, %rsi
je 0x11e0d
andl $0x3, %esi
movabsq $-0xff0000ffff0008, %rcx # imm = 0xFF00FFFF0000FFF8
andq %rcx, %rdx
shlq $0x30, %rsi
orq %rdx, %rsi
jmp 0x11e21
movq %r8, -0x38(%rbp)
cmpl $0x1, %ecx
jne 0x1199e
jmp 0x119d1
movabsq $-0xff0000ffff0008, %rsi # imm = 0xFF00FFFF0000FFF8
andq %rsi, %rdx
leaq (%rcx,%rdx), %rsi
incq %rsi
movq %rsi, 0x20(%r14)
movq -0x38(%rbp), %r15
testq %r15, %r15
je 0x11edb
movzbl 0x2(%r15), %ecx
andq 0x20(%r14), %rax
movzbl 0x3(%r15), %edx
shll $0x18, %edx
shll $0x10, %ecx
orl %edx, %ecx
orq %rax, %rcx
movq %rcx, 0x20(%r14)
cmpl $0x1, 0x1114(%r14)
jne 0x11e9d
leaq 0x870(%r14), %r12
movabsq $0x30000000000, %r13    # imm = 0x30000000000
xorl %ebx, %ebx
movq %r12, %rdi
movq %r13, %rsi
callq 0x3090
movzbl 0x9(%r15,%rbx), %esi
shll $0x10, %esi
btsq $0x28, %rsi
movq %r12, %rdi
callq 0x3090
incq %rbx
addq $0x10000, %r13          # imm = 0x10000
cmpq $0x10, %rbx
jne 0x11e6c
movzbl 0x8(%r15), %esi
shll $0x10, %esi
orq $0x1400fffd, %rsi       # imm = 0x1400FFFD
movl $0x4, %edi
movq %r14, %rdx
callq 0x10ad4
movzbl 0x5(%r15), %esi
shll $0x10, %esi
orq $0x14007ffd, %rsi       # imm = 0x14007FFD
movl $0x4, %edi
movq %r14, %rdx
callq 0x10ad4
movq -0x40(%rbp), %rsi
jmp 0x11efa
movq -0x40(%rbp), %rsi
movzbl 0x6(%rsi), %ecx
andq 0x20(%r14), %rax
movzbl 0x7(%rsi), %edx
shll $0x18, %edx
shll $0x10, %ecx
orl %edx, %ecx
orq %rax, %rcx
movq %rcx, 0x20(%r14)
movzbl 0xc(%rsi), %eax
andl $0xe, %eax
leaq 0x26e8(%rip), %rcx      # 0x145f0
movl $0xffd7d7d7, %edx       # imm = 0xFFD7D7D7
andl (%rcx,%rax,2), %edx
movl %edx, 0x1140(%r14)
movb $0x1, %al
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x248b(%rip), %rdi      # 0x143ba
leaq 0x2234(%rip), %rsi      # 0x1416a
leaq 0x2488(%rip), %rcx      # 0x143c5
movl $0x3a1, %edx            # imm = 0x3A1
callq 0x30b0
leaq 0x24a8(%rip), %rdi      # 0x143f6
leaq 0x2215(%rip), %rsi      # 0x1416a
leaq 0x2469(%rip), %rcx      # 0x143c5
movl $0x3b4, %edx            # imm = 0x3B4
callq 0x30b0
leaq 0x21a7(%rip), %rdi      # 0x14114
leaq 0x215d(%rip), %rsi      # 0x140d1
leaq 0x219d(%rip), %rcx      # 0x14118
movl $0x2d0, %edx            # imm = 0x2D0
callq 0x30b0