// File: /workspace/github_c_makefile_star2_O3/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 $0xa8, %rsp
cmpq $0x18, %rdx
jb 0x1eb2
movq %rdi, %r8
movl 0x14(%rsi), %ecx
bswapl %ecx
cmpq $0x87, %rdx
jb 0x19bf
cmpl $0x6071962, %ecx        # imm = 0x6071962
jle 0x19d3
cmpl $0x6071963, %ecx        # imm = 0x6071963
je 0x19e7
cmpl $0x12031990, %ecx       # imm = 0x12031990
je 0x1a08
cmpl $0x12030090, %ecx       # imm = 0x12030090
je 0x1a08
jmp 0x1ede
cmpq $0x2d, %rdx
jb 0x1ede
cmpl $0x6071963, %ecx        # imm = 0x6071963
jne 0x19db
jmp 0x19e7
cmpl $0x31990, %ecx          # imm = 0x31990
je 0x1a08
cmpl $0x6070063, %ecx        # imm = 0x6070063
jne 0x1ede
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, (%rsp)
xorl %r12d, %r12d
jmp 0x1a1e
movzwl 0x28(%rsi), %eax
rolw $0x8, %ax
movzwl %ax, %eax
movl %eax, (%rsp)
leaq 0x2e(%rsi), %r12
leaq 0x6e(%rsi), %r13
movl 0x10(%r13), %ebp
bswapl %ebp
movq %rsi, %rax
subq %r13, %rax
addq %rdx, %rax
cmpq %rax, %rbp
ja 0x1eb2
movl 0x14(%r13), %ecx
bswapl %ecx
movq %rcx, 0x10(%rsp)
cmpq %rax, %rcx
ja 0x1eb2
movzbl 0x8(%r13), %eax
shll $0x8, %eax
movzbl 0x9(%r13), %edi
movq %rax, 0x58(%rsp)
addl %edi, %eax
movzbl 0xa(%r13), %ecx
shll $0x8, %ecx
movq %rsi, 0x70(%rsp)
movzbl 0xb(%r13), %esi
movq %rcx, 0x48(%rsp)
movq %rsi, 0xa0(%rsp)
addl %esi, %ecx
movzbl 0xc(%r13), %esi
shll $0x8, %esi
movzbl 0xd(%r13), %r9d
movq %rsi, 0x50(%rsp)
movq %r9, 0x98(%rsp)
leal (%rsi,%r9), %r14d
movzbl 0xe(%r13), %esi
shll $0x8, %esi
movb 0xf(%r13), %r9b
movb %r9b, 0x30(%rsp)
movzbl %r9b, %r9d
movq %rsi, 0x38(%rsp)
movq %r9, 0x90(%rsp)
addl %r9d, %esi
movq %rdi, 0x28(%rsp)
movl %edi, %r15d
andl $0x1, %r15d
movl %eax, 0x6c(%rsp)
addl %eax, %r15d
movl %esi, 0xc(%rsp)
movl %esi, %eax
imull %r15d, %eax
movl %r14d, 0x1c(%rsp)
movl %ecx, 0x68(%rsp)
imull %ecx, %r14d
movq %rax, 0x40(%rsp)
imull %r14d, %eax
movq %rax, 0x20(%rsp)
leal 0xb0(%rax), %ebx
movq %rbx, %rdi
movq %r8, 0x88(%rsp)
movq %rdx, 0x78(%rsp)
callq 0x1100
movq 0x70(%rsp), %rdx
movq 0x78(%rsp), %rcx
testq %rax, %rax
je 0x1eb2
movq %rbx, 0x80(%rsp)
addq %rdx, %rcx
movq %rcx, 0x60(%rsp)
leaq 0x1811(%rip), %rsi      # 0x3350
movl $0xa8, %edx
movq %rax, %rdi
movq %rax, %rbx
callq 0x10f0
movq 0x20(%rsp), %rdi
leal 0xa8(%rdi), %eax
movl %eax, %ecx
shrl $0x18, %ecx
movb %cl, 0x4(%rbx)
movl %eax, %ecx
shrl $0x10, %ecx
movb %cl, 0x5(%rbx)
movb %ah, 0x6(%rbx)
movb %al, 0x7(%rbx)
movl %r15d, %eax
shrl $0x5, %eax
movb %al, 0x14(%rbx)
leal (,%r15,8), %ecx
movb %cl, 0x15(%rbx)
movl %r14d, %edx
shrl $0x8, %edx
movb %dl, 0x16(%rbx)
movb %r14b, 0x17(%rbx)
movb 0x30(%rsp), %sil
movb %sil, 0x1c(%rbx)
movb %al, 0x24(%rbx)
movb %cl, 0x25(%rbx)
movb %dl, 0x26(%rbx)
movb %r14b, 0x27(%rbx)
movl (%rsp), %ecx
movl %ecx, %eax
shrl $0x18, %eax
movb %al, 0x30(%rbx)
movl %ecx, %eax
shrl $0x10, %eax
movb %al, 0x31(%rbx)
movb %ch, 0x32(%rbx)
movb %cl, 0x33(%rbx)
movl $0x59444f42, 0xa8(%rbx) # imm = 0x59444F42
movq %rdi, %rcx
movl %ecx, %eax
shrl $0x18, %eax
movb %al, 0xac(%rbx)
movl %ecx, %eax
shrl $0x10, %eax
movb %al, 0xad(%rbx)
movb %ch, 0xae(%rbx)
movb %cl, 0xaf(%rbx)
movq %rbx, (%rsp)
leaq 0x4a(%rbx), %rax
xorl %ecx, %ecx
testq %r12, %r12
je 0x1c0c
movzwl (%r12,%rcx,2), %edx
rolw $0x8, %dx
movzwl %dx, %edx
jmp 0x1c17
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 0x1bf9
cmpl $0x0, 0xc(%rsp)
je 0x1e3e
movq (%rsp), %r8
addq $0xb0, %r8
movq %r13, %rax
addq %rbp, %rax
movq 0x10(%rsp), %rdx
cmpb $0x0, (%r13,%rdx)
leaq 0x1(%r13,%rbp), %rcx
cmovsq %rcx, %rax
leaq 0x2(%r13,%rbp), %r12
cmovnsq %rcx, %r12
movq 0x58(%rsp), %rcx
orl 0x28(%rsp), %ecx
movq %rcx, 0x58(%rsp)
leaq (%rdx,%r13), %rcx
movb (%rax), %sil
movb 0x18(%r13), %dil
addq $0x19, %r13
movq 0x48(%rsp), %rax
orl 0xa0(%rsp), %eax
movq %rax, 0x48(%rsp)
movq 0x40(%rsp), %rax
movl %eax, %edx
imull 0x1c(%rsp), %eax
movq %rax, 0x40(%rsp)
movl %r15d, %eax
movq %rax, 0x28(%rsp)
movq 0x38(%rsp), %rax
orl 0x90(%rsp), %eax
movq %rax, 0x38(%rsp)
movq 0x50(%rsp), %rax
addl 0x98(%rsp), %eax
movq %rax, 0x50(%rsp)
movl $0x0, 0x20(%rsp)
movb $0x7, %r11b
movb $0x6, %r10b
cmpl $0x0, 0x68(%rsp)
je 0x1e1f
xorl %eax, %eax
movq %r8, 0x10(%rsp)
movq %r8, 0x30(%rsp)
movl %eax, 0xc(%rsp)
cmpl $0x0, 0x6c(%rsp)
je 0x1df3
xorl %ebx, %ebx
movq 0x10(%rsp), %rax
cmpl $0x0, 0x1c(%rsp)
je 0x1ddc
movq 0x50(%rsp), %r8
movq %rax, %rbp
movzbl %sil, %r9d
movzbl %r11b, %r14d
btl %r14d, %r9d
jae 0x1d75
leaq 0x1(%r13), %r9
cmpq 0x60(%rsp), %r9
ja 0x1ec4
movb (%r13), %dil
movq %r9, %r13
decb %r11b
movb %dil, (%rbp)
cmpb $0x8, %r11b
jb 0x1da6
movzbl (%rcx), %r9d
movzbl %r10b, %r11d
btl %r11d, %r9d
jae 0x1dab
leaq 0x1(%r12), %r9
cmpq 0x60(%rsp), %r9
ja 0x1ec4
movb (%r12), %sil
jmp 0x1dae
movq %r12, %r9
jmp 0x1dcb
movq %r12, %r9
decb %r10b
movb $0x7, %r11b
cmpb $0x8, %r10b
jb 0x1dcb
incq %rcx
movb $0x7, %r10b
cmpq 0x60(%rsp), %rcx
ja 0x1ec4
addq %rdx, %rbp
movq %r9, %r12
decl %r8d
jne 0x1d51
jmp 0x1ddf
movq %r12, %r9
incq %rax
incl %ebx
movq %r9, %r12
cmpl 0x58(%rsp), %ebx
jne 0x1d3e
jmp 0x1df6
movq %r12, %r9
movq 0x10(%rsp), %rax
addq 0x40(%rsp), %rax
movq %rax, 0x10(%rsp)
movl 0xc(%rsp), %eax
incl %eax
movq %r9, %r12
cmpl 0x48(%rsp), %eax
movq 0x30(%rsp), %r8
jne 0x1d28
jmp 0x1e22
movq %r12, %r9
addq 0x28(%rsp), %r8
movl 0x20(%rsp), %eax
incl %eax
movq %r9, %r12
movl %eax, 0x20(%rsp)
cmpl 0x38(%rsp), %eax
jne 0x1d11
movq 0x70(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x15c5
leaq 0x122f(%rip), %rsi      # 0x3083
movq 0x88(%rsp), %rbx
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1383
testq %rax, %rax
je 0x1f0a
movq %rax, %r14
leaq 0x1214(%rip), %rdi      # 0x308f
movq %rbx, %rsi
movq %rax, %rdx
movq 0x80(%rsp), %r15
movl %r15d, %ecx
xorl %eax, %eax
callq 0x10c0
movq %r14, %rdi
movq (%rsp), %rbx
movq %rbx, %rsi
movq %r15, %rdx
callq 0x131e
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
jmp 0x1ec8
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rsp), %rdi
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1030
movq 0x310b(%rip), %rax      # 0x4ff0
movq (%rax), %rdi
leaq 0x1171(%rip), %rsi      # 0x3060
movq %r8, %rdx
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x10d0
movq %rbx, %rdi
callq 0x1120
movq (%rsp), %rbx
jmp 0x1ead