// File: /workspace/github_c_makefile_star2_O1/simh[P]simtools/crossassemblers/macro11/mlb-rsx.c
// Function: mlb_open
MLB            *mlb_open(
    char *name,
    int allow_objlib)
{
    MLB            *mlb = memcheck(malloc(sizeof(MLB)));
    char           *buff;
    unsigned        entsize;
    unsigned        nr_entries;
    unsigned        start_block;
    int             i;

    mlb->directory = NULL;

    mlb->fp = fopen(name, "rb");
    if (mlb->fp == NULL) {
        mlb_close(mlb);
        return NULL;
    }

    buff = memcheck(malloc(060));      /* Size of MLB library header */

    if (fread(buff, 1, 060, mlb->fp) < 060) {
        fprintf(stderr, "error: can't read full header\n");
        mlb_close(mlb);
        free(buff);
        return NULL;
    }

    mlb->is_objlib = 0;
    if (allow_objlib && WORD(buff) == 01000) { /* Is it an object library? */
        mlb->is_objlib = 1;
    } else if (WORD(buff) != 01001) {  /* Is this really a macro library? */
        fprintf(stderr, "error: first word not correct value\n");
        mlb_close(mlb);                /* Nope. */
        return NULL;
    }

    entsize = buff[032];               /* The size of each macro directory
                                          entry */
    nr_entries = WORD(buff + 036);     /* The number of directory entries */
    start_block = WORD(buff + 034) - 1;/* The start RT-11 block of the
                                          directory */

    if (entsize < 8) {                 /* Is this really a macro library? */
        mlb_close(mlb);                /* Nope. */
        fprintf(stderr, "error: entsize too small: %d\n", entsize);
        return NULL;
    }

//    fprintf(stderr, "entsize=%d, nr_entries=%d, start_block=%d\n",
//            entsize, nr_entries, start_block);
    free(buff);                        /* Done with that header. */

    /* Allocate a buffer for the disk directory */
    buff = memcheck(malloc(nr_entries * entsize));
    fseek(mlb->fp, start_block * BLOCKSIZE, SEEK_SET);        /* Go to the directory */

    /* Read the disk directory */
    if (fread(buff, entsize, nr_entries, mlb->fp) < nr_entries) {
        mlb_close(mlb);                /* Sorry, read error. */
        free(buff);
        return NULL;
    }

    /* Shift occupied directory entries to the front of the array */
    {
        int             j;

        for (i = 0, j = nr_entries; i < j; i++) {
            char           *ent1,
                           *ent2;

            ent1 = buff + (i * entsize);
            /* Unused entries have 0177777 0177777 for the RAD50 name,
               which is not legal RAD50. */
            if (WORD(ent1) == 0177777 && WORD(ent1 + 2) == 0177777) {
                while (--j > i
                       && (ent2 = buff + (j * entsize), WORD(ent2) == 0177777 && WORD(ent2 + 2) == 0177777)) ;
                if (j <= i)
                    break;             /* All done. */
                memcpy(ent1, ent2, entsize);    /* Move used entry
                                                   into unused entry's
                                                   space */
                memset(ent2, 0377, entsize);    /* Mark entry unused */
            } else {
//            fprintf(stderr, "entry %d:  %02x%02x.%02x%02x\n",
//                    i, ent1[5] & 0xFF, ent1[4] & 0xFF, ent1[7] & 0xFF, ent1[6] & 0xFF);
            }
        }

        /* Now i contains the actual number of entries. */

        mlb->nentries = i;
//        fprintf(stderr, " mlb->nentries=%d\n",  mlb->nentries);

        /* Now, allocate my in-memory directory */
        mlb->directory = memcheck(malloc(sizeof(MLBENT) * mlb->nentries));
        memset(mlb->directory, 0, sizeof(MLBENT) * mlb->nentries);

        /* Build in-memory directory */
        for (j = 0; j < i; j++) {
            char            radname[16];
            char           *ent;

            ent = buff + (j * entsize);

            unrad50(WORD(ent), radname);
            unrad50(WORD(ent + 2), radname + 3);
            radname[6] = 0;

//            fprintf(stderr, "entry %d: \"%s\" %02x%02x.%02x%02x\n",
//                    j, radname,
//                    ent[5] & 0xFF, ent[4] & 0xFF, ent[7] & 0xFF, ent[6] & 0xFF);
            trim(radname);

            mlb->directory[j].label = memcheck(strdup(radname));
            mlb->directory[j].position = BYTEPOS(ent);
//            fprintf(stderr, "entry %d: \"%s\" bytepos=%d\n", j, mlb->directory[j].label, mlb->directory[j].position);
            mlb->directory[j].length = -1;
        }

        free(buff);
    }

    /* Done.  Return the struct that represents the opened MLB. */
    return mlb;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %esi, %ebp
movq %rdi, %r14
movl $0x18, %edi
callq 0x2230
movq %rax, %rdi
callq 0xe34f
movq %rax, %r13
movq $0x0, 0x8(%rax)
leaq 0x4c7a(%rip), %rsi      # 0x10b55
movq %r14, %rdi
callq 0x2270
movq %rax, (%r13)
testq %rax, %rax
je 0xbfd4
movl $0x30, %edi
callq 0x2230
movq %rax, %rdi
callq 0xe34f
movq %rax, %r14
movq (%r13), %rcx
movl $0x1, %esi
movl $0x30, %edx
movq %rax, %rdi
callq 0x20c0
cmpq $0x2f, %rax
jbe 0xc1e2
movl $0x0, 0x14(%r13)
testl %ebp, %ebp
je 0xbf43
cmpw $0x200, (%r14)          # imm = 0x200
jne 0xbf43
movl $0x1, 0x14(%r13)
jmp 0xbf4f
cmpw $0x201, (%r14)          # imm = 0x201
jne 0xc218
movsbl 0x1a(%r14), %ebp
cmpl $0x7, %ebp
jbe 0xc1f2
movzwl 0x1e(%r14), %r12d
movzbl 0x1d(%r14), %ebx
movzbl 0x1c(%r14), %r15d
movq %r14, %rdi
callq 0x2050
movl %r12d, %edi
imull %ebp, %edi
callq 0x2230
movq %rax, %rdi
callq 0xe34f
movq %rax, %r14
movq (%r13), %rdi
shll $0x11, %ebx
shll $0x9, %r15d
leal (%r15,%rbx), %esi
addl $0xfffffe00, %esi       # imm = 0xFFFFFE00
xorl %r15d, %r15d
xorl %edx, %edx
callq 0x2250
movl %ebp, %ebx
movq (%r13), %rcx
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x20c0
cmpq %r12, %rax
jae 0xbfe3
movq %r13, %rdi
callq 0xc225
movq %r14, %rdi
callq 0x2050
jmp 0xbfdc
movq %r13, %rdi
callq 0xc225
xorl %ebx, %ebx
jmp 0xc1d0
testl %r12d, %r12d
movl %ebp, 0xc(%rsp)
je 0xc0c3
movq %rbx, 0x30(%rsp)
movq %r13, 0x28(%rsp)
xorl %r15d, %r15d
movl %r15d, %edi
imull %ebp, %edi
movb $0x1, %bl
cmpw $-0x1, (%r14,%rdi)
jne 0xc0a4
addq %r14, %rdi
cmpw $-0x1, 0x2(%rdi)
jne 0xc0a4
leal -0x1(%r12), %ecx
movslq %ecx, %rax
cmpq %rax, %r15
setl %al
jge 0xc075
movl %ecx, %edx
imull %ebp, %edx
leaq (%r14,%rdx), %r13
cmpw $-0x1, (%r14,%rdx)
jne 0xc075
movl %ecx, %edx
addl $-0x2, %r12d
imull %ebp, %r12d
movl %r12d, %ecx
movq %rdx, %r12
cmpw $-0x1, 0x2(%r13)
jne 0xc078
decq %r12
cmpq %r15, %r12
setg %al
jle 0xc0b9
movl %ecx, %edx
leaq (%r14,%rdx), %r13
subl %ebp, %ecx
cmpw $-0x1, (%r14,%rdx)
je 0xc050
jmp 0xc078
movl %ecx, %r12d
testb $0x1, %al
je 0xc0a2
movq %r13, %rsi
movq 0x30(%rsp), %rbp
movq %rbp, %rdx
callq 0x2220
movq %r13, %rdi
movl $0xff, %esi
movq %rbp, %rdx
movl 0xc(%rsp), %ebp
callq 0x2140
jmp 0xc0a4
xorl %ebx, %ebx
testb %bl, %bl
je 0xc0be
incq %r15
movslq %r12d, %rax
cmpq %rax, %r15
jl 0xbffd
jmp 0xc0be
movq %r15, %r12
jmp 0xc078
movq 0x28(%rsp), %r13
movl %r15d, 0x10(%r13)
movl %r15d, %ebp
leaq (,%rbp,8), %rax
leaq (%rax,%rax,2), %rdi
callq 0x2230
movq %rax, %rdi
callq 0xe34f
movq %rax, 0x8(%r13)
movq %r13, %rbx
movslq 0x10(%r13), %rcx
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x2140
testl %r15d, %r15d
je 0xc1c8
xorl %r15d, %r15d
leaq 0x10(%rsp), %r12
movl %r15d, %r13d
imull 0xc(%rsp), %r13d
movzwl (%r14,%r13), %edi
movq %r12, %rsi
callq 0xe678
movzwl 0x2(%r14,%r13), %edi
leaq 0x13(%rsp), %rsi
callq 0xe678
movb $0x0, 0x16(%rsp)
movq %r12, %rdi
callq 0x20e0
leaq 0xf(%rsp), %rcx
addq %rcx, %rax
cmpq %r12, %rax
jb 0xc15e
cmpb $0x20, (%rax)
jne 0xc15e
movb $0x0, (%rax)
decq %rax
jmp 0xc14c
movq %r12, %rdi
callq 0x22e0
movq %rax, %rdi
callq 0xe34f
movq 0x8(%rbx), %rcx
leaq (%r15,%r15,2), %rdx
movq %rax, (%rcx,%rdx,8)
movzbl 0x4(%r14,%r13), %eax
movzbl 0x5(%r14,%r13), %esi
andl $0x7f, %esi
shll $0x8, %esi
orl %eax, %esi
shll $0x9, %esi
movzbl 0x6(%r14,%r13), %eax
movzbl 0x7(%r14,%r13), %edi
andl $0x1, %edi
shll $0x8, %edi
orl %eax, %edi
leal (%rsi,%rdi), %eax
addl $0xfffffe00, %eax       # imm = 0xFFFFFE00
cltq
movq %rax, 0x8(%rcx,%rdx,8)
movl $0xffffffff, 0x10(%rcx,%rdx,8) # imm = 0xFFFFFFFF
incq %r15
cmpq %rbp, %r15
jne 0xc111
movq %r14, %rdi
callq 0x2050
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, %rdi
movq %r14, %rsi
callq 0x24ae
jmp 0xbfdc
movq %r13, %rdi
callq 0xc225
movq 0x8df7(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
leaq 0x4991(%rip), %rsi      # 0x10b9c
xorl %ebx, %ebx
movl %ebp, %edx
xorl %eax, %eax
callq 0x21e0
jmp 0xc1d0
movq %r13, %rdi
callq 0x2485
jmp 0xbfdc