// File: /workspace/github_c_makefile_star2_O2/kyz[P]amostools/dumpamos.c
// Function: decode_pacpic
void decode_pacpic(char *fname, uint8_t *src, size_t len) {
    uint8_t *end = &src[len], *s, *pal, *picdata, *rledata,
        *points, *ilbm;
    uint32_t i, j, k, l, bplcon0, width, ilbm_width, lumps,
        lump_height, ilbm_height, bitplanes, ilbm_len, ilbm_line,
        rledata_offset, points_offset;

    /* check if screen header present */
    if (len < 24) return;
    i = amos_leek(&src[20]);
    if (len > 134 && (i == 0x12031990 || i == 0x00031990 || i == 0x12030090)) {
        bplcon0 = amos_deek(&src[20 + 20]); /* screen mode */
        pal = &src[20 + 26]; /* palette */
        s = &src[110]; /* picture header */
    }
    else if (len > 44 && (i == 0x06071963 || i == 0x06070063)) {
        bplcon0 = amos_deek(&src[20 + 14]) << 12 | 0x200; /* guess BPLCON0 */
        pal = NULL; /* no palette */
        s = &src[20]; /* picture header */
    }
    else {
        fprintf(stderr, "%s: unknown Pic.Pac. header $%08X\n", fname, i);
        return;
    }

    width = amos_deek(&s[8]);
    lumps            = amos_deek(&s[10]);
    lump_height      = amos_deek(&s[12]);
    bitplanes        = amos_deek(&s[14]);
    rledata_offset   = amos_leek(&s[16]);
    points_offset    = amos_leek(&s[20]);

    if (rledata_offset > (len - (s - src)) ||
        points_offset > (len - (s - src)))
    {
        return;
    }

    /* IFF ILBM requires an even width */
    ilbm_width = width;
    if (ilbm_width & 1) ilbm_width++;

    /* number of bytes jump to get to the next line in IFF */
    ilbm_line = ilbm_width * bitplanes;
    ilbm_height = lumps * lump_height;

    ilbm_len = IFF_ILBM_HEADER_LEN + ilbm_line * ilbm_height;
    if ((ilbm = malloc(ilbm_len))) {
        uint8_t *plane, rbit, rrbit, picbyte, rlebyte;
        char *outname;

        memcpy(ilbm, iff_ilbm_header, IFF_ILBM_HEADER_LEN);
        amos_loke(&ilbm[0x04], ilbm_len - 8);
        amos_doke(&ilbm[0x14], ilbm_width * 8);  /* width */
        amos_doke(&ilbm[0x16], ilbm_height);     /* height */
        ilbm[0x1c] = bitplanes & 0xFF;           /* number of bitplanes */
        amos_doke(&ilbm[0x24], ilbm_width * 8);  /* page width */
        amos_doke(&ilbm[0x26], ilbm_height);     /* page height */
        amos_loke(&ilbm[0x30], bplcon0);         /* viewmode */
        memcpy(&ilbm[0xA8], "BODY", 4);
        amos_loke(&ilbm[0xAC], ilbm_len - IFF_ILBM_HEADER_LEN); /* body length */
        /* convert palette from 0x0RGB to 0xRR 0xGG 0xBB */
        for (int i = 0; i < 32; i++) {
            uint32_t c = pal ? amos_deek(&pal[i*2]) : (i & 0x0F) * 0x111;
            ilbm[0x48 + (i * 3) + 0] = ((c >> 8) & 0xF) * 0x11;
            ilbm[0x48 + (i * 3) + 1] = ((c >> 4) & 0xF) * 0x11;
            ilbm[0x48 + (i * 3) + 2] = ((c     ) & 0xF) * 0x11;
        }

        /* decrunch RLE streams */
        rbit = 7;
        rrbit = 6;
        picdata = &s[24];
        rledata = &s[rledata_offset];
        points  = &s[points_offset];
        picbyte = *picdata++;
        rlebyte = *rledata++;
        if (*points & 0x80) rlebyte = *rledata++;
        plane = &ilbm[IFF_ILBM_HEADER_LEN];
        for (i = 0; i < bitplanes; i++) {
            uint8_t *lump_start = plane;
            for (j = 0; j < lumps; j++) {
                uint8_t *lump_offset = lump_start;
                for (k = 0; k < width; k++) {
                    uint8_t *d = lump_offset;
                    for (l = 0; l < lump_height; l++) {
                        /* if the current RLE bit is set to 1, read in a new picture byte */
                        if (rlebyte & (1 << rbit--)) {
                            picbyte = *picdata++;
                            if (picdata > end) {free(ilbm); return;}
                        }

                        /* write picture byte and move down by one line in the picture */
                        *d = picbyte; d += ilbm_line;

                        /* if we've run out of RLE bits, check the POINTS bits to see if
                         * a new RLE byte is needed */
                        if (rbit > 7) {
                            rbit = 7;
                            if (*points & (1 << rrbit--)) {
                                rlebyte = *rledata++;
                                if (rledata > end) {free(ilbm); return;}

                            }
                            if (rrbit > 7) {
                                rrbit = 7, points++;
                                if (points > end) {free(ilbm); return;}
                            }
                        }
                    }
                    lump_offset++;
                }
                lump_start += ilbm_line * lump_height;
            }
            plane += ilbm_width; /* ILBM interleaved bitplanes */
        }

        /* save IFF ILBM */
        if ((outname = output_fname(fname, "pic%02X.iff", bank_number(src, len)))) {
            printf("%s: unpacking to ILBM image %s (%d bytes)\n", fname, outname, ilbm_len);
            write_file(outname, ilbm, ilbm_len);
            free(outname);
        }
        else {
            perror(fname);
        }


        free(ilbm);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
cmpq $0x18, %rdx
jb 0x1bf9
movq %rdi, %r8
movl 0x14(%rsi), %ecx
bswapl %ecx
cmpq $0x87, %rdx
jb 0x1983
cmpl $0x31990, %ecx          # imm = 0x31990
je 0x196a
cmpl $0x6070063, %ecx        # imm = 0x6070063
je 0x19a1
cmpl $0x6071963, %ecx        # imm = 0x6071963
je 0x19a1
cmpl $0x12031990, %ecx       # imm = 0x12031990
je 0x196a
cmpl $0x12030090, %ecx       # imm = 0x12030090
jne 0x1dc7
movzwl 0x28(%rsi), %eax
rolw $0x8, %ax
movzwl %ax, %eax
movl %eax, 0x8(%rsp)
leaq 0x2e(%rsi), %rbx
leaq 0x6e(%rsi), %r12
jmp 0x19c0
cmpq $0x2d, %rdx
jb 0x1dc7
cmpl $0x6071963, %ecx        # imm = 0x6071963
je 0x19a1
cmpl $0x6070063, %ecx        # imm = 0x6070063
jne 0x1dc7
leaq 0x14(%rsi), %r12
movzbl 0x22(%rsi), %eax
movzbl 0x23(%rsi), %ecx
shll $0x14, %eax
shll $0xc, %ecx
addl %ecx, %eax
addl $0x200, %eax            # imm = 0x200
movl %eax, 0x8(%rsp)
xorl %ebx, %ebx
movl 0x10(%r12), %r14d
bswapl %r14d
movq %rsi, %rax
subq %r12, %rax
addq %rdx, %rax
cmpq %rax, %r14
ja 0x1bf9
movl 0x14(%r12), %ecx
bswapl %ecx
movq %rcx, 0x10(%rsp)
cmpq %rax, %rcx
ja 0x1bf9
movzbl 0x8(%r12), %eax
shll $0x8, %eax
movzbl 0x9(%r12), %edi
movq %rax, 0x48(%rsp)
addl %edi, %eax
movzbl 0xa(%r12), %ecx
shll $0x8, %ecx
movq %rsi, 0x60(%rsp)
movzbl 0xb(%r12), %esi
movq %rcx, 0x50(%rsp)
movq %rsi, 0x28(%rsp)
leal (%rcx,%rsi), %r13d
movzbl 0xc(%r12), %ebp
shll $0x8, %ebp
movzbl 0xd(%r12), %ecx
movq %rcx, 0x30(%rsp)
addl %ebp, %ecx
movzbl 0xe(%r12), %esi
shll $0x8, %esi
movb 0xf(%r12), %r9b
movb %r9b, 0x7(%rsp)
movzbl %r9b, %r9d
movq %rsi, 0x38(%rsp)
movq %r9, 0x90(%rsp)
addl %r9d, %esi
movq %rdi, 0x18(%rsp)
movl %edi, %r15d
andl $0x1, %r15d
addl %eax, %r15d
imull %r15d, %esi
movq %rcx, 0x40(%rsp)
imull %ecx, %r13d
movl %esi, 0x20(%rsp)
movl %esi, %eax
imull %r13d, %eax
movq %rax, 0x88(%rsp)
leal 0xb0(%rax), %edi
movq %rdi, 0x70(%rsp)
movq %r8, 0x78(%rsp)
movq %rdx, 0x68(%rsp)
callq 0x1100
movq 0x60(%rsp), %rdx
movq 0x68(%rsp), %rcx
testq %rax, %rax
je 0x1bf9
addq %rdx, %rcx
movq %rcx, 0x58(%rsp)
leaq 0x1882(%rip), %rsi      # 0x3350
movl $0xa8, %edx
movq %rax, %rdi
movq %rbp, 0x80(%rsp)
movq %rax, %rbp
callq 0x10f0
movq 0x88(%rsp), %rdi
leal 0xa8(%rdi), %eax
movl %eax, %ecx
shrl $0x18, %ecx
movb %cl, 0x4(%rbp)
movl %eax, %ecx
shrl $0x10, %ecx
movb %cl, 0x5(%rbp)
movb %ah, 0x6(%rbp)
movb %al, 0x7(%rbp)
movl %r15d, %eax
shrl $0x5, %eax
movb %al, 0x14(%rbp)
leal (,%r15,8), %ecx
movb %cl, 0x15(%rbp)
movl %r13d, %edx
shrl $0x8, %edx
movb %dl, 0x16(%rbp)
movb %r13b, 0x17(%rbp)
movb 0x7(%rsp), %sil
movb %sil, 0x1c(%rbp)
movb %al, 0x24(%rbp)
movb %cl, 0x25(%rbp)
movb %dl, 0x26(%rbp)
movb %r13b, 0x27(%rbp)
movl 0x8(%rsp), %ecx
movl %ecx, %eax
shrl $0x18, %eax
movb %al, 0x30(%rbp)
movl %ecx, %eax
shrl $0x10, %eax
movb %al, 0x31(%rbp)
movb %ch, 0x32(%rbp)
movb %cl, 0x33(%rbp)
movl $0x59444f42, 0xa8(%rbp) # imm = 0x59444F42
movq %rdi, %rcx
movl %ecx, %eax
shrl $0x18, %eax
movb %al, 0xac(%rbp)
movl %ecx, %eax
shrl $0x10, %eax
movb %al, 0xad(%rbp)
movb %ch, 0xae(%rbp)
movb %cl, 0xaf(%rbp)
movq %rbp, 0x8(%rsp)
leaq 0x4a(%rbp), %rax
movq 0x80(%rsp), %r10
xorl %ecx, %ecx
cmpq $0x20, %rcx
je 0x1c0b
testq %rbx, %rbx
je 0x1bb5
movzwl (%rbx,%rcx,2), %edx
rolw $0x8, %dx
movzwl %dx, %edx
jmp 0x1bc0
movl %ecx, %edx
andl $0xf, %edx
imull $0x111, %edx, %edx      # imm = 0x111
movl %edx, %esi
shrl $0x8, %esi
andb $0xf, %sil
movzbl %sil, %esi
imull $0x11, %esi, %esi
movb %sil, -0x2(%rax)
movl %edx, %esi
shrb $0x4, %sil
movzbl %sil, %esi
imull $0x11, %esi, %esi
movb %sil, -0x1(%rax)
andb $0xf, %dl
movzbl %dl, %edx
imull $0x11, %edx, %edx
movb %dl, (%rax)
incq %rcx
addq $0x3, %rax
jmp 0x1b9d
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq (%r12,%r14), %rcx
leaq (%r12,%r14), %rax
incq %rax
movq 0x10(%rsp), %rdx
cmpb $0x0, (%r12,%rdx)
leaq 0x2(%r12,%r14), %r9
cmovnsq %rax, %r9
cmovsq %rax, %rcx
movq 0x48(%rsp), %r14
orl 0x18(%rsp), %r14d
leaq (%r12,%rdx), %rax
movb (%rcx), %sil
movb 0x18(%r12), %dil
leaq 0x19(%r12), %rcx
movq 0x50(%rsp), %rdx
orl 0x28(%rsp), %edx
movq %rdx, 0x50(%rsp)
movq 0x8(%rsp), %rdx
addq $0xb0, %rdx
movq %rdx, 0x18(%rsp)
movq 0x40(%rsp), %rdx
movl 0x20(%rsp), %r8d
imull %r8d, %edx
movq %rdx, 0x40(%rsp)
movl %r8d, %r8d
movl %r15d, %edx
movq %rdx, 0x20(%rsp)
movq 0x38(%rsp), %rdx
orl 0x90(%rsp), %edx
addl 0x30(%rsp), %r10d
movb $0x6, %r11b
movb $0x7, %bl
xorl %ebp, %ebp
movq %rdx, 0x38(%rsp)
movq %r14, 0x48(%rsp)
cmpl %edx, %ebp
je 0x1df3
xorl %r12d, %r12d
movq 0x18(%rsp), %r13
movq %r13, 0x10(%rsp)
movl %ebp, 0x28(%rsp)
cmpl 0x50(%rsp), %r12d
je 0x1d9b
xorl %r15d, %r15d
movq 0x10(%rsp), %rdx
movl %r12d, 0x30(%rsp)
cmpl %r14d, %r15d
je 0x1d7f
movq %r10, %r14
movl %r10d, %ebp
movq %rdx, %r12
subl $0x1, %ebp
jb 0x1d63
movzbl %sil, %r13d
movzbl %bl, %r10d
btl %r10d, %r13d
jae 0x1d12
leaq 0x1(%rcx), %r13
cmpq 0x58(%rsp), %r13
ja 0x1dac
movb (%rcx), %dil
movq %r13, %rcx
decb %bl
movb %dil, (%r12)
cmpb $0x8, %bl
jb 0x1d3b
movzbl (%rax), %r10d
movzbl %r11b, %ebx
btl %ebx, %r10d
jae 0x1d40
leaq 0x1(%r9), %r13
cmpq 0x58(%rsp), %r13
ja 0x1dac
movb (%r9), %sil
jmp 0x1d43
movq %r9, %r13
jmp 0x1d5b
movq %r9, %r13
decb %r11b
movb $0x7, %bl
cmpb $0x8, %r11b
jb 0x1d5b
incq %rax
movb $0x7, %r11b
cmpq 0x58(%rsp), %rax
ja 0x1dac
addq %r8, %r12
movq %r13, %r9
jmp 0x1cea
incq %rdx
incl %r15d
movq %r14, %r10
movq 0x48(%rsp), %r14
movl 0x28(%rsp), %ebp
movl 0x30(%rsp), %r12d
jmp 0x1cd8
movq 0x10(%rsp), %rdx
addq 0x40(%rsp), %rdx
movq %rdx, 0x10(%rsp)
incl %r12d
movq 0x38(%rsp), %rdx
jmp 0x1cc0
movq 0x20(%rsp), %r12
addq %r12, 0x18(%rsp)
incl %ebp
jmp 0x1ca7
movq 0x8(%rsp), %rdi
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1030
movq 0x3222(%rip), %rax      # 0x4ff0
movq (%rax), %rdi
leaq 0x1288(%rip), %rsi      # 0x3060
movq %r8, %rdx
xorl %eax, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x10d0
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x15a6
leaq 0x127a(%rip), %rsi      # 0x3083
movq 0x78(%rsp), %rbx
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1378
testq %rax, %rax
je 0x1e61
movq %rax, %r14
leaq 0x1266(%rip), %rdi      # 0x308f
movq %rbx, %rsi
movq %rax, %rdx
movq 0x70(%rsp), %r15
movl %r15d, %ecx
xorl %eax, %eax
callq 0x10c0
movq %r14, %rdi
movq 0x8(%rsp), %rbx
movq %rbx, %rsi
movq %r15, %rdx
callq 0x1317
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
jmp 0x1db1
movq %rbx, %rdi
callq 0x1120
movq 0x8(%rsp), %rbx
jmp 0x1e59