// File: /workspace/github_c_makefile_star2_O1/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 $0xc8, %rsp
movq %rsi, 0x70(%rsp)
movq %rdi, 0xb0(%rsp)
movq %rdx, 0x78(%rsp)
cmpq $0x18, %rdx
jb 0x1ff0
movq 0x70(%rsp), %rsi
movl 0x14(%rsi), %ecx
bswapl %ecx
movq 0x78(%rsp), %rdx
cmpq $0x87, %rdx
jb 0x19e5
cmpl $0x31990, %ecx          # imm = 0x31990
je 0x19cc
cmpl $0x12031990, %ecx       # imm = 0x12031990
je 0x19cc
cmpl $0x12030090, %ecx       # imm = 0x12030090
jne 0x19e5
movzwl 0x28(%rsi), %eax
rolw $0x8, %ax
movzwl %ax, %eax
movl %eax, 0x4(%rsp)
leaq 0x2e(%rsi), %r14
leaq 0x6e(%rsi), %r13
jmp 0x1a23
cmpq $0x2d, %rdx
jb 0x2002
cmpl $0x6071963, %ecx        # imm = 0x6071963
je 0x1a03
cmpl $0x6070063, %ecx        # imm = 0x6070063
jne 0x2002
leaq 0x14(%rsi), %r13
movzbl 0x22(%rsi), %eax
movzbl 0x23(%rsi), %ecx
shll $0x14, %eax
shll $0xc, %ecx
addl %ecx, %eax
addl $0x200, %eax            # imm = 0x200
movl %eax, 0x4(%rsp)
xorl %r14d, %r14d
movl 0x10(%r13), %ebx
bswapl %ebx
movq %rsi, %rax
subq %r13, %rax
addq %rdx, %rax
cmpq %rax, %rbx
ja 0x1ff0
movl 0x14(%r13), %ecx
bswapl %ecx
movq %rcx, 0xa0(%rsp)
cmpq %rax, %rcx
ja 0x1ff0
movzbl 0x8(%r13), %ebp
shll $0x8, %ebp
movzbl 0x9(%r13), %edx
leal (%rdx,%rbp), %edi
movl %edi, 0xc(%rsp)
movzbl 0xa(%r13), %eax
shll $0x8, %eax
movzbl 0xb(%r13), %ecx
movq %rax, 0x88(%rsp)
movq %rcx, 0x28(%rsp)
addl %ecx, %eax
movzbl 0xc(%r13), %ecx
shll $0x8, %ecx
movzbl 0xd(%r13), %esi
movq %rsi, 0x38(%rsp)
movq %rcx, 0x90(%rsp)
leal (%rcx,%rsi), %r15d
movl %r15d, 0x8(%rsp)
movzbl 0xe(%r13), %ecx
shll $0x8, %ecx
movb 0xf(%r13), %sil
movb %sil, 0x60(%rsp)
movzbl %sil, %esi
movq %rcx, 0x68(%rsp)
movq %rsi, 0x20(%rsp)
addl %esi, %ecx
movq %rdx, 0x58(%rsp)
movl %edx, %r12d
andl $0x1, %r12d
addl %edi, %r12d
movl %ecx, 0x40(%rsp)
imull %r12d, %ecx
movl %eax, 0x1c(%rsp)
imull %eax, %r15d
movq %rcx, 0x80(%rsp)
imull %r15d, %ecx
movq %rcx, 0x98(%rsp)
leal 0xb0(%rcx), %edi
movq %rdi, 0xb8(%rsp)
callq 0x1110
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0x1ff0
movq %rbp, 0x30(%rsp)
movq 0x78(%rsp), %rax
movq 0x70(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x50(%rsp)
leaq 0x1818(%rip), %rsi      # 0x3350
movl $0xb0, %edx
movq 0x10(%rsp), %rbp
movq %rbp, %rdi
callq 0x1100
movl 0x8(%rsp), %r10d
movq 0x38(%rsp), %r9
movl 0xc(%rsp), %r8d
movq 0x98(%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 %r12d, %eax
shrl $0x5, %eax
movb %al, 0x14(%rbp)
leal (,%r12,8), %ecx
movb %cl, 0x15(%rbp)
movl %r15d, %edx
shrl $0x8, %edx
movb %dl, 0x16(%rbp)
movb %r15b, 0x17(%rbp)
movb 0x60(%rsp), %sil
movb %sil, 0x1c(%rbp)
movb %al, 0x24(%rbp)
movb %cl, 0x25(%rbp)
movb %dl, 0x26(%rbp)
movb %r15b, 0x27(%rbp)
movl 0x4(%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)
leaq 0x4a(%rbp), %rax
xorl %ecx, %ecx
testq %r14, %r14
je 0x1c16
movzwl (%r14,%rcx,2), %edx
rolw $0x8, %dx
movzwl %dx, %edx
jmp 0x1c21
movl %ecx, %edx
andl $0xf, %edx
imull $0x111, %edx, %edx      # imm = 0x111
movl %edx, %esi
shrl $0x8, %esi
andb $0xf, %sil
movzbl %sil, %esi
movl %esi, %edi
shll $0x4, %edi
addl %esi, %edi
movb %dil, -0x2(%rax)
movl %edx, %esi
shrb $0x4, %sil
movzbl %sil, %esi
movl %esi, %edi
shll $0x4, %edi
addl %esi, %edi
movb %dil, -0x1(%rax)
andb $0xf, %dl
movzbl %dl, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %esi
movb %sil, (%rax)
incq %rcx
addq $0x3, %rax
cmpq $0x20, %rcx
jne 0x1c03
cmpl $0x0, 0x40(%rsp)
movq 0x30(%rsp), %rdi
movq 0x50(%rsp), %r11
je 0x1f67
movq 0x10(%rsp), %rax
addq $0xb0, %rax
movq %rax, 0xa8(%rsp)
movq 0xa0(%rsp), %rdx
cmpb $0x0, (%r13,%rdx)
leaq (%r13,%rbx), %rax
leaq 0x1(%r13,%rbx), %rcx
cmovsq %rcx, %rax
leaq (%r13,%rdx), %rdx
movq %rdx, 0x40(%rsp)
leaq 0x2(%r13,%rbx), %rbx
cmovnsq %rcx, %rbx
movb 0x18(%r13), %r14b
addq $0x19, %r13
cmpl $0x0, 0x1c(%rsp)
setne 0x1(%rsp)
testl %r8d, %r8d
setne 0x2(%rsp)
testl %r10d, %r10d
setne 0x3(%rsp)
orl 0x58(%rsp), %edi
movb (%rax), %al
movb %al, 0x4(%rsp)
movq 0x88(%rsp), %rax
orl 0x28(%rsp), %eax
movq %rax, 0x88(%rsp)
movq 0x80(%rsp), %rax
movl %eax, %ecx
movq %rcx, 0xa0(%rsp)
imull %r10d, %eax
movq %rax, 0x80(%rsp)
movl %r12d, %eax
movq %rax, 0xc0(%rsp)
movq 0x68(%rsp), %rax
orl 0x20(%rsp), %eax
movq %rax, 0x68(%rsp)
addl 0x90(%rsp), %r9d
negl %r9d
movl $0x0, 0x4c(%rsp)
movb $0x7, %r12b
movb $0x6, %bpl
movq %rdi, 0x30(%rsp)
movq %r9, 0x38(%rsp)
cmpl $0x0, 0x1c(%rsp)
je 0x1f30
xorl %ecx, %ecx
movb 0x1(%rsp), %al
movb %al, 0x20(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x28(%rsp)
testl %r8d, %r8d
je 0x1eee
xorl %eax, %eax
movb 0x2(%rsp), %dl
movq 0x28(%rsp), %rsi
movq %rsi, 0x60(%rsp)
movl %ecx, 0x58(%rsp)
movl %eax, 0x98(%rsp)
movb %dl, 0x90(%rsp)
testl %r10d, %r10d
je 0x1e49
movl $0x1, %ecx
movb 0x3(%rsp), %r15b
movq 0x60(%rsp), %rax
movzbl 0x4(%rsp), %edx
movzbl %r12b, %esi
decb %r12b
btl %esi, %edx
jae 0x1dde
movb (%r13), %r14b
incq %r13
cmpq %r11, %r13
ja 0x1e55
movb %r14b, (%rax)
cmpb $0x8, %r12b
jb 0x1e27
movq 0x40(%rsp), %rdx
movzbl (%rdx), %edx
movzbl %bpl, %esi
decb %bpl
btl %esi, %edx
jae 0x1e09
movb (%rbx), %dl
movb %dl, 0x4(%rsp)
incq %rbx
cmpq %r11, %rbx
ja 0x1e7a
movb $0x7, %r12b
cmpb $0x8, %bpl
jb 0x1e27
movq 0x40(%rsp), %rdx
incq %rdx
movq %rdx, 0x40(%rsp)
cmpq %r11, %rdx
ja 0x1ea2
movb $0x7, %bpl
addq 0xa0(%rsp), %rax
cmpl %r10d, %ecx
setb %r15b
leal (%r9,%rcx), %edx
incl %edx
incl %ecx
cmpl $0x1, %edx
jne 0x1dc1
jmp 0x1e4e
movb 0x3(%rsp), %r15b
incq 0x60(%rsp)
jmp 0x1ecb
movq 0x10(%rsp), %rdi
callq 0x1030
movq 0x50(%rsp), %r11
movl 0x8(%rsp), %r10d
movq 0x38(%rsp), %r9
movl 0xc(%rsp), %r8d
movq 0x30(%rsp), %rdi
jmp 0x1ecb
movq 0x10(%rsp), %rdi
callq 0x1030
movq 0x50(%rsp), %r11
movl 0x8(%rsp), %r10d
movq 0x38(%rsp), %r9
movl 0xc(%rsp), %r8d
movq 0x30(%rsp), %rdi
movb $0x7, %r12b
jmp 0x1ecb
movq 0x10(%rsp), %rdi
callq 0x1030
movq 0x50(%rsp), %r11
movl 0x8(%rsp), %r10d
movq 0x38(%rsp), %r9
movl 0xc(%rsp), %r8d
movq 0x30(%rsp), %rdi
movb $0x7, %r12b
movb $0x7, %bpl
testb $0x1, %r15b
movl 0x98(%rsp), %eax
jne 0x1f06
incl %eax
cmpl %r8d, %eax
setb %dl
cmpl %edi, %eax
movl 0x58(%rsp), %ecx
jne 0x1d9b
jmp 0x1ef2
movb 0x2(%rsp), %dl
movq 0x28(%rsp), %rax
addq 0x80(%rsp), %rax
movq %rax, 0x28(%rsp)
jmp 0x1f11
movl 0x58(%rsp), %ecx
movb 0x90(%rsp), %dl
testb $0x1, %dl
jne 0x1f48
incl %ecx
cmpl 0x1c(%rsp), %ecx
setb 0x20(%rsp)
cmpl 0x88(%rsp), %ecx
jne 0x1d7e
jmp 0x1f38
movb 0x1(%rsp), %al
movb %al, 0x20(%rsp)
movq 0xc0(%rsp), %rax
addq %rax, 0xa8(%rsp)
testb $0x1, 0x20(%rsp)
jne 0x1ff0
movl 0x4c(%rsp), %eax
incl %eax
movl %eax, 0x4c(%rsp)
cmpl 0x68(%rsp), %eax
jne 0x1d5c
movq 0x70(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x15d4
leaq 0x1106(%rip), %rsi      # 0x3083
movq 0xb0(%rsp), %rbx
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1394
testq %rax, %rax
je 0x2033
movq %rax, %r14
leaq 0x10eb(%rip), %rdi      # 0x308f
movq %rbx, %rsi
movq %rax, %rdx
movq 0xb8(%rsp), %r15
movl %r15d, %ecx
xorl %eax, %eax
callq 0x10c0
movq %r14, %rdi
movq 0x10(%rsp), %rbx
movq %rbx, %rsi
movq %r15, %rdx
callq 0x132e
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1030
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2fe7(%rip), %rax      # 0x4ff0
movq (%rax), %rdi
leaq 0x104d(%rip), %rsi      # 0x3060
movq 0xb0(%rsp), %rdx
xorl %eax, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x10e0
movq %rbx, %rdi
callq 0x1130
movq 0x10(%rsp), %rbx
jmp 0x1fd7