// File: /workspace/github_c_makefile_star2_O3/simh[P]simtools/crossassemblers/macro11/mlb-rsx.c
// Function: mlb_entry
BUFFER         *mlb_entry(
    MLB *mlb,
    char *name)
{
    int             i;
    MLBENT         *ent;
    BUFFER         *buf;
    char           *bp;
    int             c;
    unsigned char   module_header[022];

    for (i = 0; i < mlb->nentries; i++) {
        ent = &mlb->directory[i];
        if (strcmp(mlb->directory[i].label, name) == 0)
            break;
    }

    if (i >= mlb->nentries) {
//        fprintf(stderr, "mlb_entry: %s not found\n", name);
        return NULL;
    }

    fseek(mlb->fp, ent->position, SEEK_SET);
//    fprintf(stderr, "mlb_entry: %s at position %ld\n", name, (long)ent->position);

#define MODULE_HEADER_SIZE      022

    if (fread(module_header, MODULE_HEADER_SIZE, 1, mlb->fp) < 1) {
//        fprintf(stderr, "mlb_entry: %s at position %lx can't read 022 bytes\n", name, (long)ent->position);
        return NULL;
    }

//    for (i = 0; i < MODULE_HEADER_SIZE; i++) {
//        fprintf(stderr, "%02x ", module_header[i]);
//    }
//    fprintf(stderr, "\n");
    ent->length = (WORD(module_header + 04) << 16) +
                   WORD(module_header + 06);
    ent->length -= MODULE_HEADER_SIZE; /* length is including this header */
//    fprintf(stderr, "mlb_entry: %s at position %lx length = %d\n", name, (long)ent->position, ent->length);

    if (module_header[02] == 1) {
        fprintf(stderr, "mlb_entry: %s at position %lx deleted entry\n", name, (long)ent->position);
        /* Deleted Entry */
        return NULL;
    }

    /*
     * Allocate a buffer to hold the text.
     * The text is always shorter than the on-disk size.
     */
    buf = new_buffer();
    buffer_resize(buf, ent->length);       /* Make it large enough */
    bp = buf->buffer;

    /*
     * Check the file format: variable length records,
     * or stream of bytes.
     * Not sure if this check is the correct one; I've only
     * seen MLB and OLB files with var length records.
     */

    if (mlb->is_objlib) {
        /* In object libraries, copy the internal structure, since we
         * can consider them to be binary.
         */
        i = fread(bp, 1, ent->length, mlb->fp);
        bp += i;
    } else if (module_header[0] & 0x10) {
//        fprintf(stderr, "mlb_entry: %s at position %lx variable length records\n", name, (long)ent->position);
        /* Variable length records with size before them */
        i = ent->length;
        while (i > 0) {
            int length;

//            fprintf(stderr, "file offset:$%lx\n", (long)ftell(mlb->fp));
            c = fgetc(mlb->fp);            /* Get low byte of length */
            length = c & 0xFF;
            c = fgetc(mlb->fp);            /* Get high byte */
            length += (c & 0xFF) << 8;
            i -= 2;
//            fprintf(stderr, "line length: %d $%x\n", length, length);

            /* Odd lengths are padded with an extra 0 byte */
            int padded = length & 1;
            if (length > i) {
                fprintf(stderr, "line length %d > remaining archive member %d\n", length, i);
                length = i;
            }

            while (length > 0) {
                c = fgetc(mlb->fp);        /* Get macro byte */
                //fprintf(stderr, "%02x %c length=%d\n", c, c, length);
                i--;
                length--;
                if (c == '\r' || c == 0)   /* If it's a carriage return or 0,
                                              discard it. */
                    continue;
                *bp++ = c;
            }
            *bp++ = '\n';
            if (padded) {
                c = fgetc(mlb->fp);        /* Get pad byte; need not be 0. */
                //fprintf(stderr, "pad byte %02x %c length=%d\n", c, c, length);
                i--;
            }
        }
    } else {
//        fprintf(stderr, "mlb_entry: %s at position %lx byte stream records\n", name, (long)ent->position);
        for (i = 0; i < ent->length; i++) {
            c = fgetc(mlb->fp);            /* Get macro byte */
            if (c == '\r' || c == 0)       /* If it's a carriage return or 0,
                                              discard it. */
                continue;
            *bp++ = c;
        }
    }

    /* Now resize that buffer to the length actually read. */
    buffer_resize(buf, (int) (bp - buf->buffer));

    return buf;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movslq 0x10(%rdi), %rax
testq %rax, %rax
jle 0xc0b8
movq %rsi, %r15
movq %rdi, %r14
movq 0x8(%rdi), %r12
shlq $0x3, %rax
leaq (%rax,%rax,2), %r13
xorl %ebp, %ebp
movq (%r12,%rbp), %rdi
movq %r15, %rsi
callq 0x21d0
testl %eax, %eax
je 0xc0bf
addq $0x18, %rbp
cmpq %rbp, %r13
jne 0xc09f
xorl %ebx, %ebx
jmp 0xc15c
movq (%r14), %rdi
movq 0x8(%r12,%rbp), %rsi
xorl %ebx, %ebx
xorl %edx, %edx
callq 0x2250
movq (%r14), %rcx
movq %rsp, %rdi
movl $0x12, %esi
movl $0x1, %edx
callq 0x20c0
testq %rax, %rax
je 0xc15c
movl 0x4(%rsp), %eax
shll $0x10, %eax
movzwl 0x6(%rsp), %ecx
addl %ecx, %eax
addl $-0x12, %eax
movl %eax, 0x10(%r12,%rbp)
cmpb $0x1, 0x2(%rsp)
je 0xc25b
callq 0xda54
movq %rax, %rbx
movl 0x10(%r12,%rbp), %esi
movq %rax, %rdi
callq 0xda76
movq %rbx, 0x20(%rsp)
movq (%rbx), %r15
cmpl $0x0, 0x14(%r14)
je 0xc16e
movslq 0x10(%r12,%rbp), %rdx
movq (%r14), %rcx
movl $0x1, %esi
movq %r15, %rdi
callq 0x20c0
cltq
addq %rax, %r15
movq 0x20(%rsp), %rbx
subl (%rbx), %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0xda76
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb $0x10, (%rsp)
movl 0x10(%r12,%rbp), %r13d
jne 0xc1a4
testl %r13d, %r13d
jle 0xc149
xorl %r13d, %r13d
movq (%r14), %rdi
callq 0x2160
testl %eax, %eax
je 0xc198
cmpl $0xd, %eax
je 0xc198
movb %al, (%r15)
incq %r15
incl %r13d
cmpl 0x10(%r12,%rbp), %r13d
jl 0xc181
jmp 0xc149
testl %r13d, %r13d
jle 0xc149
movq (%r14), %rdi
callq 0x2160
movl %eax, %ebp
movzbl %bpl, %ebx
movq (%r14), %rdi
callq 0x2160
shll $0x8, %eax
movzwl %ax, %r12d
orl %ebx, %r12d
addl $-0x2, %r13d
cmpl %r13d, %r12d
jg 0xc235
testl %r12d, %r12d
jle 0xc218
decl %r13d
movl %r13d, %eax
movl %eax, %r13d
movq (%r14), %rdi
callq 0x2160
cmpl $0xd, %eax
je 0xc1f1
testl %eax, %eax
jne 0xc204
decl %r12d
leal 0x1(%r12), %ecx
leal -0x1(%r13), %eax
cmpl $0x1, %ecx
ja 0xc1dd
jmp 0xc218
movb %al, (%r15)
incq %r15
leal -0x1(%r12), %eax
cmpl $0x1, %r12d
movl %eax, %r12d
ja 0xc1d7
movb $0xa, (%r15)
testb $0x1, %bpl
je 0xc22d
movq (%r14), %rdi
callq 0x2160
decl %r13d
incq %r15
jmp 0xc1a4
movq 0x8dbc(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
leaq 0x49b0(%rip), %rsi      # 0x10bf6
movl %r12d, %edx
movl %r13d, %ecx
xorl %eax, %eax
callq 0x21e0
movl %r13d, %r12d
jmp 0xc1d2
movq 0x8d96(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
movq 0x8(%r12,%rbp), %rcx
leaq 0x4958(%rip), %rsi      # 0x10bc9
xorl %ebx, %ebx
movq %r15, %rdx
xorl %eax, %eax
callq 0x21e0
jmp 0xc15c