// File: /workspace/github_c_makefile_star2_O2/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
movq %rdi, %r14
movl 0x10(%rdi), %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
movq %rsi, %r15
imulq $0x18, %rax, %rbp
addq $0x18, %rbp
xorl %ecx, %ecx
leaq 0x18(%rcx), %r12
cmpq %r12, %rbp
je 0xb81b
movq 0x8(%r14), %r13
movq (%r13,%rcx), %rdi
movq %r15, %rsi
callq 0x21d0
movq %r12, %rcx
testl %eax, %eax
jne 0xb75f
movq (%r14), %rdi
movq -0x10(%r13,%r12), %rsi
xorl %edx, %edx
callq 0x2250
movq (%r14), %rcx
movq %rsp, %rdi
pushq $0x12
popq %rsi
pushq $0x1
popq %rdx
callq 0x20c0
testq %rax, %rax
je 0xb81b
movl 0x4(%rsp), %eax
shll $0x10, %eax
movzwl 0x6(%rsp), %ecx
addl %ecx, %eax
addl $-0x12, %eax
movl %eax, -0x8(%r13,%r12)
cmpb $0x1, 0x2(%rsp)
je 0xb8eb
callq 0xc798
movq %rax, %rbx
movl -0x8(%r13,%r12), %esi
movq %rax, %rdi
callq 0xc7b8
movq %rbx, 0x20(%rsp)
movq (%rbx), %r15
cmpl $0x0, 0x14(%r14)
je 0xb82f
movslq -0x8(%r13,%r12), %rdx
movq (%r14), %rcx
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x20c0
cltq
addq %rax, %r15
movq 0x20(%rsp), %rbx
subl (%rbx), %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0xc7b8
jmp 0xb81d
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb $0x10, (%rsp)
jne 0xb859
xorl %ebp, %ebp
cmpl -0x8(%r13,%r12), %ebp
jge 0xb806
movq (%r14), %rdi
callq 0x2160
testl %eax, %eax
je 0xb855
cmpl $0xd, %eax
je 0xb855
movb %al, (%r15)
incq %r15
incl %ebp
jmp 0xb837
movl -0x8(%r13,%r12), %r12d
testl %r12d, %r12d
jle 0xb806
movq (%r14), %rdi
callq 0x2160
movl %eax, %r13d
movzbl %r13b, %ebx
movq (%r14), %rdi
callq 0x2160
shll $0x8, %eax
movzwl %ax, %ebp
orl %ebx, %ebp
addl $-0x2, %r12d
cmpl %r12d, %ebp
jg 0xb8c9
testl %ebp, %ebp
jle 0xb8af
movq (%r14), %rdi
callq 0x2160
cmpl $0xd, %eax
je 0xb8a0
testl %eax, %eax
jne 0xb8a7
decl %r12d
decl %ebp
jmp 0xb88b
movb %al, (%r15)
incq %r15
jmp 0xb8a0
movb $0xa, (%r15)
incq %r15
testb $0x1, %r13b
je 0xb85e
movq (%r14), %rdi
callq 0x2160
decl %r12d
jmp 0xb85e
movq 0x9728(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
leaq 0x436c(%rip), %rsi      # 0xfc46
movl %ebp, %edx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x21e0
movl %r12d, %ebp
jmp 0xb88b
movq 0x9706(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
movq -0x10(%r13,%r12), %rcx
leaq 0x4318(%rip), %rsi      # 0xfc19
xorl %ebx, %ebx
movq %r15, %rdx
xorl %eax, %eax
callq 0x21e0
jmp 0xb81d