// File: /workspace/github_c_makefile_star2_O1/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 %rsi, %r15
movq %rdi, %rbx
movslq 0x10(%rdi), %r14
testq %r14, %r14
setg %bpl
jle 0xc2f4
movq 0x8(%rbx), %r12
movq (%r12), %rdi
movq %r15, %rsi
callq 0x21d0
testl %eax, %eax
je 0xc300
leal -0x1(%r14), %eax
leaq (%rax,%rax,2), %rax
leaq (%r12,%rax,8), %r13
movl $0x1, %ecx
movq %rcx, %rbp
cmpq %rcx, %r14
je 0xc2f6
movq 0x18(%r12), %rdi
addq $0x18, %r12
movq %r15, %rsi
callq 0x21d0
leaq 0x1(%rbp), %rcx
testl %eax, %eax
jne 0xc2d1
jmp 0xc2f9
jmp 0xc300
movq %r13, %r12
cmpq %r14, %rbp
setb %bpl
testb %bpl, %bpl
je 0xc3c1
movq (%rbx), %rdi
movq 0x8(%r12), %rsi
xorl %r14d, %r14d
xorl %edx, %edx
callq 0x2250
movq (%rbx), %rcx
movq %rsp, %rdi
movl $0x12, %esi
movl $0x1, %edx
callq 0x20c0
testq %rax, %rax
je 0xc3c4
movzbl 0x4(%rsp), %eax
movzbl 0x5(%rsp), %ecx
shll $0x18, %ecx
shll $0x10, %eax
orl %ecx, %eax
movzbl 0x6(%rsp), %ecx
orl %eax, %ecx
movzbl 0x7(%rsp), %eax
shll $0x8, %eax
addl %ecx, %eax
addl $-0x12, %eax
movl %eax, 0x10(%r12)
cmpb $0x1, 0x2(%rsp)
je 0xc4c1
callq 0xdd0c
movq %rax, %r14
movl 0x10(%r12), %esi
movq %rax, %rdi
callq 0xdd2e
movq (%r14), %r15
cmpl $0x0, 0x14(%rbx)
movq %r14, 0x20(%rsp)
je 0xc3d6
movslq 0x10(%r12), %rdx
movq (%rbx), %rcx
movl $0x1, %esi
movq %r15, %rdi
callq 0x20c0
cltq
addq %rax, %r15
movq 0x20(%rsp), %r14
subl (%r14), %r15d
movq %r14, %rdi
movl %r15d, %esi
callq 0xdd2e
jmp 0xc3c4
xorl %r14d, %r14d
movq %r14, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb $0x10, (%rsp)
movl 0x10(%r12), %r13d
jne 0xc40a
testl %r13d, %r13d
jle 0xc3ac
xorl %ebp, %ebp
movq (%rbx), %rdi
callq 0x2160
testl %eax, %eax
je 0xc3ff
cmpl $0xd, %eax
je 0xc3ff
movb %al, (%r15)
incq %r15
incl %ebp
cmpl 0x10(%r12), %ebp
jl 0xc3e8
jmp 0xc3ac
testl %r13d, %r13d
jle 0xc3ac
movq (%rbx), %rdi
callq 0x2160
movl %eax, %ebp
movzbl %bpl, %r14d
movq (%rbx), %rdi
callq 0x2160
shll $0x8, %eax
movzwl %ax, %r12d
orl %r14d, %r12d
addl $-0x2, %r13d
cmpl %r13d, %r12d
jg 0xc49b
testl %r12d, %r12d
jle 0xc47e
decl %r13d
movl %r13d, %eax
movl %eax, %r13d
movq (%rbx), %rdi
callq 0x2160
cmpl $0xd, %eax
je 0xc457
testl %eax, %eax
jne 0xc46a
decl %r12d
leal 0x1(%r12), %ecx
leal -0x1(%r13), %eax
cmpl $0x1, %ecx
jg 0xc443
jmp 0xc47e
movb %al, (%r15)
incq %r15
leal -0x1(%r12), %eax
cmpl $0x1, %r12d
movl %eax, %r12d
jg 0xc43d
movb $0xa, (%r15)
testb $0x1, %bpl
je 0xc493
movq (%rbx), %rdi
callq 0x2160
decl %r13d
incq %r15
jmp 0xc40a
movq 0x8b56(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
leaq 0x473b(%rip), %rsi      # 0x10be7
movl %r12d, %edx
movl %r13d, %ecx
xorl %eax, %eax
callq 0x21e0
movl %r13d, %r12d
jmp 0xc438
movq 0x8b30(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
movq 0x8(%r12), %rcx
leaq 0x46e3(%rip), %rsi      # 0x10bba
xorl %r14d, %r14d
movq %r15, %rdx
xorl %eax, %eax
callq 0x21e0
jmp 0xc3c4