// File: /workspace/github_c_makefile_star2_O3/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 $0x28, %rsp
movl %esi, %ebp
movq %rdi, %r14
movl $0x18, %edi
callq 0x2230
movq %rax, %rdi
callq 0xe094
movq %rax, %r13
movq $0x0, 0x8(%rax)
leaq 0x4e51(%rip), %rsi      # 0x10b64
movq %r14, %rdi
callq 0x2270
movq %rax, (%r13)
testq %rax, %rax
je 0xbd83
movl $0x30, %edi
callq 0x2230
movq %rax, %rdi
callq 0xe094
movq %rax, %r14
movq (%r13), %rcx
movl $0x1, %esi
movl $0x30, %edx
movq %rax, %rdi
callq 0x20c0
cmpq $0x2f, %rax
jbe 0xbfc6
movl $0x0, 0x14(%r13)
testl %ebp, %ebp
setne %cl
movzwl (%r14), %eax
cmpl $0x200, %eax            # imm = 0x200
sete %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0xbd90
movl $0x1, 0x14(%r13)
jmp 0xbd9b
movq %r13, %rdi
callq 0xc009
jmp 0xbe16
cmpl $0x201, %eax            # imm = 0x201
jne 0xbffc
movsbl 0x1a(%r14), %ebp
cmpl $0x7, %ebp
jbe 0xbfd6
movzwl 0x1e(%r14), %r15d
movzwl 0x1c(%r14), %r12d
shll $0x9, %r12d
movq %r14, %rdi
callq 0x2050
movl %r15d, %edi
imull %ebp, %edi
callq 0x2230
movq %rax, %rdi
callq 0xe094
movq %rax, %r14
movq (%r13), %rdi
addl $0xfffffe00, %r12d      # imm = 0xFFFFFE00
xorl %ebx, %ebx
movq %r12, %rsi
xorl %edx, %edx
callq 0x2250
movl %ebp, %r12d
movq (%r13), %rcx
movq %r14, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x20c0
cmpq %r15, %rax
jae 0xbe1d
movq %r13, %rdi
callq 0xc009
movq %r14, %rdi
callq 0x2050
xorl %ebx, %ebx
jmp 0xbfb4
testl %r15d, %r15d
movq %r13, 0x8(%rsp)
je 0xbea1
xorl %ebx, %ebx
movl %ebx, %edi
imull %ebp, %edi
cmpw $-0x1, (%r14,%rdi)
jne 0xbe8f
addq %r14, %rdi
cmpw $-0x1, 0x2(%rdi)
jne 0xbe8f
decl %r15d
movslq %r15d, %rcx
movl %ebp, %eax
imull %ecx, %eax
cmpq %rcx, %rbx
jge 0xbe9c
movq %rcx, %r15
movl %eax, %ecx
leaq (%r14,%rcx), %r13
cmpw $-0x1, (%r14,%rcx)
jne 0xbe6f
leaq -0x1(%r15), %rcx
subl %ebp, %eax
cmpw $-0x1, 0x2(%r13)
je 0xbe4b
movq %r13, %rsi
movq %r12, %rdx
callq 0x2220
movq %r13, %rdi
movl $0xff, %esi
movq %r12, %rdx
callq 0x2140
movq 0x8(%rsp), %r13
incq %rbx
movslq %r15d, %rax
cmpq %rax, %rbx
jl 0xbe29
jmp 0xbea1
movq 0x8(%rsp), %r13
movl %ebx, 0x10(%r13)
movq %r13, %r15
movl %ebx, %r13d
leaq (,%r13,8), %rax
leaq (%rax,%rax,2), %rdi
callq 0x2230
movq %rax, %rdi
callq 0xe094
movq %rax, 0x8(%r15)
movslq 0x10(%r15), %rcx
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x2140
testl %ebx, %ebx
je 0xbfa7
xorl %r15d, %r15d
leaq 0x10(%rsp), %r12
movl %r15d, %ebx
imull %ebp, %ebx
movzwl (%r14,%rbx), %edi
movq %r12, %rsi
callq 0xe3c8
movzwl 0x2(%r14,%rbx), %edi
leaq 0x13(%rsp), %rsi
callq 0xe3c8
movb $0x0, 0x16(%rsp)
movq %r12, %rdi
callq 0x20e0
leaq 0xf(%rsp), %rcx
addq %rcx, %rax
cmpq %r12, %rax
jb 0xbf38
cmpb $0x20, (%rax)
jne 0xbf38
movb $0x0, (%rax)
decq %rax
jmp 0xbf26
movq %r12, %rdi
callq 0x22e0
movq %rax, %rdi
callq 0xe094
movq 0x8(%rsp), %rcx
movq 0x8(%rcx), %rcx
leaq (%r15,%r15,2), %rdx
movq %rax, (%rcx,%rdx,8)
movzbl 0x4(%r14,%rbx), %eax
movzbl 0x5(%r14,%rbx), %esi
andl $0x7f, %esi
shll $0x8, %esi
orl %eax, %esi
shll $0x9, %esi
movzbl 0x6(%r14,%rbx), %eax
movzbl 0x7(%r14,%rbx), %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 %r13, %r15
jne 0xbeee
movq %r14, %rdi
callq 0x2050
movq 0x8(%rsp), %rbx
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, %rdi
movq %r14, %rsi
callq 0x24ae
jmp 0xbe16
movq %r13, %rdi
callq 0xc009
movq 0x9013(%rip), %rax      # 0x14ff8
movq (%rax), %rdi
leaq 0x4bbc(%rip), %rsi      # 0x10bab
xorl %ebx, %ebx
movl %ebp, %edx
xorl %eax, %eax
callq 0x21e0
jmp 0xbfb4
movq %r13, %rdi
callq 0x2485
jmp 0xbe16